feat(accessibility): add reduceMotion scaling and minimize animations; apply RepaintBoundary to heavy widgets
This commit is contained in:
@@ -10,6 +10,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import '../utils/reduce_motion.dart';
|
||||
|
||||
// 파비콘 캐시 관리 클래스
|
||||
class FaviconCache {
|
||||
@@ -190,12 +191,15 @@ class _WebsiteIconState extends State<WebsiteIcon>
|
||||
// 애니메이션 컨트롤러 초기화
|
||||
_animationController = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
duration: ReduceMotion.platform()
|
||||
? const Duration(milliseconds: 0)
|
||||
: const Duration(milliseconds: 300),
|
||||
);
|
||||
|
||||
_scaleAnimation = Tween<double>(begin: 1.0, end: 1.08).animate(
|
||||
CurvedAnimation(
|
||||
parent: _animationController, curve: Curves.easeOutCubic));
|
||||
_scaleAnimation =
|
||||
Tween<double>(begin: 1.0, end: ReduceMotion.platform() ? 1.0 : 1.08)
|
||||
.animate(CurvedAnimation(
|
||||
parent: _animationController, curve: Curves.easeOutCubic));
|
||||
|
||||
// 초기 _previousServiceKey 설정
|
||||
_previousServiceKey = _serviceKey;
|
||||
@@ -548,11 +552,14 @@ class _WebsiteIconState extends State<WebsiteIcon>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedBuilder(
|
||||
return RepaintBoundary(
|
||||
child: AnimatedBuilder(
|
||||
animation: _animationController,
|
||||
builder: (context, child) {
|
||||
final scale =
|
||||
ReduceMotion.isEnabled(context) ? 1.0 : _scaleAnimation.value;
|
||||
return Transform.scale(
|
||||
scale: _scaleAnimation.value,
|
||||
scale: scale,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
@@ -578,12 +585,25 @@ class _WebsiteIconState extends State<WebsiteIcon>
|
||||
),
|
||||
child: _buildIconContent(),
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildIconContent() {
|
||||
// 로딩 중 표시
|
||||
if (_isLoading) {
|
||||
if (ReduceMotion.isEnabled(context)) {
|
||||
return Container(
|
||||
key: ValueKey('loading_${widget.serviceName}_$_uniqueId'),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.surfaceColorAlt,
|
||||
borderRadius: BorderRadius.circular(widget.size * 0.2),
|
||||
border: Border.all(
|
||||
color: AppColors.borderColor,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container(
|
||||
key: ValueKey('loading_${widget.serviceName}_$_uniqueId'),
|
||||
decoration: BoxDecoration(
|
||||
@@ -633,20 +653,31 @@ class _WebsiteIconState extends State<WebsiteIcon>
|
||||
width: widget.size,
|
||||
height: widget.size,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (context, url) => Container(
|
||||
color: AppColors.surfaceColorAlt,
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: widget.size * 0.4,
|
||||
height: widget.size * 0.4,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
AppColors.primaryColor.withValues(alpha: 0.7)),
|
||||
fadeInDuration: ReduceMotion.isEnabled(context)
|
||||
? const Duration(milliseconds: 0)
|
||||
: const Duration(milliseconds: 300),
|
||||
fadeOutDuration: ReduceMotion.isEnabled(context)
|
||||
? const Duration(milliseconds: 0)
|
||||
: const Duration(milliseconds: 300),
|
||||
placeholder: (context, url) {
|
||||
if (ReduceMotion.isEnabled(context)) {
|
||||
return Container(color: AppColors.surfaceColorAlt);
|
||||
}
|
||||
return Container(
|
||||
color: AppColors.surfaceColorAlt,
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: widget.size * 0.4,
|
||||
height: widget.size * 0.4,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
AppColors.primaryColor.withValues(alpha: 0.7)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
errorWidget: (context, url, error) => _buildFallbackIcon(),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user