彩虹系列
通过动画控制绘制的结束点,就可以让贝塞尔曲线动起来。例如下面的动图展示的效果,看起来像搭了一个滑滑梯一样。实际上就是用7条贝塞尔曲线实现的,我们使用了 animation
对象的值来控制绘制的结束点,从而实现了对应的动画效果。
具体源码如下,其中控制绘制结束点就是在动画过程中修改循环的次数,即t <= (100 * animationvalue).toint();
这句代码,其中 animationvalue 是动画控制器当前值,范围时从0-1。
class animationbezierpainter extends custompainter { animationbezierpainter({required this.animationvalue}); final double animationvalue; @override void paint(canvas canvas, size size) { final linewidth = 6.0; paint.strokewidth = linewidth; paint.style = paintingstyle.stroke; final colors = [ color(0xffe05100), color(0xfff0a060), color(0xffe0e000), color(0xff10f020), color(0xff2080f5), color(0xff104ff0), color(0xffa040e5), ]; final linenumber = 7; for (var i = 0; i < linenumber; ++i) { paint.color = colors[i % colors.length]; _drawanimatedlines(canvas, paint, size, size.height / 4 + i * linewidth); } } @override bool shouldrepaint(covariant custompainter olddelegate) { return true; } _drawrainbowlines(canvas canvas, paint paint, size size, ypos) { var ygap = 60.0; var p0 = offset(0, ypos - ygap / 2); var p1 = offset(size.width * 2 / 3, ypos - ygap); var p2 = offset(size.width / 3, ypos + ygap); var p3 = offset(size.width, ypos + ygap * 1.5); var path = path(); path.moveto(p0.dx, p0.dy); for (var t = 1; t <= (100 * animationvalue).toint(); t += 1) { var curvepoint = bezierutil.get3orderbezierpoint(p0, p1, p2, p3, t / 100.0); path.lineto(curvepoint.dx, curvepoint.dy); } canvas.drawpath(path, paint); } }
我们修改曲线的控制点还可以实现下面的效果,大家有兴趣可以自己尝试一下。
用多个贝塞尔曲线首尾相接,在垂直方向叠起来就能画出一条弹簧了,然后我们更改弹簧的间距和高度(曲线的数量)就能做出弹簧压下去和弹起来的动画效果了。
这部分的代码如下所示:
@override void paint(canvas canvas, size size) { var paint = paint()..color = colors.black54; final linewidth = 2.0; paint.strokewidth = linewidth; paint.style = paintingstyle.stroke; final linenumber = 20; // 弹簧效果 final ygap = 2.0 + 16.0 * animationvalue; for (var i = 0; i < (linenumber * animationvalue).toint(); ++i) { _drawspirallines( canvas, paint, size, size.width / 2, size.height - i * ygap, ygap); } } _drawspirallines(canvas canvas, paint paint, size size, double xpos, double ypos, double ygap) { final xwidth = 160.0; var p0 = offset(xpos, ypos); var p1 = offset(xpos + xwidth / 2 + xwidth / 4, ypos - ygap); var p2 = offset(xpos + xwidth / 2 - xwidth / 4, ypos - 3 * ygap); var p3 = offset(xpos, ypos - ygap); var path = path(); path.moveto(p0.dx, p0.dy); for (var t = 1; t <= 100; t += 1) { var curvepoint = bezierutil.get3orderbezierpoint(p0, p1, p2, p3, t / 100.0); path.lineto(curvepoint.dx, curvepoint.dy); } canvas.drawpath(path, paint); }
通过多条贝塞尔图形组成的曲线往往会有立体的效果,而立体的效果动起来的时候就会感觉是3d 动画一样,实际上通过贝塞尔曲线是能够绘制出一些3d 效果的动画的,比如下面这个效果,就感觉像在三维空间飞行一样(如果配上背景图移动会更逼真)。这里实际使用了4组贝塞尔曲线来实现,当然实际还可以画一些有趣的图形,比如说画一条鱼。这个源码比较长,就不贴了,有兴趣的可以自行去下载源码(注:本篇之后的 flutter版本升级到了2.10.3):绘图相关源码。
可以看到,通过动画控制贝赛尔曲线动起来的效果还是挺有趣的。而且,我们还可以根据之前动画相关的篇章做一些更有趣的效果出来。这种玩法可以用在一些特殊的加载动画或是做一些比较酷炫的特效上面,增添 app 的趣味性。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。