我正在参与「构思开发 投稿大赛」详情请看:构思开发大赛来了!
本篇将给你带来愈加炫酷动画作用,最终教你怎么经过纯代码完成一只立体的 Flutter 的吉祥物 Dash 和 3D 的 logo 动画。
❤️ 本文正在参与征文投稿活动,还请看官们走过路过来个点赞一键三连,感激不尽~
在之前的 《炫酷的 3D 卡片和帅气的 360 展示作用》 里,咱们运用手势代码和视点切换,在 2D 画板里完成了“伪” 3D 的视觉作用,就在我觉得作用还不错时, 有一位掘友提出了一个要害性的问题:卡片短少厚度,也便是没有 3D 的质感 。
的确,如下图所示,在之前的完成里,跟着卡片视点的歪斜,有两个问题特别显着:
- 当卡片旋转到侧边时,卡片的短少“厚度”的质感,乃至呈现了消失的状况
- 卡片上的文字尽管做了相似凹凸的视觉作用,可是从旁边面看时也是短少立体质感
而为了在 2D 平面完成三唯的质感,在查阅相关材料时我发现了前端的 Zdog 结构,Zdog 是一个运用 Canvas
完成的伪 3D 引擎, 它支持经过 2D 的 Canvas
API渲染出相似 3D 的作用。
Zdog 作为一个 js 结构,它大约只要 2800 多行代码,而且其最小体积为 28KB ,能够说非常轻量级。
尽管 Zdog 是一个纯 js 结构, 但已然它是经过 Canvas
完成的逻辑,那就完全能够 “轻松” 迁移到 Flutter ,毕竟 Flutter 自身便是一个重度依赖于 Canvas
的结构,而恰巧在 Flutter 社区就有针对 Zdog 的移植版本: zflutter 。
尽管这个 package 作者现已两年不保护,也没有发布 null-safety 的 pub 支持,可是已然是开源项目,自己动手风衣足食,在经过一番“简略”的迁移适配之后, zflutter 再次在 Flutter 3.0 下“勃发新春” 。
咱们先看作用,在结合 zflutter 的完成之后,能够看到卡片的立体作用得到了全面的提高:
- 首要卡片有了厚度的质感,旋转到侧边也不会“消失”
- 卡片上的字体在歪斜时也有了立体的作用
那在解说完成之前,咱们要解决一个疑问: zflutter 究竟是怎么在 2D 画板上完成 3D 的质感 ?而其实这个问题的要害就在于:经过手势发生的矩阵改换是作用于画板仍是作用于途径 。
咱们首要看一个比如,如下代码所示,咱们创建了一个 CustomPaint
,然后在代码里制作了 4 条相同赤色直线,接着对其间 3 条直线的 Canvas
进行不同程度的矩阵旋转,如下图 2 能够看到有两条红线消失不见了:
- 当红线绕 Y 轴旋转
pi / 2
(90)时,由于此刻画板恰好和咱们呈笔直状况,所以会呈现看不到的状况 - 当红线绕 XY 轴旋转
pi / 4
时,能够看到画板此刻和咱们视觉成 45 的状况 - 当红线绕 XY 轴旋转
pi / 2
(90) 时,由于此刻画板仍是和咱们呈笔直状况,所以呈现看不到的状况
假如觉得上面的描述太抽象,那么结合下面动图,能够看到当红线在环绕 XY 轴做旋转时,假如画布(Canavas
)和咱们呈 90 笔直的时分,此刻就会呈现消失不见的状况,由于画布是 2D 的平面,这也是为什么之前完成的卡片没有“厚度”的原因 。
那假如不对 Canavs
,而是对制作途径 Path
进行矩阵改换呢 ?不对画布进行旋转,不就不会呈现消失的状况了吗?
如下代码所示,同样是环绕 XY 轴进行旋转,可是此刻是直接对 Path
进行 path.transform
操作,也便是此刻画布Canvas
不会呈现视点改换,呈现改变的是制作的 Path
途径,能够看到:
- 当红线绕 Y 轴旋转
pi / 2
(90)时,此刻红线成了红点,由于它此刻它是“头正对着咱们” - 当红线绕 XY 轴旋转
pi / 4
时,能够看到此刻红线整体成 45 的状况对着咱们 - 当红线绕 XY 轴旋转
pi / 2
(90) 时,能够看到此刻红线是“笔直正对着咱们”
结合下面的动图,能够看到对 Path
进行矩阵改换的旋转之后,整体的立体感就不相同了,也便是一开始是调整咱们和画布之间的视点,可是现在咱们是改变了“笔”在画布上的制作方式来发生的视差,这也是 zflutter 里完成 3D 立体感的要害:对 Path
做矩阵运算而不只是对 Canvas
。
题外话,借着这个机会顺带普及个小知识点:在前面的代码里能够看到会对矩阵进行 leftTranslate
和 translate
的操作 ,这是由于咱们需求在不同方位制作多条红线,所以它们的方位并非都在起点,而运用 leftTranslate
和 translate
来对矩阵进行平移,才能达到每次旋转时都是以红线的“中心”去旋转,举个比如:
- 如图 1 所示是红线没有绕 Z 轴旋转的状况
- 如图 2 所示是红线在绕 Z 轴旋转
pi / 2
时没有进行矩阵平移的状况,能够看到此刻它们的中心点还在开始方位 - 如图 3 所示是红线在绕 Z 轴旋转
pi / 2
时,进行了leftTranslate
和translate
操作的状况
完好代码可见: github.com/CarGuo/gsy_…
Web 体会地址,PC 端记住开 Chrome 手机形式:guoshuyu.cn/home/web/#%… 。
那么回到 zflutter 里,在 zflutter 里便是经过组合各类图形和线条,然后使用对 Path
进行矩阵改换,从而完成相似 3D 立体的视觉作用 ,例如下面图 2 的立体正方形,就符合咱们对增加厚度的需求。
这儿先简略介绍下 zflutter 里常用目标的作用:
-
ZIllustration
相似于画板的作用,能够装备zoom
特点来调整画板的缩放 -
ZPositioned
用于装备方位和巨细信息,例如scale
、translate
、rotate
等特点(其实它便是在内部将接收到的矩阵参数装备到ParentData
,然后传递给 child) -
ZDragDetector
用于处理手势相关信息,主要是装备ZPositioned
的rotate
就能够快速完成上面的 360 拖拽作用 -
ZGroup
用于组合多个图形的层叠 -
ZToBoxAdapter
用于嵌套一般的 Flutter 控件 -
ZRect
、ZRoundedRect
、ZCircle
、ZEllipse
、ZPolygon
、ZCone
、ZCylinder
、ZHemisphere
等是内置的形状,如下图 -
ZShape
相似于 Canvas ,用于合作ZMove
、ZLine
、ZBezier
、ZArc
等制作自定义形状
所以要完成卡片的 “真” 3D 作用,简略来说咱们需求做的是:
- 增加一个
ZIllustration
画布 - 增加一个
ZDragDetector
合作ZPositioned
用于处理手势旋转 - 增加一个
ZGroup
,然后在里面经过ZToBoxAdapter
增加银行卡的前后两张 png 图片 - 在两张图片之间增加一个
ZRoundedRect
做边框,装备颜色为Color(0x8A000000);
完成厚度作用 - 使用
ZShape
制作数字,这样制作呈现的数字就会有立体的感觉
如上图所示,能够看到经过 zflutter 的处理之后,不只是卡片自身有了“厚度”的质感,在歪斜也能够看到文字立体视觉,现在就算是如图 3 相同旋转到 90 的状况,仍然能够看到卡片和文字之间的层次联系 。
完好代码可见: github.com/CarGuo/gsy_…
Web 体会地址,PC 端记住开 Chrome 手机形式: guoshuyu.cn/home/web/#%… 。
详细源码能够直接看上方链接,那认识了 zflutter 之后,咱们还能使用 zflutter做什么呢 ?其实在官方的 Demo 里就有一个很有典型的示例,那便是 Flutter 的吉祥物 Dash ,接下来咱们看怎么使用 zflutter 开始完成一只立体质感的 Dash 。
首要咱们使用 ZCircle
画一个圆,用于完成 Dash 的身体
然后咱们经过 3 个不同方位和视点的 ZEllipse
椭圆来组成 Dash 的头发,事实上 zflutter 里很多作用便是经过相似这样的图形组合来完成的。
接着咱们在 ZShape
里使用 ZArc
完成不同视点的弧形组合完成尾巴,这儿的要害是 z 轴上需求有部分落差,如下图展示是尾巴在 3 个不同视点的可视作用。
再经过调整两个 ZEllipse
椭圆的视点来完成 Dash 的手部作用,在这一点上 zflutter 的确很考验开发者关于图形在平面上的空间感。
接着经过 ZCone
就能够快速完成 Dash 的嘴巴。
然后这部分信任不用代码大家也知道,便是经过组合多个 ZEllipse
和 ZCircle
堆叠来完成 Dash 的眼睛。
最终,把上面的零部件组合到一起,在装备上循环的动画参数,当当当~一只生动立体的 Dash 就完成了。
完好代码可见: github.com/CarGuo/gsy_…
Web 体会地址,PC 端记住开 Chrome 手机形式: guoshuyu.cn/home/web/#3… 。
比照实物 Dash ,能够看到使用 zflutter 完成的 Dash ,乍看之下形似度仍是蛮高的,同时 zflutter 自身也只要 82k 左右的巨细,作为一个超轻量级的伪 3D 动画结构,它在接入本钱很低的状况下,尽或许做到了咱们对 3D 空间所需的视觉作用,这儿面的要害仍是在于:矩阵改换是作用于画板仍是作用于途径 。
那在知道原理之后,咱们接下来就能够经过三个简略的 ZShape
组合,使用 ZMove
和 ZLine
就能组合出具有 3D 质感的 Logo ,里面的参数直接从 SVG 的 path 映射过来就能够了 。
由于咱们的矩阵旋转改变的是 Path 而不是 Canvas ,所以 Logo 的立体作用能够经过 skroke
的粗细合作画布 zoom
扩大来表现。
完好代码可见: github.com/CarGuo/gsy_…
Web 体会地址,PC 端记住开 Chrome 手机形式: guoshuyu.cn/home/web/#%… 。
那或许就有人要说了,这个 logo 立体感仍是不行强,由于它仍是太扁平了 ~ 的确,受制于 stroke
参数的影响,在旁边面的立体感上的确有所缺失,而为了提高立体感,咱们能够经过 zflutter 里的 ZBoxToBoxAdapter
来完成。
在 zflutter 里, ZBoxToBoxAdapter
能够经过装备 front
、rear
、left
、right
、top
、bottom
等参数来装备长方体每个面的 UI,而且它自身就会依据 width
、height
、depth
参数生成一个立体长方形,如下图 1所示。
接着咱们简略经过图 2 的量角器确定 logo 的视点,然后如下代码所示,使用不同方位和视点,经过 ZBoxToBoxAdapter
组合堆叠不同的长方体,从而构成如上图 3 所示的立体 logo,当然,这个组合过程很显着是体力活。
完好代码可见: github.com/CarGuo/gsy_…
Web 体会地址,PC 端记住开 Chrome 手机形式: guoshuyu.cn/home/web/#%… 。
能够看到 zflutter 尽管没有之前 用 rive 给 Logo 快速增加动画作用 来的强大和方便,可是好在它体积够小,不需求加载任何资源,纯代码就能够完成各种立体的 3D 动画作用 ,这关于程序员来说愈加可控,至少它不需求依赖于任何第三方设计东西,便是开发速度上的确不如 rive 来的高效,需求必定的空间想象力 。
好了,本篇动画特效就到此为止,假如你有什么想法,欢迎留言谈论,感谢大家耐性看完,也还请看官们走过路过的来个点赞一键三连,感激不尽 ~