Files
blog/src/components/widget/Sakura.astro
lirui b6abc32784 feat(ui): 实现ACG风格UI改造和动画效果
添加樱花飘落和表情点击特效组件,优化卡片动画和背景模糊效果
更新主题色为粉色并添加动漫风格背景图
引入圆角字体提升可爱风格
新增开发文档记录改造计划
2026-01-11 12:59:41 +08:00

104 lines
2.3 KiB
Plaintext

<canvas id="sakura-canvas"></canvas>
<style>
#sakura-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 0;
}
</style>
<script>
// Sakura falling effect
const canvas = document.getElementById("sakura-canvas") as HTMLCanvasElement;
const ctx = canvas.getContext("2d");
let width = 0;
let height = 0;
let petals = [];
const resize = () => {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
class Petal {
x: number;
y: number;
vx: number;
vy: number;
opacity: number;
size: number;
rotation: number;
rotationSpeed: number;
color: string;
constructor() {
this.reset();
}
reset() {
this.x = Math.random() * width;
this.y = Math.random() * height - height;
this.vx = Math.random() * 1 + 0.5;
this.vy = Math.random() * 1 + 0.5;
this.opacity = Math.random() * 0.5 + 0.3;
this.size = Math.random() * 10 + 5;
this.rotation = Math.random() * 360;
this.rotationSpeed = (Math.random() - 0.5) * 2;
this.color = `rgba(255, 183, 197, ${this.opacity})`; // Sakura pink
}
update() {
this.x += this.vx;
this.y += this.vy;
this.rotation += this.rotationSpeed;
if (this.y > height) {
this.reset();
this.y = -20;
}
if (this.x > width) {
this.x = -20;
}
}
draw() {
if (!ctx) return;
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate((this.rotation * Math.PI) / 180);
ctx.fillStyle = this.color;
ctx.beginPath();
// Draw a simple petal shape
ctx.moveTo(0, 0);
ctx.bezierCurveTo(this.size / 2, -this.size / 2, this.size, 0, 0, this.size);
ctx.bezierCurveTo(-this.size, 0, -this.size / 2, -this.size / 2, 0, 0);
ctx.fill();
ctx.restore();
}
}
const init = () => {
resize();
petals = Array.from({ length: 50 }, () => new Petal()); // 50 petals
animate();
};
const animate = () => {
if (!ctx) return;
ctx.clearRect(0, 0, width, height);
petals.forEach((petal) => {
petal.update();
petal.draw();
});
requestAnimationFrame(animate);
};
window.addEventListener("resize", resize);
init();
</script>