给客户做的动效图,结果应证了还是第一版的好,不忍舍弃,放这里,喜欢的人自取;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Particle Star Border Demo</title>
<style>
body, html {
background-color: #cccccc;
}
.item-container {
position: relative;
width: 300px;
height: 150px;
margin: 50px auto;
border-radius: 16px;
padding: 10px;
}
.item-border-canvas {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
z-index: 9;
pointer-events: none;
border-radius: 10px;
}
.item-content-canvas {
position: relative;
z-index: 1;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
background: linear-gradient(to bottom, #fff8e1, #fff0c2);
border-radius: 10px;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
font-weight: bold;
color: #ff9900;
}
</style>
</head>
<body>
<div class="item-container">
<canvas id="borderCanvas" class="item-border-canvas"></canvas>
<div class="item-content-canvas">
✨布灵布灵的星星✨
</div>
</div>
<script>
(function () {
const show = true; // 控制是否显示星星边框
if (!show) return;
const canvas = document.getElementById("borderCanvas");
const ctx = canvas.getContext("2d");
const offset = 15;
let w, h, perimeter;
let stars = [];
let animationId;
function initCanvas() {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
w = canvas.width;
h = canvas.height;
perimeter = 2 * (w + h);
initStars();
}
function initStars() {
stars = [];
for (let i = 0; i < 40; i++) {
stars.push({
distance: Math.random() * perimeter,
speed: 0.07 + Math.random() * 0.06,
flickerPhase: Math.random() * Math.PI * 2,
flickerSpeed: 0.006 + Math.random() * 0.009,
maxSize: 10 + Math.random() * 5,
rotate: Math.random() * Math.PI * 2,
});
}
}
function getPointOnPerimeter(distance) {
let d = distance % perimeter;
if (d < w) return { x: d, y: offset };
d -= w;
if (d < h) return { x: w - offset, y: d };
d -= h;
if (d < w) return { x: w - d, y: h - offset };
return { x: offset, y: h - (d - w) };
}
function pulse(t) {
return Math.pow(Math.sin(t), 4);
}
function drawStar(ctx, cx, cy, spikes, outerRadius, innerRadius, alpha, rotation) {
let rot = rotation - Math.PI / 2;
const step = Math.PI / spikes;
ctx.beginPath();
ctx.moveTo(cx + Math.cos(rot) * outerRadius, cy + Math.sin(rot) * outerRadius);
for (let i = 0; i < spikes; i++) {
rot += step;
ctx.lineTo(cx + Math.cos(rot) * innerRadius, cy + Math.sin(rot) * innerRadius);
rot += step;
ctx.lineTo(cx + Math.cos(rot) * outerRadius, cy + Math.sin(rot) * outerRadius);
}
ctx.closePath();
const r = Math.floor(220 + 35 * alpha);
const g = Math.floor(190 + 50 * alpha);
const b = Math.floor(60 + 30 * alpha);
ctx.fillStyle = `rgba(${r},${g},${b},0.95)`;
ctx.shadowBlur = 12;
ctx.shadowColor = `rgba(${r},${g},${b},0.6)`;
ctx.fill();
if (alpha > 0.9) {
ctx.beginPath();
ctx.arc(cx, cy, outerRadius / 2, 0, 2 * Math.PI);
ctx.fillStyle = `rgba(255, 245, 200, ${alpha * 0.7})`;
ctx.fill();
}
}
function animate() {
ctx.clearRect(0, 0, w, h);
stars.forEach(star => {
star.distance += star.speed;
const pos = getPointOnPerimeter(star.distance);
const flicker = pulse(star.flickerPhase % (Math.PI * 2));
const size = flicker * star.maxSize;
drawStar(ctx, pos.x, pos.y, 5, size, size / 2, flicker, star.rotate);
star.flickerPhase += star.flickerSpeed;
});
animationId = requestAnimationFrame(animate);
}
window.addEventListener("resize", () => {
initCanvas();
});
initCanvas();
animate();
})();
</script>
</body>
</html>