Skip to content

Commit e74e18c

Browse files
committed
绘制集录-动画数值散点图
1 parent c06a2ff commit e74e18c

File tree

5 files changed

+206
-3
lines changed

5 files changed

+206
-3
lines changed
+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import 'dart:ui';
2+
3+
import 'package:flutter/material.dart';
4+
5+
import 'point_data.dart';
6+
7+
class AnimPainter extends CustomPainter {
8+
final PointData points;
9+
10+
Paint axisPaint = Paint()
11+
..style = PaintingStyle.stroke
12+
..strokeWidth = 1;
13+
14+
Paint fpsPaint = Paint()
15+
..style = PaintingStyle.stroke
16+
..color = Colors.green;
17+
18+
TextPainter textPainter = TextPainter(
19+
textAlign: TextAlign.center, textDirection: TextDirection.ltr);
20+
21+
AnimPainter(this.points) : super(repaint: points);
22+
23+
@override
24+
void paint(Canvas canvas, Size size) {
25+
canvas.translate(0, size.height);
26+
27+
_drawAxis(canvas,size);
28+
_drawScale(canvas, size);
29+
_drawPoint(points.values, canvas, size);
30+
31+
Path fps_60 = Path();
32+
fps_60.moveTo(3.0 * 60, 0);
33+
fps_60.relativeLineTo(0, -size.height);
34+
canvas.drawPath(fps_60, fpsPaint);
35+
textPainter.text = TextSpan(
36+
text: '60 帧', style: TextStyle(fontSize: 12, color: Colors.green));
37+
textPainter.layout(); // 进行布局
38+
textPainter.paint(canvas, Offset(3.0 * 61 + 5, -size.height));
39+
}
40+
41+
@override
42+
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
43+
44+
void _drawAxis(Canvas canvas, Size size){
45+
Path axisPath = Path();
46+
axisPath.relativeLineTo(size.width, 0);
47+
axisPath.relativeLineTo(-10, -4);
48+
axisPath.moveTo(size.width, 0);
49+
axisPath.relativeLineTo(-10, 4);
50+
axisPath.moveTo(0, 0);
51+
axisPath.relativeLineTo(0, -size.height);
52+
axisPath.relativeLineTo(-4, 10);
53+
axisPath.moveTo(0, -size.height);
54+
axisPath.relativeLineTo(4, 10);
55+
canvas.drawPath(axisPath, axisPaint);
56+
57+
textPainter.text = TextSpan(
58+
text: '帧数/f', style: TextStyle(fontSize: 12, color: Colors.black));
59+
textPainter.layout(); // 进行布局
60+
Size textSize = textPainter.size; // 尺寸必须在布局后获取
61+
textPainter.paint(canvas, Offset(size.width - textSize.width, 5));
62+
textPainter.text = TextSpan(
63+
text: '数值/y', style: TextStyle(fontSize: 12, color: Colors.black));
64+
textPainter.layout(); // 进行布局
65+
Size textSize2 = textPainter.size; // 尺寸必须在布局后获取
66+
textPainter.paint(canvas,
67+
Offset(-textSize2.width + textSize2.width/2, -size.height - textSize2.height-3));
68+
}
69+
70+
void _drawScale(Canvas canvas, Size size) {
71+
72+
double step = size.height / 11;
73+
74+
if(points.values.length>0){
75+
canvas.drawLine(Offset(0, -points.values.last*step*10), Offset(280, -points.values.last*step*10), Paint()..color=Colors.purple);
76+
canvas.drawCircle(Offset(240, -points.values.last*step*10), 10, Paint()..color=Colors.orange);
77+
}
78+
79+
Path scalePath = Path();
80+
for (int i = 1; i <= 10; i++) {
81+
scalePath
82+
..moveTo(0, -step * i)
83+
..relativeLineTo(5, 0);
84+
85+
textPainter.text = TextSpan(
86+
text: '${i / 10}',
87+
style: TextStyle(fontSize: 12, color: Colors.black));
88+
89+
textPainter.layout(); // 进行布局
90+
Size textSize = textPainter.size; // 尺寸必须在布局后获取
91+
textPainter.paint(
92+
canvas, Offset(-textSize.width - 5, -step * i - textSize.height / 2));
93+
}
94+
canvas.drawPath(scalePath, axisPaint);
95+
}
96+
97+
void _drawPoint(List<double> values, Canvas canvas, Size size) {
98+
double stepY = size.height / 11;
99+
100+
List<Offset> drawPoint = [];
101+
// print(values.length);
102+
103+
for (int i = 0; i < values.length; i++) {
104+
drawPoint.add(Offset(3.0 * (i + 1), -values[i] * (size.height - stepY)));
105+
}
106+
107+
canvas.drawPoints(
108+
PointMode.points,
109+
drawPoint,
110+
Paint()
111+
..style = PaintingStyle.stroke..color=Colors.blue
112+
..strokeWidth = 2);
113+
}
114+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import 'dart:ui';
2+
3+
import 'package:flutter/material.dart';
4+
5+
import 'anim_painter.dart';
6+
import 'point_data.dart';
7+
8+
class CurveAnimShower extends StatefulWidget {
9+
const CurveAnimShower();
10+
11+
@override
12+
_CurveAnimShowerState createState() => _CurveAnimShowerState();
13+
}
14+
15+
class _CurveAnimShowerState extends State<CurveAnimShower>
16+
with SingleTickerProviderStateMixin {
17+
PointData points = PointData();
18+
19+
AnimationController _ctrl;
20+
21+
final Duration animDuration = const Duration(milliseconds: 1000);
22+
23+
Animation<double> curveAnim;
24+
25+
@override
26+
void initState() {
27+
super.initState();
28+
_ctrl = AnimationController(
29+
vsync: this,
30+
duration: animDuration,
31+
)..addListener(_collectPoint);
32+
curveAnim = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
33+
}
34+
35+
@override
36+
void dispose() {
37+
_ctrl.dispose();
38+
points.dispose();
39+
super.dispose();
40+
}
41+
42+
void _collectPoint() {
43+
points.push(curveAnim.value);
44+
}
45+
46+
void _startAnim() async {
47+
points.clear();
48+
await _ctrl.forward(from: 0);
49+
}
50+
51+
@override
52+
Widget build(BuildContext context) {
53+
return GestureDetector(
54+
onTap: _startAnim,
55+
child: Padding(
56+
padding: const EdgeInsets.all(30.0),
57+
child: CustomPaint(
58+
painter: AnimPainter(points),
59+
size: const Size(
60+
200,
61+
200,
62+
),
63+
),
64+
),
65+
);
66+
}
67+
}

Diff for: lib/painter_system/anim/curve_shower/point_data.dart

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:flutter/cupertino.dart';
2+
3+
class PointData extends ChangeNotifier {
4+
final List<double> values = [];
5+
6+
void push(double value) {
7+
values.add(value);
8+
notifyListeners();
9+
}
10+
11+
12+
void clear() {
13+
values.clear();
14+
notifyListeners();
15+
}
16+
}

Diff for: lib/painter_system/gallery_factory.dart

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_unit/painter_system/anim/spring_widget.dart';
33

44
import 'anim/bezier3_player/bezier3_palyer.dart';
5+
import 'anim/curve_shower/curve_anim_shower.dart';
56
import 'anim/draw_path.dart';
67
import 'art/circle_packing.dart';
78
import 'art/cubic_disarray.dart';
@@ -69,6 +70,11 @@ class GalleryFactory {
6970
author: "张风捷特烈",
7071
info: " 本样例介绍如何绘制弹簧,通过触点竖直拖拽拉伸、压缩,放手时进行恢复动画,是一个很好的综合小案例。",
7172
content: const SpringWidget()),
73+
FrameShower(
74+
title: "动画曲线散点图",
75+
author: "张风捷特烈",
76+
info: " 本样例通过直观的方式,来查看动画曲线 curve 的作用效果,让大家对动画有更深的理解。",
77+
content: const CurveAnimShower()),
7278
FrameShower(
7379
title: "Draw Curve",
7480
author: "张风捷特烈",

Diff for: pubspec.lock

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ packages:
1414
name: async
1515
url: "https://pub.flutter-io.cn"
1616
source: hosted
17-
version: "2.5.0"
17+
version: "2.6.1"
1818
bloc:
1919
dependency: transitive
2020
description:
@@ -363,7 +363,7 @@ packages:
363363
name: source_span
364364
url: "https://pub.flutter-io.cn"
365365
source: hosted
366-
version: "1.8.0"
366+
version: "1.8.1"
367367
sqflite:
368368
dependency: "direct main"
369369
description:
@@ -419,7 +419,7 @@ packages:
419419
name: test_api
420420
url: "https://pub.flutter-io.cn"
421421
source: hosted
422-
version: "0.2.19"
422+
version: "0.3.0"
423423
toggle_rotate:
424424
dependency: "direct main"
425425
description:

0 commit comments

Comments
 (0)