style: 添加预设样式
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
<style>
|
||||
#canvas-stardust-container {
|
||||
width: 100%; height: 100%; background: #020208; /* 非常暗的蓝黑色 */
|
||||
overflow: hidden; position: relative;
|
||||
}
|
||||
#stardust-canvas { display: block; position: absolute; top: 0; left: 0; }
|
||||
</style>
|
||||
<div id="canvas-stardust-container">
|
||||
<canvas id="stardust-canvas"></canvas>
|
||||
</div>
|
||||
<script>
|
||||
(function() {
|
||||
const canvas = document.getElementById('stardust-canvas');
|
||||
const layerElement = canvas.closest('.terminal-custom-html-layer') || canvas.parentElement;
|
||||
if (!canvas || !layerElement) return;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
let width, height, particles = [];
|
||||
const particleCount = 300; // 粒子数量,根据性能调整
|
||||
const baseSpeed = 0.3;
|
||||
const lifeSpan = 200; // 粒子生命周期(帧数)
|
||||
const baseRadius = 0.5;
|
||||
const radiusVariance = 1.5;
|
||||
const colors = ["#FFFFFF", "#DDDDFF", "#BBBBFF", "#9999EE"]; // 星尘颜色
|
||||
|
||||
class Particle {
|
||||
constructor() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.x = Math.random() * width;
|
||||
this.y = Math.random() * height; // 初始位置随机
|
||||
// 或者让粒子从一个方向进入
|
||||
// this.x = Math.random() * width;
|
||||
// this.y = height + Math.random() * 100; // 从底部进入
|
||||
|
||||
|
||||
this.vx = (Math.random() - 0.5) * baseSpeed * 0.5; // x方向轻微随机漂移
|
||||
this.vy = -baseSpeed - Math.random() * baseSpeed; // 主要向上流动
|
||||
|
||||
this.life = Math.random() * lifeSpan * 0.5 + lifeSpan * 0.5;
|
||||
this.initialLife = this.life;
|
||||
this.radius = baseRadius + Math.random() * radiusVariance;
|
||||
this.color = colors[Math.floor(Math.random() * colors.length)];
|
||||
}
|
||||
|
||||
update() {
|
||||
this.x += this.vx;
|
||||
this.y += this.vy;
|
||||
this.life--;
|
||||
|
||||
if (this.life <= 0 || this.y < -this.radius || this.x < -this.radius || this.x > width + this.radius) {
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
|
||||
draw() {
|
||||
ctx.beginPath();
|
||||
// 透明度随生命周期变化,实现淡入淡出
|
||||
const blinkFactor = Math.sin( (this.initialLife - this.life) * 0.1 + Math.random() * Math.PI ); // 模拟闪烁
|
||||
const alpha = (this.life / this.initialLife) * 0.5 + 0.3 * blinkFactor;
|
||||
|
||||
ctx.globalAlpha = Math.max(0, Math.min(1, alpha));
|
||||
ctx.fillStyle = this.color;
|
||||
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
width = layerElement.offsetWidth;
|
||||
height = layerElement.offsetHeight;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
particles = [];
|
||||
for (let i = 0; i < particleCount; i++) {
|
||||
particles.push(new Particle());
|
||||
}
|
||||
}
|
||||
|
||||
let animationFrameId;
|
||||
function animate() {
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
ctx.globalAlpha = 1; // Reset globalAlpha for clearing
|
||||
|
||||
particles.forEach(p => {
|
||||
p.update();
|
||||
p.draw();
|
||||
});
|
||||
ctx.globalAlpha = 1; // Reset globalAlpha after drawing all particles
|
||||
animationFrameId = requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
let resizeTimeout;
|
||||
function onResize() {
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(() => {
|
||||
if (animationFrameId) cancelAnimationFrame(animationFrameId);
|
||||
init();
|
||||
animate();
|
||||
}, 250);
|
||||
}
|
||||
|
||||
init();
|
||||
animate();
|
||||
window.addEventListener('resize', onResize);
|
||||
|
||||
canvas.cleanup = function() {
|
||||
if (animationFrameId) cancelAnimationFrame(animationFrameId);
|
||||
window.removeEventListener('resize', onResize);
|
||||
console.log("Stardust canvas cleaned up");
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user