“破碎-重组-破碎” CSS3实现Lowpoly风格变形动画终极篇

在受到SVG+CSS3动画仿做草莓音乐节宣传视频的伤害后,一直想找个简单唬人的东西作一作来平复一下悲愤的心情。翻了下收藏夹,找到了一个珍藏了好久的存货,三十种濒危动物的碎片动画效果。有时候,不少创意来自于别人,别不认可,戳戳看,很惊艳 。之前写过CSS3实现lowpoly动画效果的文章,虽然同为lowpoly效果,其实那个的实现难度要比这个高的多,也更加繁复,还用到了CSS的选择器,可是,仍是那句至臻名言,创意远比技艺重要,这个动物碎片的创意曾让我惊为天人。设计师小伙伴不用惧怕,最终效果,若是耐心的把文章看完,应该是能够作出来的,拿去吓一吓前端也是极好的,至于前端童鞋们,大家能够跳过直接看第三部分了,或者第四部分留的大坑。不废话,直接走起。javascript

1.第一步,不管如何你须要作一下动画底图

由于原效果有三十种动物,我固然不会闲到每个都作一遍,因此就挑本身心中喜欢的来几个就好。为了避免让各位看官失望,我会附上可复用的代码并注明增长新的图形的使用方法,想作三十张或者三百张的,随意。先拿第一张来讲:css

这是我在AI中几乎彻底仿照原图绘制的,对于设计师来讲,作这种图分分钟钟的事,大家比我溜,我是懒人作法,把底图扔上,而后比着作出了一堆三角形,这个不用太精确的,而后各个碎片按原图着色就能够了。若是看这篇文章的恰好是诸位前端大神们,嗯,去给美腻的UI妹纸买些零食吧,只能帮到你这里了。 一共有多少个三角形的碎片呢? 33片,请记住这个数字, 33,后面咱们再说缘由。
固然了,碎片数不须要一个个的去数,由于当存为SVG格式后,打开时,会有一些 <polygon points="" />的标签,每一个 <polygon>对应一个碎片,看看行数就好了(如下这句话仅针对无代码基础的设计师小伙伴,去下个notepad打开你的SVG文件,代码的可读性会增强)。 固然了,一张图是没法实现变形的,有些地方来不得偷懒,索性把那两张都作了吧,我选了鲸鱼和青蛙。

鲸鱼的碎片只有 30片,若是你看过个人其余关于变形动画的文章 好比这篇 ,应该有个基础的了解,首先碎片的数量是要相等的,因此鲸鱼加了 3片白云(或者确切的说是3个 <polygon>)来补齐数量。

这里说明一点,不管用哪一种作图软件,AI或者sketch,切记基础图形必定是三角形,不要引入任何其余形状。也就是说导出的每一个<polygon poins="">里面的坐标数量是相等的,会有三组或者四组。(AI另存和导出为两种方法生成的SVG是不一样的,但四组的最后一组与第一组是重复的,推荐另存为SVG格式,此坑已经踩过)html

2.第二步,如今,要想办法让碎片变形了

首先,咱们须要改变SVG文件的DOM结构,目前导出来的SVG文件除了一个背景的矩形<rect>标签,剩下的应该都是<polygon>标签了,举个例子,看看你的是否是和个人同样。 这是里面的任意一个碎片(好比是鸟bird),这个动画总体的思路就是每一个碎片变形的组合,以上面的为例,要变形的鲸鱼whale的 <polygon>标签以下: 前端

<polygon points="W1,W2 W3,W4 W5,W6" style="fill: #…"/>  
复制代码

若是是内联的样式,那CSS3能够直接黯然离场了,还谈什么动画。如今要作的是,把这些内联的属性通通扔到CSS部分里去,而后经过d:path属性的变化来获得变形动效。java

