这篇文章发布于 2016年06月7日,星期二,23:51,归类于 JS实例。 阅读 51576 次, 今日 1 次 22 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=5426
一、先看效果
您可以狠狠地点击这里:基于clip-path的元素碎片飞入动效demo
二、实现原理
效果本质上是CSS3动画,就是旋转(transform:rotate
)和位移(transform:translate
),只是旋转和位移的部件是三角碎片而已。
那三角从何而来,本质上是使用CSS3 clip-path剪裁出来的。
关于CSS3 clip-path可以参见我之前的文章:“CSS3 clip-path polygon图形构建与动画变换二三事”。
剪裁一个三角并不难,但是,如果把任意的元素剪裁成一个一个的三角呢?
这就需要借助JS来实现了。
JS把元素剪裁成一个一个的等腰直角三角形,然后随机分布在四周,然后,通过CSS3 animation动画,让所有的在四周的元素归为就可以。因为CSS3 animation动画关键帧中的CSS样式权重似乎要比style
大。
于是,我们有如下核心CSS:
.clip[style] { opacity: 0; } .active .clip[style] { will-change: transform; animation: noTransform .5s both; } @keyframes noTransform { to { opacity: 1; transform: translate3d(0, 0, 0) rotate(0); } }
其中,will-change
作用是让动画更流畅,可参见我之前文章:“使用CSS3 will-change提高页面滚动、动画等渲染性能”。
.active .clip[style]
这段CSS表示的意思是,只要被剪裁的三角们的父级有了类名active
, 所有的三角的位置就不是随机分布,而是会以动画形式归位到其原本的位置。没错,是所有,我们没有必要对每一个剪裁的三角碎片做动画,只要归位就可以。
通过toggle类名active
, 碎片的动效就可以不停地呈现,经测试,在移动端效果也是不错的。
目前,除了IE浏览器和Android4.3-都支持了clip-path
,不过还需要-webkit-
私有前缀。
三、我也想使用
我花了点功夫封装了一个方法,1K出头一点,代码如下(大家可以直接放到项目JS中或独立个JS文件):
/**
* @description 任意元素碎片化,配合CSS可以有碎片拼接特效
更多内容参见 http://www.zhangxinxu.com/wordpress/?p=5426
* @author zhangxinxu(.com)
* @license MIT [保留此段注释信息署名]
*/
var clipPath=function(t){if(!t){return false}t.removeAttribute("id");var r={height:t.clientHeight,width:t.clientWidth,distance:60,html:t.outerHTML};if(window.getComputedStyle(document.body).webkitClipPath){var a=r.distance,n=r.width,e=r.height;var o="";for(var i=0;i<n;i+=a){for(var h=0;h<e;h+=a){var d=[i,h],u=[i,h+a],l=[i+a,h+a],v=[i+a,h];var c=[i+a/2,h+a/2];var m=[[d,c,v],[d,u,c],[c,u,l],[v,c,l]];m.forEach(function(t,a){var n=t.map(function(t){return t.map(function(t){return t+"px"}).join(" ")}).join();var e="-webkit-clip-path: polygon("+n+");";var i=Math.random();var h=i<.5?-1:1;var u=[600*(.5-Math.random()),600*(.5-Math.random())];var l="translate("+u.map(function(t){return t+"px"}).join()+") rotate("+Math.round(h*360*Math.random())+"deg)";var v="-webkit-transform:"+l+";transform:"+l+";";o=o+r.html.replace('">','" style="'+e+v+'">')})}}t.parentNode.innerHTML=r.html+o;return true}else{t.className+=" no-clipath";return false}};
语法如下:
clipPath(ele);
其中,ele
为DOM元素,clipPath
方法基于原生JS书写,不依赖其他JS框架,对于不支持clip-path
的浏览器没有效果。返回值是布尔值true
或false
, 返回true
表示浏览器支持clip-path
,false
为不支持。
代码中的distance:60
表示碎片的大小,越小碎片越多,对性能的考验就越大。
例如,demo中文字和图片的使用:
var eleText = document.getElementById('text'),
eleImage = document.getElementById('image');
// 碎片特效初始化
clipPath(eleText);
clipPath(eleImage);
需要注意的是:
- 应用动效的务必是absolute绝对定位元素。一来效果必须,二来性能考量;
- 应用动效的元素不要太复杂,可能对性能会有考验;
- 原始被用来粉碎的元素一直都在的,这样,碎片拼接处的间隙就看不出来啦!
四、结束语
我写的第一版JS中的碎片分布是为随机分布,基本上根据自身方位随机分布在4个角的方向上;这里给大家展示的是真随机,也就是最左边的碎片可能是从最右侧飞过来的,所以效果要更爆裂一点。
好了,其他就没什么了,一个小特效而已。
其实说穿了,并没有多大的难度,一点JS+一点CSS。关键是想到好的解决思路。如何才能有好的解决思路呢,需要对前端是真爱,这样你会一直把前端放在脑中,自然而然就会是不是迸出很多很好的思路,创意和解决方案了!否则,永远都只能拾人牙慧。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=5426
(本篇完)
- 使用CSS3 will-change提高页面滚动、动画等渲染性能 (0.413)
- CSS3/SVG clip-path路径剪裁遮罩属性简介 (0.289)
- 介绍一种全新的clipPath Sprites小图标技术 (0.289)
- 3种纯CSS实现中间镂空的12色彩虹渐变圆环方法 (0.220)
- 今天学习SVG滤镜feGaussianBlur和feDropShadow (0.207)
- CSS CSS3实现3D开门动画效果 (0.160)
- CSS clip:rect矩形剪裁功能及一些应用介绍 (0.138)
- 您可能不知道的CSS元素隐藏“失效”以其妙用 (0.138)
- CSS hover效果的逆向思维实现 (0.138)
- canvas图形绘制之星空、噪点与烟雾效果 (0.138)
- 介绍一种CSS变量未定义语法也OK的小妙招 (RANDOM - 0.022)
我要用火狐跨域,谷歌好难弄,火狐还不能用这个效果啊
用animation来做的话实现逆过程比较麻烦
.open{
opacity: 1 !important;
transform: translate3d(0, 0, 0) rotate(0) !important;
}
通过点击添加/删除类名的形式更好控制
效果很酷炫,虽然目前只能支持chrome,已在项目上使用!!
对前端真的是真爱啊 ,研究好透彻
对前端的真爱!!!说的真好!
这个不支持IE 怎么破?
真他妈服你了
别人问的好好的,你能耐什么?你这种人说话方式能在这里没被删真是奇迹,我还以为进了某垃圾贴吧,遇到了你们这群素质低下的人
你妈嗨这个效果还要支持IE,你是在做宝搞吗
整个评论区就服你
我也是醉了……
自然而然就会是不是迸出很多很好的思路———-
时不时
让所有的在四周的元素归为就可以—-
归位
为什么第一遍可以执行,如果放在单击事件中就不能够执行了呢?还报index.js:48 Uncaught TypeError: Cannot read property ‘innerHTML’ of null这个错误呢??
原来的clipPath(eleImage);改成clipPath(document.getElementById(‘image’));试试
好像用缓存下来的元素就会这样
图片没有效果啊
怎么随机分隔成n个三角形,可以介绍一下吗?
动画逆转就是爆炸效果!
你的支付宝链接失效了兄弟
firefox无效
这么那么厉害啊,膜拜大神
怎么可能 权重大过 内联样式 。。。
结束样式 只是 动画的属性而已: animation-fill-mode