我正在参与「构思开发 投稿大赛」详情请看:构思开发大赛来了!

本篇将给你带来愈加炫酷动画作用,最终教你怎么经过纯代码完成一只立体的 Flutter 的吉祥物 Dash 和 3D 的 logo 动画

❤️ 本文正在参与征文投稿活动,还请看官们走过路过来个点赞一键三连,感激不尽~

在之前的 《炫酷的 3D 卡片和帅气的 360 展示作用》 里,咱们运用手势代码和视点切换,在 2D 画板里完成了“伪” 3D 的视觉作用,就在我觉得作用还不错时, 有一位掘友提出了一个要害性的问题:卡片短少厚度,也便是没有 3D 的质感

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

的确,如下图所示,在之前的完成里,跟着卡片视点的歪斜,有两个问题特别显着:

  • 当卡片旋转到侧边时,卡片的短少“厚度”的质感,乃至呈现了消失的状况
  • 卡片上的文字尽管做了相似凹凸的视觉作用,可是从旁边面看时也是短少立体质感

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

而为了在 2D 平面完成三唯的质感,在查阅相关材料时我发现了前端的 Zdog 结构,Zdog 是一个运用 Canvas 完成的伪 3D 引擎, 它支持经过 2D 的 Canvas API渲染出相似 3D 的作用

Zdog 作为一个 js 结构,它大约只要 2800 多行代码,而且其最小体积为 28KB ,能够说非常轻量级。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

尽管 Zdog 是一个纯 js 结构, 但已然它是经过 Canvas 完成的逻辑,那就完全能够 “轻松” 迁移到 Flutter ,毕竟 Flutter 自身便是一个重度依赖于 Canvas 的结构,而恰巧在 Flutter 社区就有针对 Zdog 的移植版本: zflutter 。

尽管这个 package 作者现已两年不保护,也没有发布 null-safety 的 pub 支持,可是已然是开源项目,自己动手风衣足食,在经过一番“简略”的迁移适配之后, zflutter 再次在 Flutter 3.0 下“勃发新春” 。

咱们先看作用,在结合 zflutter 的完成之后,能够看到卡片的立体作用得到了全面的提高:

  • 首要卡片有了厚度的质感,旋转到侧边也不会“消失”
  • 卡片上的字体在歪斜时也有了立体的作用

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

那在解说完成之前,咱们要解决一个疑问: zflutter 究竟是怎么在 2D 画板上完成 3D 的质感 ?而其实这个问题的要害就在于:经过手势发生的矩阵改换是作用于画板仍是作用于途径

咱们首要看一个比如,如下代码所示,咱们创建了一个 CustomPaint ,然后在代码里制作了 4 条相同赤色直线,接着对其间 3 条直线的 Canvas 进行不同程度的矩阵旋转,如下图 2 能够看到有两条红线消失不见了:

  • 当红线绕 Y 轴旋转 pi / 2(90)时,由于此刻画板恰好和咱们呈笔直状况,所以会呈现看不到的状况
  • 当红线绕 XY 轴旋转 pi / 4 时,能够看到画板此刻和咱们视觉成 45 的状况
  • 当红线绕 XY 轴旋转 pi / 2(90) 时,由于此刻画板仍是和咱们呈笔直状况,所以呈现看不到的状况
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

假如觉得上面的描述太抽象,那么结合下面动图,能够看到当红线在环绕 XY 轴做旋转时,假如画布(Canavas)和咱们呈 90 笔直的时分,此刻就会呈现消失不见的状况,由于画布是 2D 的平面,这也是为什么之前完成的卡片没有“厚度”的原因

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

那假如不对 Canavs ,而是对制作途径 Path 进行矩阵改换呢 ?不对画布进行旋转,不就不会呈现消失的状况了吗?

