Flutter自定义绘制器多颜色渐变动画

huangapple go评论62阅读模式
英文:

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&lt;Color?&gt; color;

  CircleChart({required this.value, required Animation&lt;double&gt; 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 &lt; 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;
  }
}

希望这可以帮助您!如果有任何其他问题,请随时提出。

英文:

Flutter自定义绘制器多颜色渐变动画

import &#39;package:flutter/material.dart&#39;;
void main() {
runApp(
const MaterialApp(
home: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State&lt;MyApp&gt; createState() =&gt; _MyAppState();
}
class _MyAppState extends State&lt;MyApp&gt; {
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(&#39;Value: ${value.toInt()}&#39;, textAlign: TextAlign.center),
Slider(
min: 0,
max: 1000,
inactiveColor: Colors.black,
value: value,
onChanged: (v) =&gt; setState(() {
value = v;
}),
),
const Spacer(),
],
),
);
}
}
class AnimatedStick extends StatefulWidget {
const AnimatedStick({
required this.value,
super.key,
});
final double value;
@override
State&lt;AnimatedStick&gt; createState() =&gt; _AnimatedStickState();
}
class _AnimatedStickState extends State&lt;AnimatedStick&gt;
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation&lt;Color?&gt; 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&lt;Color?&gt;(
&lt;TweenSequenceItem&lt;Color?&gt;&gt;[
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;
}
}

huangapple
  • 本文由 发表于 2023年4月17日 16:18:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76033042.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定