LoginSignup
1
0

More than 1 year has passed since last update.

【Flutter】CustomPaintを用いてLoadingを描いてみる(応用編)

Last updated at Posted at 2023-04-18

FlutterでLoadingを表すアニメーションWidgetが何個がありますが(例えば、CircularProgressIndicatorとか)、自分なりのアニメーションのカスタマイズしたい場合、CustomPaintを用いて描くことも可能です。

回転円

まずはシンプルな円回転を描いてみましょう。
下記の例では、AnimationControllerの値に応じてアークを連続的に回転させるだけです。

光輪(ハロー)

円の光輪(ハロー)はPaintのmaskFilterの属性で実現できます。

  /// See also:
  ///
  ///  * [Canvas.drawShadow], which is a more efficient way to draw shadows.
  const MaskFilter.blur(
    this._style,
    this._sigma,
  ) : assert(_style != null),
      assert(_sigma != null);

上記の属性でぼやけた影を生成できます。パラメーター_sigmaがぼかしの程度を表します。

paint.maskFilter = MaskFilter.blur(BlurStyle.solid, 4);

その_sigmaをアニメーションの値にすると、光輪の動画生成できます。

  final Animatable<double> breatheTween = TweenSequence<double>(
    <TweenSequenceItem<double>>[
      TweenSequenceItem<double>(
        tween: Tween<double>(begin: 0, end: 4),
        weight: 1,
      ),
      TweenSequenceItem<double>(
        tween: Tween<double>(begin: 4, end: 0),
        weight: 1,
      ),
    ],
  ).chain(CurveTween(curve: Curves.decelerate));
  paint.maskFilter = MaskFilter.blur(BlurStyle.solid, breatheTween.evaluate(animation));

着色

前の章でPathのpaint属性でshader着色を紹介したことあるので、今回をこちらの知識で光輪を着色しようと思います。

    // 光輪
    paint.maskFilter = MaskFilter.blur(BlurStyle.solid, breatheTween.evaluate(animation));
    List<Color> colors = [
      Colors.red,
      Colors.orange,
      Colors.yellow,
      Colors.green,
      Colors.cyan,
      Colors.blue,
      Colors.purple,
    ];

    colors.addAll(colors.toList());

    final List<double> pos = List.generate(colors.length, (index) => index / colors.length);
    // shader
    paint.shader = ui.Gradient.sweep(Offset.zero, colors, pos, TileMode.clamp, 0, 2 * pi);

光輪を回転させる

最後は光輪と回転する円を結合すれば、ぐるぐる回るLoading円ができます。

    canvas.translate(size.width / 2, size.height / 2);
    final Paint paint = Paint()
      ..style = PaintingStyle.stroke
      ..color = Colors.purple
      ..strokeWidth = 1;
    // 光輪
    paint.maskFilter = MaskFilter.blur(BlurStyle.solid, breatheTween.evaluate(animation));
    List<Color> colors = [
      Colors.red,
      Colors.orange,
      Colors.yellow,
      Colors.green,
      Colors.cyan,
      Colors.blue,
      Colors.purple,
    ];

    colors.addAll(colors.toList());

    final List<double> pos = List.generate(colors.length, (index) => index / colors.length);
    // shader
    paint.shader = ui.Gradient.sweep(Offset.zero, colors, pos, TileMode.clamp, 0, 2 * pi);
    Path path = Path();
    path.addOval(Rect.fromCenter(center: Offset.zero, width: 200, height: 200));
    canvas.save();
    canvas.rotate(animation.value * 2 * pi);
    canvas.drawPath(path, paint);
    canvas.restore();
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0