From 409942b4af67d76814b52cb1f46dbb8442f0ea48 Mon Sep 17 00:00:00 2001 From: gem Date: Tue, 9 Jun 2026 12:06:58 +0800 Subject: [PATCH] Fix text alpha updates during fade --- lib/runtime/rendering/runtime_component.dart | 41 +++++++++++------ .../rendering/runtime_component_test.dart | 45 +++++++++++++++++++ 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/lib/runtime/rendering/runtime_component.dart b/lib/runtime/rendering/runtime_component.dart index 3dd2f90..aaef7a8 100644 --- a/lib/runtime/rendering/runtime_component.dart +++ b/lib/runtime/rendering/runtime_component.dart @@ -67,7 +67,12 @@ class RuntimeComponent extends PositionComponent double get renderAlpha => _runtimeAlpha ?? _node.alpha; void setRuntimeAlpha(double value) { - _runtimeAlpha = value.clamp(0, 1).toDouble(); + final next = value.clamp(0, 1).toDouble(); + if (_runtimeAlpha == next) { + return; + } + _runtimeAlpha = next; + _syncTextStyle(_node); } void setParentScroll({ @@ -961,21 +966,11 @@ class RuntimeComponent extends PositionComponent } final text = label ?? ''; - final color = _textColor(node); - final style = TextStyle( - color: composeRuntimeColorAlpha(color, renderAlpha), - fontSize: node.fontSize ?? 18, - fontWeight: node.type == RuntimeNodeType.button - ? FontWeight.w600 - : FontWeight.normal, - shadows: _textShadows(node), - ); - final component = _textComponent; if (component == null) { _textComponent = TextComponent( text: text, - textRenderer: TextPaint(style: style), + textRenderer: TextPaint(style: _textStyle(node)), anchor: _textAnchor(node), position: _textPosition(node), priority: priority + 1, @@ -986,10 +981,30 @@ class RuntimeComponent extends PositionComponent component ..text = text - ..textRenderer = TextPaint(style: style) ..anchor = _textAnchor(node) ..position = _textPosition(node) ..priority = priority + 1; + _syncTextStyle(node); + } + + void _syncTextStyle(RuntimeNode node) { + final component = _textComponent; + if (component == null) { + return; + } + component.textRenderer = TextPaint(style: _textStyle(node)); + } + + TextStyle _textStyle(RuntimeNode node) { + final color = _textColor(node); + return TextStyle( + color: composeRuntimeColorAlpha(color, renderAlpha), + fontSize: node.fontSize ?? 18, + fontWeight: node.type == RuntimeNodeType.button + ? FontWeight.w600 + : FontWeight.normal, + shadows: _textShadows(node), + ); } @override diff --git a/test/runtime/rendering/runtime_component_test.dart b/test/runtime/rendering/runtime_component_test.dart index eb1bc8b..cb29170 100644 --- a/test/runtime/rendering/runtime_component_test.dart +++ b/test/runtime/rendering/runtime_component_test.dart @@ -138,6 +138,51 @@ void main() { ); }); + test('updates text alpha style without rebuilding text component', () { + final component = RuntimeComponent( + node: const RuntimeNode( + id: 'text', + type: RuntimeNodeType.text, + text: 'Fade me', + alpha: 0, + color: Color(0xffffffff), + ), + resources: GameResourceManager(), + onNodeTap: (_, __) {}, + ); + + final text = component.children.whereType().single; + expect(((text.textRenderer as TextPaint).style.color!).a, 0); + + component.setRuntimeAlpha(1); + + final updatedText = component.children.whereType().single; + expect(identical(updatedText, text), isTrue); + expect(((updatedText.textRenderer as TextPaint).style.color!).a, 1); + }); + + test('updates button text alpha style without rebuilding text component', () { + final component = RuntimeComponent( + node: const RuntimeNode( + id: 'button', + type: RuntimeNodeType.button, + text: 'Fade me', + alpha: 0, + ), + resources: GameResourceManager(), + onNodeTap: (_, __) {}, + ); + + final text = component.children.whereType().single; + expect(((text.textRenderer as TextPaint).style.color!).a, 0); + + component.setRuntimeAlpha(1); + + final updatedText = component.children.whereType().single; + expect(identical(updatedText, text), isTrue); + expect(((updatedText.textRenderer as TextPaint).style.color!).a, 1); + }); + test('applies text shadow style', () { final component = RuntimeComponent( node: const RuntimeNode(