引き続き、いろんな模様を描いて遊んでいます。
今回は円の線を曲げるアニメーションです。 個人的に、図形描画の練習によく作るものなのですが、今回Flutterでもやってみました。
ソースは以下のとおりです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math.dart' hide Colors;
class FuyoFuyoWidget extends StatefulWidget {
@override
_FuyoFuyoWidgetState createState() => _FuyoFuyoWidgetState();
}
class _FuyoFuyoWidgetState extends State<FuyoFuyoWidget>
with SingleTickerProviderStateMixin {
double _amplitude = 15;
Animation<double> _animation;
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(milliseconds: 2000),
vsync: this,
);
_controller.addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed) {
_controller.reverse();
}
if (status == AnimationStatus.dismissed) {
_controller.forward();
}
});
_controller.forward();
}
@override
Widget build(BuildContext context) {
_animation = Tween<double>(begin: 15.0, end: -15.0).animate(_controller)
..addListener(() {
setState(() {
_amplitude = _animation.value;
});
});
return Container(
child: Center(
child: CustomPaint(
painter: _MyPainter(
amplitude: _amplitude,
),
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class _MyPainter extends CustomPainter {
_MyPainter({this.amplitude});
final double amplitude;
@override
bool shouldRepaint(_MyPainter oldDelegate) {
return oldDelegate.amplitude != amplitude;
}
@override
void paint(Canvas canvas, Size size) {
const double radius = 100;
const double frequency = 10;
final Paint stroke = Paint()
..color = Colors.black
..style = PaintingStyle.stroke
..strokeWidth = 1;
Offset lastPoint;
for (int i = 0; i <= 360; i += 1) {
final double angle = radians(i.toDouble());
final double noise = sin(angle * frequency) * amplitude;
final double x = (radius + noise) * cos(angle);
final double y = (radius + noise) * sin(angle);
final Offset point = Offset(x, y);
if (lastPoint != null) {
canvas.drawLine(lastPoint, point, stroke);
}
lastPoint = point;
}
}
}
ふよふよした円の描き方は以下の記事が参考になりました。(Processingの記事)
https://bencrowder.net/blog/2013/sine-circle-test-animation/
Flutterのアニメーションは以下の記事が参考になりました。
https://medium.com/flutter-community/flutter-custom-painter-circular-wave-animation-bdc65c112690
GitHubのリポジトリはこちらです。 https://github.com/tnantoka/moyo
今回のもFlutter for Webで問題なく動きました。