hookehuyr

perf(NumberRoll): 优化数字滚动动画性能和渲染效果

- 使用更平滑的缓动函数 easeOutQuart 替代 easeOutCubic
- 减少不必要的值更新,只在变化明显时更新
- 添加硬件加速优化(translateZ(0))
- 移除CSS transition,完全由JS控制动画
- 添加文本渲染优化属性
...@@ -8,7 +8,10 @@ ...@@ -8,7 +8,10 @@
8 <view class="digit-wrapper"> 8 <view class="digit-wrapper">
9 <view 9 <view
10 class="digit-column" 10 class="digit-column"
11 - :style="{ transform: `translateY(-${digit.currentValue * 10}%)` }" 11 + :style="{
12 + transform: `translateY(-${digit.currentValue * 10}%) translateZ(0)`,
13 + willChange: isAnimating ? 'transform' : 'auto'
14 + }"
12 > 15 >
13 <view 16 <view
14 v-for="num in 10" 17 v-for="num in 10"
...@@ -115,12 +118,17 @@ const animateDigit = (digit, index) => { ...@@ -115,12 +118,17 @@ const animateDigit = (digit, index) => {
115 const elapsed = currentTime - startTime 118 const elapsed = currentTime - startTime
116 const progress = Math.min(elapsed / props.duration, 1) 119 const progress = Math.min(elapsed / props.duration, 1)
117 120
118 - // 使用缓动函数 121 + // 使用更平滑的缓动函数
119 - const easeProgress = easeOutCubic(progress) 122 + const easeProgress = easeOutQuart(progress)
120 123
121 - // 计算当前值 124 + // 计算当前值,使用更精确的计算
122 const currentValue = startValue + (endValue - startValue) * easeProgress 125 const currentValue = startValue + (endValue - startValue) * easeProgress
123 - digit.currentValue = currentValue 126 +
127 + // 减少不必要的更新,只在值有明显变化时更新
128 + const roundedValue = Math.round(currentValue * 100) / 100
129 + if (Math.abs(digit.currentValue - roundedValue) > 0.01) {
130 + digit.currentValue = roundedValue
131 + }
124 132
125 if (progress < 1) { 133 if (progress < 1) {
126 digit.animationId = requestAnimationFrame(animate) 134 digit.animationId = requestAnimationFrame(animate)
...@@ -133,9 +141,9 @@ const animateDigit = (digit, index) => { ...@@ -133,9 +141,9 @@ const animateDigit = (digit, index) => {
133 digit.animationId = requestAnimationFrame(animate) 141 digit.animationId = requestAnimationFrame(animate)
134 } 142 }
135 143
136 -// 缓动函数 144 +// 更平滑的缓动函数
137 -const easeOutCubic = (t) => { 145 +const easeOutQuart = (t) => {
138 - return 1 - Math.pow(1 - t, 3) 146 + return 1 - Math.pow(1 - t, 4)
139 } 147 }
140 148
141 // 检查动画是否完成 149 // 检查动画是否完成
...@@ -239,6 +247,10 @@ defineExpose({ ...@@ -239,6 +247,10 @@ defineExpose({
239 background: rgba(255, 255, 255, 0.1); 247 background: rgba(255, 255, 255, 0.1);
240 border-radius: 8rpx; 248 border-radius: 8rpx;
241 border: 1rpx solid rgba(255, 255, 255, 0.2); 249 border: 1rpx solid rgba(255, 255, 255, 0.2);
250 + // 启用硬件加速
251 + transform: translateZ(0);
252 + backface-visibility: hidden;
253 + perspective: 1000px;
242 } 254 }
243 255
244 .digit-wrapper { 256 .digit-wrapper {
...@@ -246,6 +258,8 @@ defineExpose({ ...@@ -246,6 +258,8 @@ defineExpose({
246 width: 100%; 258 width: 100%;
247 height: 100%; 259 height: 100%;
248 overflow: hidden; 260 overflow: hidden;
261 + // 启用硬件加速
262 + transform: translateZ(0);
249 } 263 }
250 264
251 .digit-column { 265 .digit-column {
...@@ -253,7 +267,11 @@ defineExpose({ ...@@ -253,7 +267,11 @@ defineExpose({
253 top: 0; 267 top: 0;
254 left: 0; 268 left: 0;
255 width: 100%; 269 width: 100%;
256 - transition: transform 0.1s ease-out; 270 + // 移除CSS transition,完全由JS控制动画
271 + // transition: transform 0.1s ease-out;
272 + // 启用硬件加速和优化
273 + transform-style: preserve-3d;
274 + backface-visibility: hidden;
257 } 275 }
258 276
259 .digit-item { 277 .digit-item {
...@@ -266,5 +284,10 @@ defineExpose({ ...@@ -266,5 +284,10 @@ defineExpose({
266 font-weight: bold; 284 font-weight: bold;
267 color: #fff; 285 color: #fff;
268 font-family: 'Courier New', monospace; 286 font-family: 'Courier New', monospace;
287 + // 文本渲染优化
288 + text-rendering: optimizeSpeed;
289 + -webkit-font-smoothing: antialiased;
290 + // 启用硬件加速
291 + transform: translateZ(0);
269 } 292 }
270 </style> 293 </style>
......