hookehuyr

feat(StarryBackground): 优化星星渲染效果并调整移动速度

添加预渲染星星纹理实现放射效果,改进星星大小随机分布
降低微信移动端星星移动速度系数从1.5到0.3
......@@ -38,7 +38,7 @@ const props = defineProps({
// 星星移动速度系数 (值越大移动越快)
starSpeed: {
type: Number,
default: isWxMobile ? 1.5 : 0.1
default: isWxMobile ? 0.3 : 0.1
},
// 流星速度 - 水平分量 (负值向左,正值向右)
meteorVx: {
......@@ -75,18 +75,58 @@ let context = null;
let width = 0;
let height = 0;
let stars = [];
let starTexture = null; // 预渲染的星星纹理
let animationFrameId = null;
let meteorTimeoutId = null;
let meteorIndex = -1; // 当前流星的索引
// 创建星星纹理(放射效果)
const createStarTexture = () => {
const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 32;
const ctx = canvas.getContext('2d');
const center = 16;
const radius = 16;
// 1. 核心发光 (径向渐变)
const gradient = ctx.createRadialGradient(center, center, 0, center, center, radius);
gradient.addColorStop(0, `rgba(${props.starColor}, 1)`);
gradient.addColorStop(0.2, `rgba(${props.starColor}, 0.8)`);
gradient.addColorStop(0.5, `rgba(${props.starColor}, 0.1)`);
gradient.addColorStop(1, `rgba(${props.starColor}, 0)`);
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(center, center, radius, 0, Math.PI * 2);
ctx.fill();
// 2. 十字星芒 (模拟放射效果)
ctx.strokeStyle = `rgba(${props.starColor}, 0.9)`;
ctx.lineWidth = 1; // 细线条
ctx.beginPath();
// 横向光芒
ctx.moveTo(center - radius, center);
ctx.lineTo(center + radius, center);
// 纵向光芒
ctx.moveTo(center, center - radius);
ctx.lineTo(center, center + radius);
ctx.stroke();
return canvas;
};
// 初始化星星
const initStars = () => {
stars = [];
starTexture = createStarTexture(); // 生成纹理
for (let i = 0; i < props.starCount; i++) {
stars.push({
x: Math.round(Math.random() * width),
y: Math.round(Math.random() * height),
r: Math.random() * 3,
// 增加星星大小的随机性:范围 [2, 12] (因为使用纹理绘制,这里的r代表缩放基准)
// 较小的星星居多,较大的星星较少
r: Math.random() < 0.9 ? Math.random() * 2 + 1 : Math.random() * 6 + 4,
ra: Math.random() * 0.01,
alpha: Math.random(),
vx: Math.random() * props.starSpeed - props.starSpeed / 2,
......@@ -168,20 +208,27 @@ const render = () => {
}
// 绘制星星
context.beginPath();
// 叠加闪烁效果:使用正弦波在基础 alpha 上叠加快速变化
// Date.now() 产生时间变化,i 作为相位偏移,* 0.005 控制闪烁频率
const twinkle = Math.abs(Math.sin(Date.now() * 0.006 + i));
const finalAlpha = Math.min(1, Math.max(0, star.alpha * (0.5 + 0.5 * twinkle)));
const bg = context.createRadialGradient(star.x, star.y, 0, star.x, star.y, star.r);
bg.addColorStop(0, `rgba(${props.starColor}, ${finalAlpha})`);
bg.addColorStop(1, `rgba(${props.starColor}, 0)`);
context.fillStyle = bg;
context.arc(star.x, star.y, star.r, 0, Math.PI * 2, true);
context.fill();
context.closePath();
if (starTexture) {
// 使用预渲染的纹理绘制
context.globalAlpha = finalAlpha;
// star.r 作为大小的一半
context.drawImage(starTexture, star.x - star.r, star.y - star.r, star.r * 2, star.r * 2);
context.globalAlpha = 1.0; // 恢复
} else {
// 降级处理
context.beginPath();
const bg = context.createRadialGradient(star.x, star.y, 0, star.x, star.y, star.r);
bg.addColorStop(0, `rgba(${props.starColor}, ${finalAlpha})`);
bg.addColorStop(1, `rgba(${props.starColor}, 0)`);
context.fillStyle = bg;
context.arc(star.x, star.y, star.r, 0, Math.PI * 2, true);
context.fill();
context.closePath();
}
}
animationFrameId = requestAnimationFrame(render);
......