英文:
Flutter CustomPainter MultiColor tween animation
问题
CircleChart类是一个CustomPainter,用于在基于数值的情况下,在不同颜色之间创建动画。如果数值大于400,它将平滑地从蓝色过渡到橙色,如果数值小于400,则从橙色过渡到蓝色。你想要添加一种颜色。如果数值小于400,设为蓝色;如果大于400,则过渡到橙色;如果大于600,则过渡到红色。如果数值开始下降,你希望动画反转,并从红色过渡到橙色,然后到蓝色(如果数值低于400)。你尝试使用TweenSequence,但没有得到预期的结果。以下是在父部件中触发动画的代码:
```dart
if (magnetometerState.v < 400) {
animationController.forward();
} else if (magnetometerState.v > 600) {
animationController.reverse();
}
请问你需要更多的帮助吗?
英文:
how can I create a CustomPainter that animates between multiple colors depending on a value?
The code below only works on one Tween value, create a smooth transition from blue to orange if the value is greater than 400, and back from orange to blue if the value is smaller than 400.
class CircleChart extends CustomPainter {
double value;
final Animation<Color?> color;
CircleChart({required this.value, required Animation<double> animation})
: color = ColorTween(begin: Colors.orange, end: const Color(0xFF00D1FF))
.animate(animation),
super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
final p1 = Offset(50, 50);
final p2 = Offset(250, 150);
final paint = Paint()
..color = color.value!
..strokeWidth = 4;
canvas.drawLine(p1, p2, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
I want to add one more color there. If the value is smaller than 400, set blue, if greater, transition to orange, if greater than 600, transition to red. If the value starts dropping, I want the animation to reverse and animate from red to orange and then to blue (if it drops below 400).
I was trying TweenSequence, but it didn't give me the expected result.
here is the code where i am triggering animation (from parent widget):
if (magnetometerState.v < 400) {
animationController.forward();
} else {
animationController.reverse();
}
Can anyone share their knowledge how to solve this? There are very few articles about custom painter animations
答案1
得分: 2
以下是您要翻译的代码部分:
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
double value = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Spacer(),
AnimatedStick(
value: value / 1000,
),
const Spacer(),
Text('Value: ${value.toInt()}', textAlign: TextAlign.center),
Slider(
min: 0,
max: 1000,
inactiveColor: Colors.black,
value: value,
onChanged: (v) => setState(() {
value = v;
}),
),
const Spacer(),
],
),
);
}
}
class AnimatedStick extends StatefulWidget {
const AnimatedStick({
required this.value,
super.key,
});
final double value;
@override
State<AnimatedStick> createState() => _AnimatedStickState();
}
class _AnimatedStickState extends State<AnimatedStick>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Color?> colorAnimation;
@override
void didUpdateWidget(_) {
super.didUpdateWidget(_);
_controller.animateTo(widget.value);
super.didChangeDependencies();
}
@override
void initState() {
super.initState();
_controller = AnimationController(
value: widget.value,
duration: const Duration(seconds: 1),
vsync: this,
);
colorAnimation = TweenSequence<Color?>(
<TweenSequenceItem<Color?>>[
TweenSequenceItem(
tween: ColorTween(begin: Colors.orange, end: const Color(0xFF00D1FF)),
weight: 4,
),
TweenSequenceItem(
tween: ColorTween(begin: const Color(0xFF00D1FF), end: Colors.black),
weight: 6,
),
],
).animate(_controller);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return CustomPaint(
painter: CircleChart(
color: colorAnimation.value,
),
);
});
}
}
class CircleChart extends CustomPainter {
final Color? color;
CircleChart({required this.color});
@override
void paint(Canvas canvas, Size size) {
const p1 = Offset(50, 50);
const p2 = Offset(250, 150);
final paint = Paint()
..color = color!
..strokeWidth = 4;
canvas.drawLine(p1, p2, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
希望这可以帮助您!如果有任何其他问题,请随时提出。
英文:
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
double value = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Spacer(),
AnimatedStick(
value: value / 1000,
),
const Spacer(),
Text('Value: ${value.toInt()}', textAlign: TextAlign.center),
Slider(
min: 0,
max: 1000,
inactiveColor: Colors.black,
value: value,
onChanged: (v) => setState(() {
value = v;
}),
),
const Spacer(),
],
),
);
}
}
class AnimatedStick extends StatefulWidget {
const AnimatedStick({
required this.value,
super.key,
});
final double value;
@override
State<AnimatedStick> createState() => _AnimatedStickState();
}
class _AnimatedStickState extends State<AnimatedStick>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Color?> colorAnimation;
@override
void didUpdateWidget(_) {
super.didUpdateWidget(_);
_controller.animateTo(widget.value);
super.didChangeDependencies();
}
@override
void initState() {
super.initState();
_controller = AnimationController(
value: widget.value,
duration: const Duration(seconds: 1),
vsync: this,
);
colorAnimation = TweenSequence<Color?>(
<TweenSequenceItem<Color?>>[
TweenSequenceItem(
tween: ColorTween(begin: Colors.orange, end: const Color(0xFF00D1FF)),
weight: 4,
),
TweenSequenceItem(
tween: ColorTween(begin: const Color(0xFF00D1FF), end: Colors.black),
weight: 6,
),
],
).animate(_controller);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return CustomPaint(
painter: CircleChart(
color: colorAnimation.value,
),
);
});
}
}
class CircleChart extends CustomPainter {
final Color? color;
CircleChart({required this.color});
@override
void paint(Canvas canvas, Size size) {
const p1 = Offset(50, 50);
const p2 = Offset(250, 150);
final paint = Paint()
..color = color!
..strokeWidth = 4;
canvas.drawLine(p1, p2, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论