1
0
mirror of https://github.com/flutter/samples.git synced 2026-10-10 03:11:13 +00:00
Files
samples/animations/lib/src/misc/curved_animation.dart
Eric Windmill 2999d738b8 Dart 3.9 / Flutter 3.35 [first LLM release] (#2714)
I got carried away with Gemini and basically rewrote CI and the release
process for the new LLM reality. This work was largely completed by
Gemini.

- Bump all SDK versions to the current beta (3.9.0-0)
- Run `flutter channel beta`
- Wrote `ci_script.dart` to replace the bash scripts
- Converted repository to pub workspace #2499 
- Added llm.md and release.md
- Added redirect for deprecated Samples Index

## Pre-launch Checklist

- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I have added sample code updates to the [changelog].
- [x] I updated/added relevant documentation (doc comments with `///`).
2025-08-14 12:26:24 -07:00

160 lines
5.2 KiB
Dart

// Copyright 2020 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:math' as math;
import 'package:flutter/material.dart';
class CurvedAnimationDemo extends StatefulWidget {
const CurvedAnimationDemo({super.key});
static const String routeName = 'misc/curved_animation';
@override
State<CurvedAnimationDemo> createState() => _CurvedAnimationDemoState();
}
class CurveChoice {
final Curve curve;
final String name;
const CurveChoice({required this.curve, required this.name});
}
class _CurvedAnimationDemoState extends State<CurvedAnimationDemo>
with SingleTickerProviderStateMixin {
late final AnimationController controller;
late final Animation<double> animationRotation;
late final Animation<Offset> animationTranslation;
static const _duration = Duration(seconds: 4);
List<CurveChoice> curves = const [
CurveChoice(curve: Curves.bounceIn, name: 'Bounce In'),
CurveChoice(curve: Curves.bounceOut, name: 'Bounce Out'),
CurveChoice(curve: Curves.easeInCubic, name: 'Ease In Cubic'),
CurveChoice(curve: Curves.easeOutCubic, name: 'Ease Out Cubic'),
CurveChoice(curve: Curves.easeInExpo, name: 'Ease In Expo'),
CurveChoice(curve: Curves.easeOutExpo, name: 'Ease Out Expo'),
CurveChoice(curve: Curves.elasticIn, name: 'Elastic In'),
CurveChoice(curve: Curves.elasticOut, name: 'Elastic Out'),
CurveChoice(curve: Curves.easeInQuart, name: 'Ease In Quart'),
CurveChoice(curve: Curves.easeOutQuart, name: 'Ease Out Quart'),
CurveChoice(curve: Curves.easeInCirc, name: 'Ease In Circle'),
CurveChoice(curve: Curves.easeOutCirc, name: 'Ease Out Circle'),
];
late CurveChoice selectedForwardCurve, selectedReverseCurve;
late final CurvedAnimation curvedAnimation;
@override
void initState() {
super.initState();
controller = AnimationController(duration: _duration, vsync: this);
selectedForwardCurve = curves[0];
selectedReverseCurve = curves[0];
curvedAnimation = CurvedAnimation(
parent: controller,
curve: selectedForwardCurve.curve,
reverseCurve: selectedReverseCurve.curve,
);
animationRotation =
Tween<double>(begin: 0, end: 2 * math.pi).animate(curvedAnimation)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
}
});
animationTranslation =
Tween<Offset>(
begin: const Offset(-1, 0),
end: const Offset(1, 0),
).animate(curvedAnimation)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Curved Animation')),
body: Column(
children: [
const SizedBox(height: 20.0),
Text(
'Select Curve for forward motion',
style: Theme.of(context).textTheme.titleLarge,
),
DropdownButton<CurveChoice>(
items: curves.map((curve) {
return DropdownMenuItem<CurveChoice>(
value: curve,
child: Text(curve.name),
);
}).toList(),
onChanged: (newCurve) {
if (newCurve != null) {
setState(() {
selectedForwardCurve = newCurve;
curvedAnimation.curve = selectedForwardCurve.curve;
});
}
},
value: selectedForwardCurve,
),
const SizedBox(height: 15.0),
Text(
'Select Curve for reverse motion',
style: Theme.of(context).textTheme.titleLarge,
),
DropdownButton<CurveChoice>(
items: curves.map((curve) {
return DropdownMenuItem<CurveChoice>(
value: curve,
child: Text(curve.name),
);
}).toList(),
onChanged: (newCurve) {
if (newCurve != null) {
setState(() {
selectedReverseCurve = newCurve;
curvedAnimation.reverseCurve = selectedReverseCurve.curve;
});
}
},
value: selectedReverseCurve,
),
const SizedBox(height: 35.0),
Transform.rotate(
angle: animationRotation.value,
child: const Center(child: FlutterLogo(size: 100)),
),
const SizedBox(height: 35.0),
FractionalTranslation(
translation: animationTranslation.value,
child: const FlutterLogo(size: 100),
),
const SizedBox(height: 25.0),
ElevatedButton(
onPressed: () {
controller.forward();
},
child: const Text('Animate'),
),
],
),
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
}