Skip to content

Commit ab08f08

Browse files
committed
优化动态背景动画逻辑,减少内存分配与GC开销,预计算颜色与距离提升渲染效率,增强交互表现力,调整桌面端粒子数量范围以提升画面效果。
1 parent d80027e commit ab08f08

File tree

2 files changed

+73
-23
lines changed

2 files changed

+73
-23
lines changed

composeApp/src/wasmJsMain/kotlin/love/forte/simbot/codegen/components/OptimizedAnimatedBackground.kt

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ fun OptimizedAnimatedBackground(
8787
// Convert dp to px and pre-calculate squared distance for performance
8888
val connectionDistancePx = with(density) { maxConnectionDistance.dp.toPx() }
8989
val connectionDistanceSquared = connectionDistancePx * connectionDistancePx
90+
91+
// Pre-calculate sqrt to avoid repeated expensive operations in drawing loops
92+
val connectionDistance = connectionDistancePx
9093

9194
// Mutable particles list for better performance
9295
val particles = remember { mutableListOf<MutableParticle>() }
@@ -95,11 +98,26 @@ fun OptimizedAnimatedBackground(
9598
// Theme-aware cached colors with sci-fi glow effects
9699
val cachedColors = remember(colorScheme, themeEffects?.glowIntensity) {
97100
val glowIntensity = themeEffects?.glowIntensity ?: 0f
101+
val particleAlpha = 0.65f + glowIntensity * 0.2f
102+
val connectionAlpha = 0.4f + glowIntensity * 0.15f
103+
val mouseConnectionAlpha = 0.48f + glowIntensity * 0.25f
104+
val triangleFillAlpha = 0.08f + glowIntensity * 0.03f
105+
98106
ParticleColors(
99-
particleColor = colorScheme.primary.copy(alpha = 0.65f + glowIntensity * 0.2f),
100-
connectionColor = colorScheme.secondary.copy(alpha = 0.4f + glowIntensity * 0.15f),
101-
mouseConnectionColor = colorScheme.secondary.copy(alpha = 0.48f + glowIntensity * 0.25f),
102-
triangleFillColor = colorScheme.secondary.copy(alpha = 0.08f + glowIntensity * 0.03f)
107+
particleColor = colorScheme.primary.copy(alpha = particleAlpha),
108+
connectionColor = colorScheme.secondary.copy(alpha = connectionAlpha),
109+
mouseConnectionColor = colorScheme.secondary.copy(alpha = mouseConnectionAlpha),
110+
triangleFillColor = colorScheme.secondary.copy(alpha = triangleFillAlpha),
111+
// Base colors without alpha for efficient calculations
112+
particleBaseColor = colorScheme.primary,
113+
connectionBaseColor = colorScheme.secondary,
114+
mouseConnectionBaseColor = colorScheme.secondary,
115+
triangleFillBaseColor = colorScheme.secondary,
116+
// Pre-calculated alpha values
117+
particleBaseAlpha = particleAlpha,
118+
connectionBaseAlpha = connectionAlpha,
119+
mouseConnectionBaseAlpha = mouseConnectionAlpha,
120+
triangleFillBaseAlpha = triangleFillAlpha
103121
)
104122
}
105123

@@ -152,6 +170,7 @@ fun OptimizedAnimatedBackground(
152170
drawOptimizedParticlesAndConnections(
153171
particles = particles,
154172
connectionDistanceSquared = connectionDistanceSquared,
173+
connectionDistance = connectionDistance,
155174
colors = cachedColors,
156175
mousePosition = mousePosition
157176
)
@@ -161,14 +180,44 @@ fun OptimizedAnimatedBackground(
161180
}
162181

163182
/**
164-
* Color cache to reduce object allocation during drawing
183+
* Optimized color cache to eliminate Color.copy() allocations.
184+
* Stores base colors and alpha values separately for efficient alpha blending.
165185
*/
186+
@Immutable
187+
@Stable
166188
private data class ParticleColors(
167189
val particleColor: Color,
168190
val connectionColor: Color,
169191
val mouseConnectionColor: Color,
170-
val triangleFillColor: Color
171-
)
192+
val triangleFillColor: Color,
193+
// Base colors without alpha for efficient dynamic alpha calculation
194+
val particleBaseColor: Color,
195+
val connectionBaseColor: Color,
196+
val mouseConnectionBaseColor: Color,
197+
val triangleFillBaseColor: Color,
198+
// Pre-calculated alpha values
199+
val particleBaseAlpha: Float,
200+
val connectionBaseAlpha: Float,
201+
val mouseConnectionBaseAlpha: Float,
202+
val triangleFillBaseAlpha: Float
203+
) {
204+
// Efficient color calculation without object allocation
205+
@Stable
206+
fun connectionColorWithAlpha(alpha: Float): Color =
207+
connectionBaseColor.copy(alpha = alpha * connectionBaseAlpha)
208+
209+
@Stable
210+
fun mouseConnectionColorWithAlpha(alpha: Float): Color =
211+
mouseConnectionBaseColor.copy(alpha = alpha * mouseConnectionBaseAlpha)
212+
213+
@Stable
214+
fun particleColorWithAlpha(alpha: Float): Color =
215+
particleBaseColor.copy(alpha = alpha * particleBaseAlpha)
216+
//
217+
// @Stable
218+
// fun triangleFillColorWithAlpha(alpha: Float): Color =
219+
// triangleFillBaseColor.copy(alpha = alpha * triangleFillBaseAlpha)
220+
}
172221

173222
/**
174223
* Create optimized mutable particle
@@ -226,6 +275,7 @@ private fun DrawScope.drawTriangles(
226275
mouseConnections: List<Int>,
227276
mousePosition: Offset?,
228277
connectionDistanceSquared: Float,
278+
connectionDistance: Float,
229279
colors: ParticleColors
230280
) {
231281

@@ -262,7 +312,7 @@ private fun DrawScope.drawTriangles(
262312
particles[p1Index],
263313
particles[p2Index],
264314
particles[p3Index],
265-
connectionDistanceSquared,
315+
connectionDistance,
266316
colors.triangleFillColor
267317
)
268318
}
@@ -288,7 +338,7 @@ private fun DrawScope.drawTriangles(
288338
particles[p1Index],
289339
particles[p2Index],
290340
mouse,
291-
connectionDistanceSquared,
341+
connectionDistance,
292342
colors.triangleFillColor
293343
)
294344
}
@@ -305,7 +355,7 @@ private fun DrawScope.drawGlassTriangle(
305355
p1: MutableParticle,
306356
p2: MutableParticle,
307357
p3: MutableParticle,
308-
connectionDistanceSquared: Float,
358+
connectionDistance: Float,
309359
baseColor: Color
310360
) {
311361
// Calculate distances of all three edges to find the longest
@@ -316,7 +366,7 @@ private fun DrawScope.drawGlassTriangle(
316366
// Use the longest edge for alpha calculation
317367
val longestDistanceSquared = maxOf(dist1Sq, dist2Sq, dist3Sq)
318368
val longestDistance = kotlin.math.sqrt(longestDistanceSquared)
319-
val maxDistance = kotlin.math.sqrt(connectionDistanceSquared)
369+
val maxDistance = connectionDistance
320370

321371
// Make triangles fainter and decay faster than connection lines
322372
// Base alpha factor is 0.3 (much fainter than lines) and use squared ratio for faster decay
@@ -332,7 +382,7 @@ private fun DrawScope.drawGlassTriangle(
332382

333383
drawPath(
334384
path = trianglePath,
335-
color = baseColor.copy(alpha = alpha)
385+
color = Color(baseColor.red, baseColor.green, baseColor.blue, alpha)
336386
)
337387
}
338388

@@ -343,7 +393,7 @@ private fun DrawScope.drawGlassTriangleWithMouse(
343393
p1: MutableParticle,
344394
p2: MutableParticle,
345395
mousePos: Offset,
346-
connectionDistanceSquared: Float,
396+
connectionDistance: Float,
347397
baseColor: Color
348398
) {
349399
// Calculate distances of all three edges to find the longest
@@ -354,7 +404,7 @@ private fun DrawScope.drawGlassTriangleWithMouse(
354404
// Use the longest edge for alpha calculation
355405
val longestDistanceSquared = maxOf(dist1Sq, dist2Sq, dist3Sq)
356406
val longestDistance = kotlin.math.sqrt(longestDistanceSquared)
357-
val maxDistance = kotlin.math.sqrt(connectionDistanceSquared)
407+
val maxDistance = connectionDistance
358408

359409
// Make triangles fainter and decay faster than connection lines
360410
// Mouse triangles get slightly higher intensity (0.4 vs 0.3) but still much fainter than lines
@@ -370,7 +420,7 @@ private fun DrawScope.drawGlassTriangleWithMouse(
370420

371421
drawPath(
372422
path = trianglePath,
373-
color = baseColor.copy(alpha = alpha)
423+
color = Color(baseColor.red, baseColor.green, baseColor.blue, alpha)
374424
)
375425
}
376426

@@ -386,6 +436,7 @@ private fun DrawScope.drawGlassTriangleWithMouse(
386436
private fun DrawScope.drawOptimizedParticlesAndConnections(
387437
particles: List<MutableParticle>,
388438
connectionDistanceSquared: Float,
439+
connectionDistance: Float,
389440
colors: ParticleColors,
390441
mousePosition: Offset? = null
391442
) {
@@ -413,10 +464,10 @@ private fun DrawScope.drawOptimizedParticlesAndConnections(
413464

414465
// Only calculate sqrt when we know we need to draw
415466
val distance = kotlin.math.sqrt(distanceSquared)
416-
val alpha = (1 - distance / kotlin.math.sqrt(connectionDistanceSquared)) * colors.connectionColor.alpha
467+
val alphaFactor = 1 - distance / connectionDistance
417468

418469
drawLine(
419-
color = colors.connectionColor.copy(alpha = alpha),
470+
color = colors.connectionColorWithAlpha(alphaFactor),
420471
start = Offset(particle1.x, particle1.y),
421472
end = Offset(particle2.x, particle2.y),
422473
strokeWidth = 1f
@@ -437,11 +488,10 @@ private fun DrawScope.drawOptimizedParticlesAndConnections(
437488
mouseConnections.add(index)
438489

439490
val distance = kotlin.math.sqrt(distanceSquared)
440-
val alpha =
441-
(1 - distance / kotlin.math.sqrt(connectionDistanceSquared)) * colors.mouseConnectionColor.alpha
491+
val alphaFactor = 1 - distance / connectionDistance
442492

443493
drawLine(
444-
color = colors.mouseConnectionColor.copy(alpha = alpha),
494+
color = colors.mouseConnectionColorWithAlpha(alphaFactor),
445495
start = Offset(particle.x, particle.y),
446496
end = mouse,
447497
strokeWidth = 1.5f
@@ -451,12 +501,12 @@ private fun DrawScope.drawOptimizedParticlesAndConnections(
451501
}
452502

453503
// Draw glass shard triangles
454-
drawTriangles(particles, connections, mouseConnections, mousePosition, connectionDistanceSquared, colors)
504+
drawTriangles(particles, connections, mouseConnections, mousePosition, connectionDistanceSquared, connectionDistance, colors)
455505

456506
// Draw particles with cached colors
457507
particles.forEach { particle ->
458508
drawCircle(
459-
color = colors.particleColor.copy(alpha = particle.alpha),
509+
color = colors.particleColorWithAlpha(particle.alpha),
460510
radius = particle.radius,
461511
center = Offset(particle.x, particle.y)
462512
)

composeApp/src/wasmJsMain/kotlin/love/forte/simbot/codegen/gen/view/GradleSettingsView.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fun GradleSettingsView(
7777
// 移动端使用较少粒子
7878
WindowSize.Mobile -> Random.nextInt(20, 25)
7979
WindowSize.Tablet -> Random.nextInt(35, 45)
80-
WindowSize.Desktop -> Random.nextInt(50, 65)
80+
WindowSize.Desktop -> Random.nextInt(70, 100)
8181
}
8282
},
8383
mousePosition = mousePosition

0 commit comments

Comments
 (0)