绘制集录-手势弹簧

This commit is contained in:
toly
2021-05-08 10:24:58 +08:00
parent 709fe248a7
commit 39d4475606
3 changed files with 149 additions and 4 deletions

View File

@@ -0,0 +1,134 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class SpringWidget extends StatefulWidget {
const SpringWidget();
@override
_SpringWidgetState createState() => _SpringWidgetState();
}
const double _kDefaultSpringHeight = 100; //弹簧默认高度
const double _kRateOfMove = 1.5; //移动距离与形变量比值
const double _kK = 3;
class _SpringWidgetState extends State<SpringWidget> with SingleTickerProviderStateMixin {
ValueNotifier<double> height = ValueNotifier(_kDefaultSpringHeight);
AnimationController _ctrl;
double s = 0; // 移动距离
double laseMoveLen = 0;
Animation<double> animation;
final Duration animDuration = const Duration(milliseconds: 500);
@override
void initState() {
super.initState();
_ctrl = AnimationController(vsync: this, duration: animDuration)
..addListener(_updateHeightByAnim);
// animation = CurvedAnimation(parent: _ctrl, curve: Curves.bounceOut);
animation = CurvedAnimation(parent: _ctrl, curve: const Interpolator());
}
void _updateHeightByAnim() {
s = laseMoveLen * (1 - animation.value);
height.value = _kDefaultSpringHeight + (-s / _kRateOfMove);
}
@override
void dispose() {
_ctrl.dispose();
height.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onVerticalDragUpdate: _updateSpace,
onVerticalDragEnd: _animateToDefault,
child: Container(
width: 200,
height: 200,
color: Colors.grey.withAlpha(11),
child: CustomPaint(
painter: SpringPainter(height: height)),
),
);
}
double f = 0;
void _updateSpace(DragUpdateDetails details) {
s += details.delta.dy;
height.value = _kDefaultSpringHeight + dx;
}
double get dx => -s / _kRateOfMove;
double get k => _kK;
void _animateToDefault(DragEndDetails details) {
// f = k * dx;
// print('----[弹性系数:$_kK]---[移动了:$dx]----[可提供弹力:$f]------------');
laseMoveLen = s;
_ctrl.forward(from: 0);
}
}
class Interpolator extends Curve {
const Interpolator();
@override
double transformInternal(double t) {
t -= 1.0;
return t * t * t * t * t + 1.0;
}
}
const double _kSpringWidth = 30;
class SpringPainter extends CustomPainter {
final int count;
final ValueListenable<double> height;
SpringPainter({this.count = 20, this.height}):super(repaint: height);
Paint _paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1;
@override
void paint(Canvas canvas, Size size) {
canvas.translate(size.width / 2+_kSpringWidth / 2, size.height);
Path springPath = Path();
springPath.relativeLineTo(-_kSpringWidth, 0);
double space = height.value/(count+1);
for (int i = 1; i < count; i++) {
if (i % 2 == 1) {
springPath.relativeLineTo(_kSpringWidth, -space);
} else {
springPath.relativeLineTo(-_kSpringWidth, -space);
}
}
if(count.isOdd){
springPath.relativeLineTo(_kSpringWidth, 0);
}else{
springPath.relativeLineTo(-_kSpringWidth, 0);
}
canvas.drawPath(springPath, _paint);
}
@override
bool shouldRepaint(covariant SpringPainter oldDelegate) =>
oldDelegate.count != count || oldDelegate.height != height;
}

View File

@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_unit/painter_system/anim/spring_widget.dart';
import 'anim/bezier3_player/bezier3_palyer.dart';
import 'anim/draw_path.dart';
import 'art/circle_packing.dart';
import 'art/cubic_disarray.dart';
import 'art/hypnotic_squares.dart';
@@ -9,10 +11,9 @@ import 'art/piet_mondrian.dart';
import 'art/tiled_lines.dart';
import 'art/triangular_mesh.dart';
import 'art/un_deux_trois.dart';
import 'anim/draw_path.dart';
import 'base/clock_widget.dart';
import 'base/draw_path_fun.dart';
import 'base/draw_grid_axis.dart';
import 'base/draw_path_fun.dart';
import 'base/draw_picture.dart';
import 'fun/random_portrait.dart';
import 'fun/stemp/stamp_paper.dart';
@@ -63,11 +64,22 @@ class GalleryFactory {
];
case GalleryType.anim:
return [
FrameShower(
title: "手势弹簧",
author: "张风捷特烈",
info: " 本样例介绍如何绘制弹簧,通过触点竖直拖拽拉伸、压缩,放手时进行恢复动画,是一个很好的综合小案例。",
content: const SpringWidget()),
FrameShower(
title: "Draw Curve",
author: "张风捷特烈",
info: " 本样例介绍如何使用路径绘制函数曲线,并使用路径测量进行动画",
content: DrawPath()),
FrameShower(
title: "Bezier3 演示 (双击清除)",
author: "张风捷特烈",
info: " 本样例介绍如何绘制三次贝塞尔曲线,通过触点判断某点是否激活,据此控制点的位置达到拖动控制效果。",
content: Bezier3Player()), FrameShower(
content: Bezier3Player()),
FrameShower(
title: "Draw Curve",
author: "张风捷特烈",
info: " 本样例介绍如何使用路径绘制函数曲线,并使用路径测量进行动画",

View File

@@ -28,7 +28,6 @@ class _UnitNavigationState extends State<UnitNavigation> {
// 禁止 PageView 滑动
final ScrollPhysics neverScroll = const NeverScrollableScrollPhysics();
@override
void dispose() {
_controller.dispose(); //释放控制器