From 5d5823931369209e5560f1381112bc66284600c5 Mon Sep 17 00:00:00 2001 From: JiWoong Sul Date: Wed, 31 Dec 2025 00:20:15 +0900 Subject: [PATCH] =?UTF-8?q?feat(animation):=20ASCII=20=EC=BA=94=EB=B2=84?= =?UTF-8?q?=EC=8A=A4=20=EB=B0=8F=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=B9=B4=EB=93=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ascii_canvas_painter: 렌더링 개선 - ascii_canvas_widget: 기능 추가 - ascii_animation_card: 스타일 업데이트 --- .../canvas/ascii_canvas_painter.dart | 25 ++++++++++++++----- .../animation/canvas/ascii_canvas_widget.dart | 12 +++++++++ .../game/widgets/ascii_animation_card.dart | 9 ++++--- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/lib/src/core/animation/canvas/ascii_canvas_painter.dart b/lib/src/core/animation/canvas/ascii_canvas_painter.dart index c4398a4..654caa1 100644 --- a/lib/src/core/animation/canvas/ascii_canvas_painter.dart +++ b/lib/src/core/animation/canvas/ascii_canvas_painter.dart @@ -40,6 +40,7 @@ class _ParagraphCacheKey { /// 레이어 기반으로 ASCII 문자를 Canvas에 그린다. /// 각 문자는 고정 크기 그리드 셀에 배치된다. /// Paragraph 캐싱으로 GC 압박 최소화. +/// 테마 인식 색상 지원 (Phase 5). class AsciiCanvasPainter extends CustomPainter { AsciiCanvasPainter({ required this.layers, @@ -48,6 +49,9 @@ class AsciiCanvasPainter extends CustomPainter { this.backgroundColor = AsciiColors.background, this.backgroundOpacity = 0.5, this.layerVersion = 0, + this.objectColor = AsciiColors.object, + this.positiveColor = AsciiColors.positive, + this.negativeColor = AsciiColors.negative, }); /// 렌더링할 레이어 목록 (z-order 정렬 필요) @@ -59,7 +63,7 @@ class AsciiCanvasPainter extends CustomPainter { /// 그리드 높이 (행 수) final int gridHeight; - /// 배경색 + /// 배경색 (테마 인식 가능) final Color backgroundColor; /// 배경 투명도 (0.0 ~ 1.0, 기본값 0.5 = 50%) @@ -68,6 +72,15 @@ class AsciiCanvasPainter extends CustomPainter { /// 레이어 버전 (변경 감지용) final int layerVersion; + /// 오브젝트 색상 (테마 인식) + final Color objectColor; + + /// 포지티브 이펙트 색상 (테마 인식) + final Color positiveColor; + + /// 네거티브 이펙트 색상 (테마 인식) + final Color negativeColor; + /// Paragraph 캐시 (문자+색상+크기 조합별) static final Map<_ParagraphCacheKey, ui.Paragraph> _paragraphCache = {}; @@ -189,13 +202,13 @@ class AsciiCanvasPainter extends CustomPainter { canvas.drawParagraph(paragraph, Offset(offsetX, offsetY)); } - /// AsciiCellColor를 Flutter Color로 변환 + /// AsciiCellColor를 Flutter Color로 변환 (테마 인식 색상 사용) Color _getColor(AsciiCellColor cellColor) { return switch (cellColor) { - AsciiCellColor.background => AsciiColors.background, - AsciiCellColor.object => AsciiColors.object, - AsciiCellColor.positive => AsciiColors.positive, - AsciiCellColor.negative => AsciiColors.negative, + AsciiCellColor.background => backgroundColor, + AsciiCellColor.object => objectColor, + AsciiCellColor.positive => positiveColor, + AsciiCellColor.negative => negativeColor, }; } diff --git a/lib/src/core/animation/canvas/ascii_canvas_widget.dart b/lib/src/core/animation/canvas/ascii_canvas_widget.dart index ce6ea06..cd2638e 100644 --- a/lib/src/core/animation/canvas/ascii_canvas_widget.dart +++ b/lib/src/core/animation/canvas/ascii_canvas_widget.dart @@ -1,5 +1,6 @@ import 'package:askiineverdie/src/core/animation/canvas/ascii_canvas_painter.dart'; import 'package:askiineverdie/src/core/animation/canvas/ascii_layer.dart'; +import 'package:askiineverdie/src/core/constants/ascii_colors.dart'; import 'package:flutter/material.dart'; /// ASCII Canvas 위젯 (RepaintBoundary 포함) @@ -7,6 +8,7 @@ import 'package:flutter/material.dart'; /// AsciiCanvasPainter를 감싸는 위젯. /// RepaintBoundary로 성능 최적화. /// willChange를 애니메이션 상태에 따라 동적 설정. +/// 테마 인식 색상 자동 적용 (Phase 5). class AsciiCanvasWidget extends StatelessWidget { const AsciiCanvasWidget({ super.key, @@ -38,14 +40,24 @@ class AsciiCanvasWidget extends StatelessWidget { @override Widget build(BuildContext context) { + // 테마 인식 색상 (다크/라이트 모드 자동 전환) + final bgColor = AsciiColors.backgroundOf(context); + final objColor = AsciiColors.objectOf(context); + final posColor = AsciiColors.positiveOf(context); + final negColor = AsciiColors.negativeOf(context); + return RepaintBoundary( child: CustomPaint( painter: AsciiCanvasPainter( layers: layers, gridWidth: gridWidth, gridHeight: gridHeight, + backgroundColor: bgColor, backgroundOpacity: backgroundOpacity, layerVersion: layerVersion, + objectColor: objColor, + positiveColor: posColor, + negativeColor: negColor, ), size: Size.infinite, isComplex: true, diff --git a/lib/src/features/game/widgets/ascii_animation_card.dart b/lib/src/features/game/widgets/ascii_animation_card.dart index d45b946..7238aab 100644 --- a/lib/src/features/game/widgets/ascii_animation_card.dart +++ b/lib/src/features/game/widgets/ascii_animation_card.dart @@ -529,8 +529,9 @@ class _AsciiAnimationCardState extends State { @override Widget build(BuildContext context) { - // 검정 배경 위에 배경 레이어(50% 투명)가 그려짐 - const bgColor = AsciiColors.background; + // 테마 인식 배경색 (다크: 검정, 라이트: 양피지) + final bgColor = AsciiColors.backgroundOf(context); + final positiveColor = AsciiColors.positiveOf(context); // 테두리 효과 결정 (전투 이벤트 또는 특수 애니메이션) final isSpecial = _currentSpecialAnimation != null; @@ -560,9 +561,9 @@ class _AsciiAnimationCardState extends State { width: 2, ); } else if (isSpecial) { - // 특수 애니메이션: 시안 테두리 + // 특수 애니메이션: 포지티브 색상 테두리 borderEffect = Border.all( - color: AsciiColors.positive.withValues(alpha: 0.5), + color: positiveColor.withValues(alpha: 0.5), ); }