和你們分享一個看上去很酷的效果,先來看效果圖吧!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),
產生的效果就是向左上方移動數組