旋转小人
几年前在某一个地方看到过这个效果:
今天又偶然看到,最神奇的地方在于:
- 在盯着gif看的某一瞬间,旋转方向突然就逆向旋转了
- 在旋转方向发送变化的同时,左腿变右腿,左手变右手
所以我在想,是不是看的时间久了,就可以任我切换旋转方向,于是盯了半个小时,结果是没成功,收获是方向切换的频次提高了。
我知道它肯定是向着一个方向旋转的,但到现在我依然不能理解为什么会是这样,困惑中。
那,是否能用canvas实现一个呢?
带来的困惑
苦苦思索:
- 这个人影是立体的,前面《太空人》 曾用到立体投影,这里估计要处理。
- 我该怎么画这个人儿呢? 用长方体拼凑怕是不合适吧。。。
- 这人儿的手臂还是伸开的。
- 在旋转的同时,看脚丫子,好像高低起伏。
第一版效果
- 先画左右腿
- 上下起伏
差距,有点远。。。
代码如下:
import 'dart:ui';
import 'dart:math';
import 'package:flutter/material.dart';
// 旋转小人儿
class RotateGirlMainPage extends StatefulWidget {
@override
_RotateGirlMainPageState createState() => _RotateGirlMainPageState();
}
class _RotateGirlMainPageState extends State<RotateGirlMainPage>
with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 1500));
_controller.repeat();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("旋转小人儿"),
centerTitle: true,
),
body: CustomPaint(
size: MediaQuery.of(context).size,
painter: _MyPainter(_controller),
),
);
}
}
class _MyPainter extends CustomPainter {
AnimationController _controller;
_MyPainter(this._controller) : super(repaint: _controller);
@override
void paint(Canvas canvas, Size size) {
translateToCenter(canvas, size);
double dy = 10 * sin(pi * 2 * _controller.value);
Path path = new Path()
..moveTo(30 * sin(pi * 2 * _controller.value), dy)
..lineTo(100 * sin(pi * 2 * _controller.value), 220 + dy)
..moveTo(0, dy)
..lineTo(0, 200 + dy)
..lineTo(300, 200 + dy)
..lineTo(-300, 200 + dy);
Paint paint = new Paint()
..color = Colors.black
..style = PaintingStyle.stroke
..strokeWidth = 2
..isAntiAlias = true;
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
void translateToCenter(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
}
}
复制代码
第二版效果
又仔细观察好像是斜对角的线,即
- 线的上端点,移动方向,左->右
- 线的下端点,移动方向,右->左
- 围绕着y轴旋转,y的坐标上下有波动,x的值通过radiussin(pi2*_controller.value)获取。(_controller是设定的一个动画,value取值范围在0-1,radius是旋转半径)
再看下效果:
是不是有那个味儿了。。。
最后,代码如下:
import 'dart:ui';
import 'dart:math';
import 'package:flutter/material.dart';
// 旋转小人儿
class RotateGirlMainPage extends StatefulWidget {
@override
_RotateGirlMainPageState createState() => _RotateGirlMainPageState();
}
class _RotateGirlMainPageState extends State<RotateGirlMainPage>
with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 1500));
_controller.repeat();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("旋转小人儿"),
centerTitle: true,
),
body: CustomPaint(
size: MediaQuery.of(context).size,
painter: _MyPainter(_controller),
),
);
}
}
class _MyPainter extends CustomPainter {
AnimationController _controller;
_MyPainter(this._controller) : super(repaint: _controller);
@override
void paint(Canvas canvas, Size size) {
translateToCenter(canvas, size);
double dy = 10 * sin(pi * 2 * _controller.value);
Path path = new Path()
..moveTo(30 * -sin(pi * 2 * _controller.value), -100+dy)
..lineTo(100 * sin(pi * 2 * _controller.value), 220 + dy);
Paint paint = new Paint()
..color = Colors.black
..style = PaintingStyle.stroke
..strokeWidth = 2
..isAntiAlias = true;
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
void translateToCenter(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
Paint paint = new Paint()
..color = Colors.black12
..style = PaintingStyle.stroke
..strokeWidth = 1
..isAntiAlias = true;
canvas.drawLine(Offset(-300,0), Offset(300,0), paint);
canvas.drawLine(Offset(0,300), Offset(0,-300), paint);
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END