如下代码所示,同样是环绕 XY 轴进行旋转,可是此刻是直接对 Path 进行 path.transform 操作,也便是此刻画布Canvas 不会呈现视点改换,呈现改变的是制作的 Path 途径,能够看到:

  • 当红线绕 Y 轴旋转 pi / 2(90)时,此刻红线成了红点,由于它此刻它是“头正对着咱们”
  • 当红线绕 XY 轴旋转 pi / 4 时,能够看到此刻红线整体成 45 的状况对着咱们
  • 当红线绕 XY 轴旋转 pi / 2(90) 时,能够看到此刻红线是“笔直正对着咱们”
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

结合下面的动图,能够看到对 Path 进行矩阵改换的旋转之后,整体的立体感就不相同了,也便是一开始是调整咱们和画布之间的视点,可是现在咱们是改变了“笔”在画布上的制作方式来发生的视差,这也是 zflutter 里完成 3D 立体感的要害:对 Path 做矩阵运算而不只是对 Canvas

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

题外话,借着这个机会顺带普及个小知识点:在前面的代码里能够看到会对矩阵进行 leftTranslatetranslate 的操作 ,这是由于咱们需求在不同方位制作多条红线,所以它们的方位并非都在起点,而运用 leftTranslatetranslate 来对矩阵进行平移,才能达到每次旋转时都是以红线的“中心”去旋转,举个比如:

  • 如图 1 所示是红线没有绕 Z 轴旋转的状况
  • 如图 2 所示是红线在绕 Z 轴旋转 pi / 2 时没有进行矩阵平移的状况,能够看到此刻它们的中心点还在开始方位
  • 如图 3 所示是红线在绕 Z 轴旋转 pi / 2 时,进行了 leftTranslatetranslate 操作的状况
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

完好代码可见: github.com/CarGuo/gsy_…

Web 体会地址,PC 端记住开 Chrome 手机形式:guoshuyu.cn/home/web/#%… 。

那么回到 zflutter 里,在 zflutter 里便是经过组合各类图形和线条,然后使用对 Path 进行矩阵改换,从而完成相似 3D 立体的视觉作用 ,例如下面图 2 的立体正方形,就符合咱们对增加厚度的需求。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

这儿先简略介绍下 zflutter 里常用目标的作用:

  • ZIllustration 相似于画板的作用,能够装备 zoom 特点来调整画板的缩放
  • ZPositioned 用于装备方位和巨细信息,例如 scaletranslaterotate 等特点(其实它便是在内部将接收到的矩阵参数装备到 ParentData ,然后传递给 child)
  • ZDragDetector 用于处理手势相关信息,主要是装备 ZPositionedrotate 就能够快速完成上面的 360 拖拽作用
  • ZGroup 用于组合多个图形的层叠
  • ZToBoxAdapter 用于嵌套一般的 Flutter 控件
  • ZRectZRoundedRectZCircleZEllipseZPolygonZConeZCylinderZHemisphere 等是内置的形状,如下图
  • ZShape 相似于 Canvas ,用于合作 ZMoveZLineZBezierZArc 等制作自定义形状

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

所以要完成卡片的 “真” 3D 作用,简略来说咱们需求做的是:

  • 增加一个 ZIllustration 画布
  • 增加一个 ZDragDetector 合作 ZPositioned 用于处理手势旋转
  • 增加一个 ZGroup ,然后在里面经过 ZToBoxAdapter 增加银行卡的前后两张 png 图片
  • 在两张图片之间增加一个 ZRoundedRect 做边框,装备颜色为 Color(0x8A000000); 完成厚度作用
  • 使用 ZShape 制作数字,这样制作呈现的数字就会有立体的感觉
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

如上图所示,能够看到经过 zflutter 的处理之后,不只是卡片自身有了“厚度”的质感,在歪斜也能够看到文字立体视觉,现在就算是如图 3 相同旋转到 90 的状况,仍然能够看到卡片和文字之间的层次联系

完好代码可见: github.com/CarGuo/gsy_…

Web 体会地址,PC 端记住开 Chrome 手机形式: guoshuyu.cn/home/web/#%… 。

详细源码能够直接看上方链接,那认识了 zflutter 之后,咱们还能使用 zflutter做什么呢 ?其实在官方的 Demo 里就有一个很有典型的示例,那便是 Flutter 的吉祥物 Dash ,接下来咱们看怎么使用 zflutter 开始完成一只立体质感的 Dash

