feat(accessibility): add reduceMotion scaling and minimize animations; apply RepaintBoundary to heavy widgets

This commit is contained in:
JiWoong Sul
2025-09-08 14:30:28 +09:00
parent 10491af55b
commit eb6691ce6a
11 changed files with 478 additions and 331 deletions

View File

@@ -6,6 +6,7 @@ import '../services/sms_service.dart';
import '../utils/platform_helper.dart';
import '../routes/app_routes.dart';
import '../l10n/app_localizations.dart';
import '../utils/reduce_motion.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
@@ -65,7 +66,8 @@ class _SplashScreenState extends State<SplashScreen>
));
// 랜덤 파티클 생성
_generateParticles();
// 접근성(모션 축소) 고려한 파티클 생성
_generateParticles(reduced: ReduceMotion.platform());
_animationController.forward();
@@ -75,15 +77,17 @@ class _SplashScreenState extends State<SplashScreen>
});
}
void _generateParticles() {
void _generateParticles({bool reduced = false}) {
final random = DateTime.now().millisecondsSinceEpoch;
final total = reduced ? 6 : 20;
for (int i = 0; i < 20; i++) {
for (int i = 0; i < total; i++) {
final size = (random % 10) / 10 * 8 + 2; // 2-10 사이의 크기
final x = (random % 100) / 100 * 300; // 랜덤 X 위치
final y = (random % 100) / 100 * 500; // 랜덤 Y 위치
final opacity = (random % 10) / 10 * 0.4 + 0.1; // 0.1-0.5 사이의 투명도
final duration = (random % 10) / 10 * 3000 + 2000; // 2-5초 사이의 지속시간
final duration = (random % 10) / 10 * (reduced ? 1800 : 3000) +
(reduced ? 1200 : 2000); // 축소 시 더 짧게
final delay = (random % 10) / 10 * 2000; // 0-2초 사이의 지연시간
int colorIndex = (random + i) % AppColors.blueGradient.length;
@@ -257,7 +261,14 @@ class _SplashScreenState extends State<SplashScreen>
BorderRadius.circular(30),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 20, sigmaY: 20),
sigmaX: ReduceMotion.scale(
context,
normal: 20,
reduced: 8),
sigmaY: ReduceMotion.scale(
context,
normal: 20,
reduced: 8)),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
@@ -277,13 +288,17 @@ class _SplashScreenState extends State<SplashScreen>
.withValues(alpha: 0.3),
width: 1.5,
),
boxShadow: const [
boxShadow: [
BoxShadow(
color:
AppColors.shadowBlack,
spreadRadius: 0,
blurRadius: 30,
offset: Offset(0, 10),
blurRadius:
ReduceMotion.scale(
context,
normal: 30,
reduced: 12),
offset: const Offset(0, 10),
),
],
),