阅读 180

Flutter 的自定义 UI 系列(六)-示例:写轮眼动效

前言

CustomPainter 除了常规的绘制外,还可以配合 AnimationController 实现动态效果。这篇文章将展示一个写轮眼的绘制动画。具体效果看封面,没有太多的技术难点,就是计算点位置和调用对应的 API 做绘制。

步骤一 背景的绘制

绘制背景,比较简单,绘制两个圆就可以了。

技巧:绘制圆形相关的图像时,可以把画布的原点挪到 widget 的中心,这样在计算三角函数、旋转画布等操作更方便。

@override void paint(Canvas canvas, Size size) {   var center = size.center(Offset.zero);   // 挪到画布到 CustomPaint 的中心位置   canvas.translate(center.dx, center.dy);   canvas.save();   canvas.restore(); } 复制代码

Sharingan1.png

步骤二 三勾玉的绘制

计算并找到点的位置,用圆和一个path路径共同绘制了一个勾玉。

void _drawMagatama(Offset center, Canvas canvas) {   var magatamaOrigin = center.translate(90, 0);   canvas.drawCircle(magatamaOrigin, 20, blackPaintFill);   path.moveTo(magatamaOrigin.dx, magatamaOrigin.dy);   path.relativeLineTo(0, -20);   var magatamaEnd = magatamaOrigin.translate(40, 20);   path.conicTo(magatamaOrigin.dx + 20, magatamaOrigin.dy - 20, magatamaEnd.dx, magatamaEnd.dy, 1);   path.moveTo(magatamaOrigin.dx, magatamaOrigin.dy);   path.conicTo(magatamaOrigin.dx + 20, magatamaOrigin.dy - 10, magatamaEnd.dx, magatamaEnd.dy, 1);   path.close();   canvas.drawPath(path, blackPaintFill); } 复制代码

Sharingan2.png

另外两个勾玉可以旋转画布,调用同一个绘制方法。省去了计算点位置的步骤。

canvas.save(); canvas.rotate(pi * 2 / 3); canvas.rotate(_animationDirection); _drawMagatama(Offset.zero, canvas); canvas.restore(); canvas.save(); canvas.rotate(pi * 4 / 3); canvas.rotate(_animationDirection); _drawMagatama(Offset.zero, canvas); canvas.restore(); 复制代码

Sharingan3.png

步骤三 万花筒绘制

万花筒的边缘是个贝塞尔曲线,找到对应的点绘制曲线就可以了

Offset ctrPoint1 = Offset(-30, -100); Offset ctrPoint2 = Offset(90, 150); Path path = Path(); var offsetA = Offset(145, 0); var offsetB = Offset(radius * cos(pi * 2 / 3), radius * sin(pi * 2 / 3)); path.moveTo(offsetA.dx, offsetA.dy); path.cubicTo(ctrPoint1.dx, ctrPoint1.dy, ctrPoint2.dx, ctrPoint2.dy, offsetB.dx, offsetB.dy); canvas.drawPath(path, blackPaint..strokeWidth=1); 复制代码

Sharingan4.png


绘制另外两条曲线时,用到了三角函数,这也是 canvas 绘制中最常用的函数,用来计算指定角度点的位置的方法。

var offsetB = Offset(radius * cos(pi * 2 / 3), radius * sin(pi * 2 / 3)); var offsetC = Offset(radius * cos(pi * 4 / 3), radius * sin(pi * 4 / 3)); 复制代码

Sharingan5.png

步骤四 加动效

创建 AnimationController ,并添加 CurvedAnimation 差值器,使动画效果更加逼真。关于差值器效果可以参考官方的示例 Curves

    _controllerMagatama = AnimationController(vsync: this, duration: Duration(seconds: 6));     _curvedAnimationMagatama = CurvedAnimation(parent: _controllerMagatama, curve: Curves.elasticIn);     _curvedAnimationMagatama.addListener(() {       _valueMagatama = _curvedAnimationMagatama.value * 3;       setState(() {});     });     _controllerMagatama.forward(); 复制代码

CurvedAnimation 的值传给 CustomPainter 再根据动画的值旋转画布对应的角度即可。最后就实现了封面的效果。


作者:码农王真实
链接:https://juejin.cn/post/7025518289887428621


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