feat(animation): ASCII 캔버스 및 애니메이션 카드 개선
- ascii_canvas_painter: 렌더링 개선 - ascii_canvas_widget: 기능 추가 - ascii_animation_card: 스타일 업데이트
This commit is contained in:
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -529,8 +529,9 @@ class _AsciiAnimationCardState extends State<AsciiAnimationCard> {
|
||||
|
||||
@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<AsciiAnimationCard> {
|
||||
width: 2,
|
||||
);
|
||||
} else if (isSpecial) {
|
||||
// 특수 애니메이션: 시안 테두리
|
||||
// 특수 애니메이션: 포지티브 색상 테두리
|
||||
borderEffect = Border.all(
|
||||
color: AsciiColors.positive.withValues(alpha: 0.5),
|
||||
color: positiveColor.withValues(alpha: 0.5),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user