和你们分享一个看上去很酷的效果,先来看效果图吧!javascript
实现这个效果的思路就是,一个大的div元素,设置好一个背景,生成必定数量小的div元素,背景设置成一样的图片,可是每一个小div元素的 background-position
属性值不一样,整齐的覆盖在大的div元素上,这样就能拼成一张完整的背景图,鼠标移入时,让全部小的div元素移动和变形。
总的来讲就是两步:
一、生成小的div元素,整齐的覆盖在大的div元素上,像下图这样(为了方便看,把每一个小div元素,分开了些)。css
二、鼠标移入时,让全部小div元素动起来,主要是改变小div元素的left、top、opacity、transform属性的值html
具体实现的代码也并很少,下面是注释很详细的代码。前端
<!doctype html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style> body { overflow: hidden; } #container { width: 400px; height: 300px; margin: 150px auto 0 auto; position: relative; } </style> </head> <body> <div id="container"></div> <script type="text/javascript"> window.onload = burst; function burst() { // ready 用来避免高频率的产生动画效果 var ready = true; // 容器 var img = document.querySelector('#container'); // 动画时间,单位是s var S = 1; // 每行 R 个 碎片 var R = 4; // 每列 C 个 碎片 var C = 7; // 容器宽度 var W = parseInt(window.getComputedStyle(img)['width']); // 容器高度 var H = parseInt(window.getComputedStyle(img)['height']); // 控制碎片的范围 var N = 2; // 碎片分散时,整个活动范围的宽 var maxW = N * W; // 碎片分散时,整个活动范围的高 var maxH = N * H; // 控制显示第 now 张图片 var now = 0; // 保存图片路径的数组 var imgArr = [ 'https://kkkk1000.com/images/ExplosionPictureSwitching/1.jpg', 'https://kkkk1000.com/images/ExplosionPictureSwitching/2.jpg', 'https://kkkk1000.com/images/ExplosionPictureSwitching/3.jpg', ]; img.style.background = 'url(' + imgArr[0] + ') no-repeat'; var next = function () { return (now + 1) % imgArr.length; } img.onmouseover = function () { // 若是ready 为false 不产生动画效果 if (!ready) return; ready = false; // 建立文档片断 var html = document.createDocumentFragment(); // 修改容器背景图 if (now + 1 >= imgArr.length) { img.style.background = 'url(' + imgArr[0] + ') no-repeat'; } else { img.style.background = 'url(' + imgArr[now + 1] + ') no-repeat'; } // posArr 用来保存每一个碎片的初始位置和结束位置, var posArr = []; var k = 0; // 生成必定数量的小div元素,覆盖在容器上 for (var i = 0; i < R; i++) { for (var j = 0; j < C; j++) { posArr[k] = { // left 表明碎片初始时的 left 值 left: W * j / C, // top 表明碎片初始时的 top 值 top: H * i / R, // endLeft 表明动画结束时的 left 值 endLeft: maxW * j / C - (maxW - (maxW - W) / C - W) / 2, // endTop 表明动画结束时的 top 值 endTop: maxH * i / R - (maxH - (maxH - H) / R - H) / 2, // (maxW-(maxW-W)/C-W)/2 和 (maxH-(maxH-H)/R-H)/2 是为了让碎片能在容器的周围散开 }; // 建立一个div,一个div就是一个碎片 var debris = document.createElement("div"); // url 用来表示碎片的背景图的路径 var url = imgArr[now]; // 初始时,碎片的样式 debris.style.cssText = ` position: absolute; width: ${Math.ceil(W / C)}px; height: ${Math.ceil(H / R)}px; background: url(${url}) -${posArr[k].left}px -${posArr[k].top}px no-repeat; left: ${posArr[k].left}px; top: ${posArr[k].top}px; opacity:1; transition:${randomNum(0.1, S)}s ease; `; // 把建立的每一个div,添加到文档片断中 html.appendChild(debris); k++; } } // 把文档片断 加到DOM树中 img.appendChild(html); // 获取容器的全部子元素,也就是全部的碎片 var debrisAll = img.children; // 改变每一个碎片样式,实现动画效果 setTimeout(function () { for (var i = 0; i < debrisAll.length; i++) { var l = posArr[i].endLeft; var t = posArr[i].endTop; debrisAll[i].style.cssText += ` left : ${l}px; top : ${t}px; opacity :0; transform:perspective(500px) rotateX(${randomNum(-180, 180)}deg) rotateY(${randomNum(-180, 180)}deg) rotateZ(${randomNum(-180, 180)}deg) scale(${randomNum(1.5, 3)}); `; } // 动画效果完成后 // 删除碎片 // 把ready 设置为true,能够再次产生动画效果 // 改变 now的值,也就是改变当前要显示的图片 setTimeout(function () { img.innerHTML = ''; ready = true; now = next(); }, S * 1000); }, 100); } // 产生一个 n - m 之间的随机数 function randomNum(n, m) { return Math.random() * (m - n) + n; } } </script> </body> </html>
这个效果其实和上次实现的一个雪花效果很相似,
简单说 JavaScript实现雪花飘落效果 都是利用定时器实现的动画,定时器应该算是这个效果的重点了,该好好理解下。 java
这个效果,代码中设置的是让碎片在容器周围散开,固然你也能够在代码中修改 碎片的 endLeft 和 endTop 的值,来改变方向,好比若是改为这样segmentfault
endLeft: maxW * j / C - (maxW - W), endTop: maxH * i / R - (maxH- H),
产生的效果就是向左上方移动数组