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,15 +101,32 @@ const render = () => { ...@@ -101,15 +101,32 @@ const render = () => {
101 101
102 // 流星逻辑 102 // 流星逻辑
103 if (i === meteorIndex) { 103 if (i === meteorIndex) {
104 - star.vx = props.meteorVx; 104 + // 检查流星是否超出边界,如果是则重置
105 - star.vy = props.meteorVy; 105 + if (star.x < -100 || star.y > height + 100) {
106 - context.beginPath(); 106 + meteorIndex = -1; // 结束当前流星
107 - context.strokeStyle = `rgba(${props.starColor}, ${star.alpha})`; 107 + } else {
108 - context.lineWidth = star.r; 108 + star.vx = props.meteorVx;
109 - context.moveTo(star.x, star.y); 109 + star.vy = props.meteorVy;
110 - context.lineTo(star.x + star.vx * props.meteorTrail, star.y + star.vy * props.meteorTrail); 110 + context.beginPath();
111 - context.stroke(); 111 +
112 - context.closePath(); 112 + // 创建线性渐变来实现淡入淡出和拖尾效果
113 + const meteorHeadX = star.x + star.vx;
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);
127 + context.stroke();
128 + context.closePath();
129 + }
113 } 130 }
114 131
115 // 星星闪烁与移动逻辑 132 // 星星闪烁与移动逻辑
...@@ -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 };
......