hookehuyr

feat(StarryBackground): 优化流星效果并调整默认参数

- 增加流星边界检测和重置逻辑
- 使用线性渐变实现流星拖尾淡出效果
- 调整流星生成位置使其从右侧出现
- 修改默认速度、长度等参数值
...@@ -31,22 +31,22 @@ const props = defineProps({ ...@@ -31,22 +31,22 @@ const props = defineProps({
31 // 星星移动速度系数 (值越大移动越快) 31 // 星星移动速度系数 (值越大移动越快)
32 starSpeed: { 32 starSpeed: {
33 type: Number, 33 type: Number,
34 - default: 0.15 34 + default: 1
35 }, 35 },
36 // 流星速度 - 水平分量 (负值向左,正值向右) 36 // 流星速度 - 水平分量 (负值向左,正值向右)
37 meteorVx: { 37 meteorVx: {
38 type: Number, 38 type: Number,
39 - default: -2 39 + default: -5
40 }, 40 },
41 // 流星速度 - 垂直分量 (正值向下) 41 // 流星速度 - 垂直分量 (正值向下)
42 meteorVy: { 42 meteorVy: {
43 type: Number, 43 type: Number,
44 - default: 4 44 + default: 5
45 }, 45 },
46 // 流星拖尾长度系数 (值越大尾巴越长) 46 // 流星拖尾长度系数 (值越大尾巴越长)
47 meteorTrail: { 47 meteorTrail: {
48 type: Number, 48 type: Number,
49 - default: 20 49 + default: 5
50 } 50 }
51 }); 51 });
52 52
...@@ -101,16 +101,33 @@ const render = () => { ...@@ -101,16 +101,33 @@ const render = () => {
101 101
102 // 流星逻辑 102 // 流星逻辑
103 if (i === meteorIndex) { 103 if (i === meteorIndex) {
104 + // 检查流星是否超出边界,如果是则重置
105 + if (star.x < -100 || star.y > height + 100) {
106 + meteorIndex = -1; // 结束当前流星
107 + } else {
104 star.vx = props.meteorVx; 108 star.vx = props.meteorVx;
105 star.vy = props.meteorVy; 109 star.vy = props.meteorVy;
106 context.beginPath(); 110 context.beginPath();
107 - context.strokeStyle = `rgba(${props.starColor}, ${star.alpha})`; 111 +
108 - context.lineWidth = star.r; 112 + // 创建线性渐变来实现淡入淡出和拖尾效果
109 - context.moveTo(star.x, star.y); 113 + const meteorHeadX = star.x + star.vx;
110 - context.lineTo(star.x + star.vx * props.meteorTrail, star.y + star.vy * props.meteorTrail); 114 + const meteorHeadY = star.y + star.vy;
115 + const meteorTailX = star.x + star.vx * props.meteorTrail;
116 + const meteorTailY = star.y + star.vy * props.meteorTrail;
117 +
118 + const gradient = context.createLinearGradient(meteorHeadX, meteorHeadY, meteorTailX, meteorTailY);
119 + gradient.addColorStop(0, `rgba(${props.starColor}, 1)`); // 头部最亮
120 + gradient.addColorStop(0.4, `rgba(${props.starColor}, 0.5)`); // 中间半透明
121 + gradient.addColorStop(1, `rgba(${props.starColor}, 0)`); // 尾部完全透明
122 +
123 + context.strokeStyle = gradient;
124 + context.lineWidth = 1; // 细一点
125 + context.moveTo(meteorHeadX, meteorHeadY);
126 + context.lineTo(meteorTailX, meteorTailY);
111 context.stroke(); 127 context.stroke();
112 context.closePath(); 128 context.closePath();
113 } 129 }
130 + }
114 131
115 // 星星闪烁与移动逻辑 132 // 星星闪烁与移动逻辑
116 star.alpha += star.ra; 133 star.alpha += star.ra;
...@@ -161,7 +178,16 @@ const render = () => { ...@@ -161,7 +178,16 @@ const render = () => {
161 const triggerMeteor = () => { 178 const triggerMeteor = () => {
162 const time = Math.round(Math.random() * 3000 + 33); 179 const time = Math.round(Math.random() * 3000 + 33);
163 meteorTimeoutId = setTimeout(() => { 180 meteorTimeoutId = setTimeout(() => {
181 + // 随机选择一个星星作为流星的起点,或者随机生成一个位置
182 + // 为了保证流星从右往左出现,我们从右侧区域随机选点
164 meteorIndex = Math.ceil(Math.random() * stars.length); 183 meteorIndex = Math.ceil(Math.random() * stars.length);
184 +
185 + // 如果选中了星星,重置它的位置到右上方,以便从右往左飞
186 + if (stars[meteorIndex]) {
187 + stars[meteorIndex].x = width + Math.random() * 200; // 屏幕右侧外
188 + stars[meteorIndex].y = Math.random() * height * 0.5; // 屏幕上半部分
189 + }
190 +
165 triggerMeteor(); 191 triggerMeteor();
166 }, time); 192 }, time);
167 }; 193 };
......