@keyframes p2{
0% {d:path('MB1,B2LB3,B4LB5,B6z');fill:#…} /*绘制bird其中之一碎片*/
100%{d:path('MW1,W2LW3,W4LW5,W6z');fill:#…} /*绘制whale其中之一碎片*/
}
#p2{animation:p2 2s ease both;} 
复制代码

而在DOM结构中,只要保留一个简单的<polygon>标签,获取这个动画属性就能够了。web

<polygon id ="p2" />
复制代码

在用CSS属性来绘制碎片时,格式记得必定要正确,填充色比较好理解,但全部的顶点坐标在写入d:path时都要转成Mxy Lx1y1 Lx2y2 Lx2y2 z这种样式,具体再也不解释了,属于基础知识。正则表达式

这里不管用什么办法,总之把全部碎片对应的<polygon>points的值转化成CSS3中的d值。好比,好比,我是用的万能的excel的强大的Find公式(嵌套了多个也挺麻烦的)来完成的(从未想过,有朝一日会用excel来拼接代码……),各路大神可能会有其余方法,正则表达式什么的,我不懂,大家各显神通, 总之,结果要是标准的,这是咱们变形动画的基础。至于顺序,不重要,按照默认生成的顺序来就能够了。若是不是把全部的33个碎片都列上,整个变形其CSS3和DOM结构是很是简单的。因此,这个动效,只是繁琐,远称不上复杂。bash

@keyframes bg{
0%{fill:#A4C5EA}
100%{fill:#73DBE0}
}
#bg{animation:bg 2s ease both;}
/*定义背景色的变化*/

@keyframes p(n){
0% {d:path('');fill:#…}
100%{d:path('');fill:#…;}
}
#p(n){animation:p(n) 2s ease both;}
/*n=1,2,3,4……33  一共须要定义33个*/
复制代码

DOM结构以下svg

<rect width="" height="" id="bg" />
<!--背景变色动效-->
<path id="p(n)" />
<!-- n=1,2,3,4……33  一共须要33个 -->
复制代码

先享受一下辛苦工做的效果:post

已经具有了雏形了,记得,上面我准备了三幅图,但这里我只作了从bird到whale的变形动画,并无启用第三张图片frog,由于这一部分只是原理,下面才是重点。

3.第三步,比原效果更优化,咱们支持交互

这里感谢Java大牛Hevo的帮助,是的,JavaScript只是随随便便懂一点,在提供了变形动画思路以后,轻松丢过来几行我看不懂的javascript脚原本实现交互,顺即可之后期扩展。原网站的动效是先后点击切换,既然求助了Hevo同窗,天然要作的优美动人一些。最后效果是支持任意图形之间的变形。如今,我把各部分从新放上来。javascript部分以下

$(function(){
	$("button").bind("click", function(){
		var turnTo = $(this).attr("turnTo");
		// for backgroud changing
		var bg = $("#p_bg");
		var bg_fill = bg.css("fill")
		bg.css("fill", bg_fill).css("animation", turnTo + "_bg 2s ease both")
		
		// for lowpoly changing
		$.each($("path"), function(i, n){
			var d = $(n).css("d");

			var fill = $(n).css("fill");
			
			$(n).css("d", d).css("fill", fill);
			$(n).css("animation", turnTo + "" + (i+1) + " 2s ease both");
		});
		
	})
})
复制代码

这个,这个,让我怎么解释呢?就是写了个循环而后根据点击按钮不一样给CSS对应赋值并调用该变形动画属性。

CSS部分以下

@keyframes bird_bg{
to{fill:#A4C5EA;}
}
/* 定义bird的背景色 */

@keyframes bird(n){
to{d:path('');fill:#…;}
}
/*定义bird碎片最终变形的效果 n=1,2,3……33*/、

@keyframes whale_bg{
to{fill:#73DBE0;}
}
/* 定义whale的背景色 */

@keyframes whale(n){
to{d:path('');fill:#…;}
}
/*定义whale碎片最终变形的效果 n=1,2,3……33*/

@keyframes frog_bg{
to{fill:#ffcffc;}
}
/* 定义frog的背景色 */

@keyframes frog(n){
to{d:path('');fill:#…;}
}
/*定义frog碎片最终变形的效果 n=1,2,3……33*/

#p_bg{
fill:#ffd480;
animation:bird_bg 2s ease both;
}
/*定义初始画面的背景*/
#p(n){
d:path('');fill:#…;
animation:bird(n) 2s ease both;
}
/*定义初始画面的路径 n=1,2,3……33*/

/* 定义按钮样式 */  
此处省略若干…… 喜欢什么样式去copy些下来吧
复制代码

DOM部分

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
	width="960"  height="720" viewbox="0 0 960 720">
<rect width="960" height="720" id="p_bg"/><!--此为背景-->
<path  id="p(n)" />  <!--n=1,2,3……33-->
</svg>
<p>
<button type="button" turnTo="bird" class="">BIRD</button> 
<button type="button" turnTo="frog" class="">FROG</button> 
<button type="button" turnTo="whale" class="">WHALE</button> 
</p>
复制代码

若是省略那一堆碎片的路径和填充色,整个代码读起来仍是清爽干净以及轻松愉快的。

如今,这个动画效果已经up了一个档次了。关于初始画面,那个 LOW,绝壁不是效果太low的意思啊,本心是想作个LOWPOLY的lowpoly效果,无奈生成的碎片超过了33片了,又懒得改其余部分(好比我能够给全部的都补充上空白路径 d:path('M0,0L0,0L0,0L0,0z')(若是你了解路径的绘制规则,应该能轻易看出来这是一个虚拟路径),来补齐全部的数量,可是,懒且麻烦就算了,low就low吧。

由于gif格式比较大,受限,因此快速点击的几下,想玩的愉快的到Demo演示地址里去吧。在文末,我会贴上个人codepen演示地址。

那么设计师小伙伴们怎么拿去用呢?看一下个人demo的命名的规则,全部的元素,我会尽可能保持统一的命名,好比,你要增长一张图片是sheep(我知道这是羚羊antelope,但这个单词超出认知范畴了,看不懂)。那么,要定义的有 图片背景色sheep_bg,sheep(n)的各个碎片的d:path属性,以及增长一个 turnTo="sheep" 的按钮,仅此而已。人肉亲测有效,见下图:

鉴于原网站仅支持上下顺序查看,而咱们支持任意切换,因此,此处应该有掌声。

4. 这个效果能够更好,只是不知道怎么用JavaScript控制

对于这一套动画的主体部分是动物之间的变形,但仍有小细节,好比身体某个部位依然能够动。以最初的那个bird turn to whale,在变形动画以前,bird尾巴部分可动,变形结束后,whale的鳍可动,我本身作了一下效果,大概是下面这样的。

思路很简单,把须要动的部分从新定义一个动画属性,以鸟的尾巴为例,由于肢体的摆动都是有关节的,因此用了旋转的变形属性 transform:rotate()

@keyframes bird_tail{
to {transform:rotate(6deg);}
}
#bird_tail{animation:bird_tail 0.5s ease-in-out 4 alternate;transform-origin:} 
/*准肯定义旋转的基点transform-origin很重要,就是关节位置*/
复制代码

而鲸鱼则嵌套了两个部分,总体的一个位移,**transform:translateX()**以及局部的几片组合的旋转,再设置好时间延迟,并非很困难。

鉴于此坑太深,不打算碰。实现这种效果后,剩下的丢给了Hevo同窗,看能不能用JavaScript实现两次按钮切换之间的局部变形的循环动画。

最后的最后,小结一下,对于这个动效而言,看上去逼格满满,但其实只是一个简单的d:path()属性值改变的变形效果。但由于单变多,因此产生了这种惊叹的效果。codepen地址Lowpoly transform animation,能够去预览,怎么改为本身想要的图形,我想在上面已经说的很清楚了,玩起来咯。

相关文章
相关标签/搜索