首要咱们使用 ZCircle 画一个圆,用于完成 Dash 的身体

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

然后咱们经过 3 个不同方位和视点的 ZEllipse 椭圆来组成 Dash 的头发,事实上 zflutter 里很多作用便是经过相似这样的图形组合来完成的。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

接着咱们在 ZShape 里使用 ZArc 完成不同视点的弧形组合完成尾巴,这儿的要害是 z 轴上需求有部分落差,如下图展示是尾巴在 3 个不同视点的可视作用。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

再经过调整两个 ZEllipse 椭圆的视点来完成 Dash 的手部作用,在这一点上 zflutter 的确很考验开发者关于图形在平面上的空间感。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

接着经过 ZCone 就能够快速完成 Dash 的嘴巴。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

然后这部分信任不用代码大家也知道,便是经过组合多个 ZEllipseZCircle 堆叠来完成 Dash 的眼睛。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

最终,把上面的零部件组合到一起,在装备上循环的动画参数,当当当~一只生动立体的 Dash 就完成了。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

完好代码可见: github.com/CarGuo/gsy_…

Web 体会地址,PC 端记住开 Chrome 手机形式: guoshuyu.cn/home/web/#3… 。

比照实物 Dash ,能够看到使用 zflutter 完成的 Dash ,乍看之下形似度仍是蛮高的,同时 zflutter 自身也只要 82k 左右的巨细,作为一个超轻量级的伪 3D 动画结构,它在接入本钱很低的状况下,尽或许做到了咱们对 3D 空间所需的视觉作用,这儿面的要害仍是在于:矩阵改换是作用于画板仍是作用于途径

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

那在知道原理之后,咱们接下来就能够经过三个简略的 ZShape 组合,使用 ZMoveZLine 就能组合出具有 3D 质感的 Logo ,里面的参数直接从 SVG 的 path 映射过来就能够了

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

由于咱们的矩阵旋转改变的是 Path 而不是 Canvas ,所以 Logo 的立体作用能够经过 skroke 的粗细合作画布 zoom 扩大来表现。

完好代码可见: github.com/CarGuo/gsy_…

Web 体会地址,PC 端记住开 Chrome 手机形式: guoshuyu.cn/home/web/#%… 。

那或许就有人要说了,这个 logo 立体感仍是不行强,由于它仍是太扁平了 ~ 的确,受制于 stroke 参数的影响,在旁边面的立体感上的确有所缺失,而为了提高立体感,咱们能够经过 zflutter 里的 ZBoxToBoxAdapter 来完成。

在 zflutter 里, ZBoxToBoxAdapter 能够经过装备 frontrearleftrighttopbottom 等参数来装备长方体每个面的 UI,而且它自身就会依据 widthheightdepth 参数生成一个立体长方形,如下图 1所示。

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

接着咱们简略经过图 2 的量角器确定 logo 的视点,然后如下代码所示,使用不同方位和视点,经过 ZBoxToBoxAdapter 组合堆叠不同的长方体,从而构成如上图 3 所示的立体 logo,当然,这个组合过程很显着是体力活

Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo
Flutter 实现 “真” 3D 动画效果,用纯代码实现立体 Dash 和 3D 掘金 Logo

完好代码可见: github.com/CarGuo/gsy_…

Web 体会地址,PC 端记住开 Chrome 手机形式: guoshuyu.cn/home/web/#%… 。

能够看到 zflutter 尽管没有之前 用 rive 给 Logo 快速增加动画作用 来的强大和方便,可是好在它体积够小,不需求加载任何资源,纯代码就能够完成各种立体的 3D 动画作用 ,这关于程序员来说愈加可控,至少它不需求依赖于任何第三方设计东西,便是开发速度上的确不如 rive 来的高效,需求必定的空间想象力

好了,本篇动画特效就到此为止,假如你有什么想法,欢迎留言谈论,感谢大家耐性看完,也还请看官们走过路过的来个点赞一键三连,感激不尽