做者:Anna Prenzel翻譯:瘋狂的技術宅javascript
原文:https://www.smashingmagazine....css
未經容許嚴禁轉載html
你是否曾經想過用花哨的、閃閃發光的粒子動畫分吸引你網站用戶的注意力,而同時又在後臺加載一些數據呢?幸運的是,沒有必要用諸如 Three.js 之類的 3D 庫進行很是深刻的圖形編程。相反,你須要的是 CSS 和 JavaScript 的一些基本知識以及輕便的動畫庫(例如 anime.js)。最後咱們應該獲得如下結果:前端
你能夠從官方 GitHub 下載 anime.js 庫。從lib/
文件夾下載文件anime.js 或 anime.min.js。java
在個人例子中,HTML 部分以下所示:git
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>Anime.js Particles</title> <!--or use anime.min.js--> <script src="anime.js"></script> <link rel="stylesheet" href="style.css"> </head> <body> <div class="anime-container"> </div> <script src="script.js"></script> </body> </html>
CSS 文件 styles.css 用來定義頁面和每一個粒子的背景色。位置是必須要設置的,稍後咱們能夠用 CSS 屬性 left
和 top
在頁面上自由放置粒子。程序員
body { background-color: hsl(30, 3%, 14%); } .anime-container { position: relative; } .anime-container .dot{ position: absolute; /*draw particles as circles:*/ border-radius: 50%; background-color: hsl(60, 100%, 80%); }
顧名思義,粒子動畫由許多遵循特定模式在空間中移動的小粒子組成。在動畫開始以前,同時生成全部粒子。github
對於如下解釋,anime.js的官方文檔 對你很是有用。面試
在個人例子中,粒子位於阿基米德螺旋上。屏幕上粒子的 x 和 y 位置(在 CSS 中又稱爲 left
和 top
)是根據其在螺旋上的位置 angle 來計算的:編程
x=a*angle*cos(angle) y=a*angle*sin(angle)
角度以及螺旋的長度由參數 l
肯定。經過參數 a
,你能夠控制螺旋線的密度。
var container = document.querySelector(".anime-container"); var n = 15; var a = 20; var l = 110; for (var i = 0; i <= l; i += 1) { var angle = 0.1 * i; //shift the particles to the center of the window //by adding half of the screen width and screen height var x = (a*angle) * Math.cos(angle) + window.innerWidth / 2; var y = (a*angle) * Math.sin(angle) + window.innerHeight / 2; var dot = document.createElement("div"); dot.classList.add("dot"); container.appendChild(dot); var size = 5; dot.style.width = size + "px"; dot.style.height = size + "px"; dot.style.left = x + "px"; dot.style.top = y + "px"; dot.style.backgroundColor = "hsl(60, 100%, 80%)"; } }
這樣,咱們獲得一個螺旋,每一個位置只有一個粒子,可是隻有在每一個位置生成一個以上的粒子時,才能實現真正的拖尾效果。爲了使軌跡顯得濃密,各個粒子的位置必須略有不一樣。動畫庫爲此提供了實用的輔助函數:
anime.random(minValue, maxValue);
粒子的大小也隨機變化:
for (var i = 0; i <= l; i += 1) { var angle = 0.1 * i; //shift particles to the center of the window //by adding half of the screen width and screen height var x = (a*angle) * Math.cos(angle) + window.innerWidth / 2; var y = (a*angle) * Math.sin(angle) + window.innerHeight / 2; var n = 15; //create n particles for each angle for (var j = 0; j < n; j++) { var dot = document.createElement("div"); dot.classList.add("dot"); container.appendChild(dot); var size = anime.random(5, 10); dot.style.width = size + "px"; dot.style.height = size + "px"; dot.style.left = x + anime.random(-15, 15) + "px"; dot.style.top = y + anime.random(-15, 15) + "px"; dot.style.backgroundColor = "hsl(60, 100%, 80%)"; } }
在這裏,你能夠嘗試中間結果:
請參閱 CodePen 上的 js 粒子動畫 wip:https://codepen.io/smashingma...。
在動畫開始以前,全部粒子都必須是不可見的。因此我將添加:
dot.style.opacity = "0";
個人動畫的基本設置以下:
anime({ loop: true, easing: "linear", targets: document.querySelectorAll(".dot"), });
在下一步中,我將爲目標的各類 CSS 屬性設置動畫。 CSS 動畫的基本步驟能夠在 anime.js 文檔中屬性相關的章節中找到。
這是咱們第一個屬性動畫的樣子,其中全部粒子在 50 毫秒內逐漸可見:
anime({ loop: true, easing: "linear", targets: document.querySelectorAll(".dot"), opacity: { value: 1, duration: 50} });
如今,我將揭示致使粒子螺旋運動的技巧!想法是使粒子以必定的時間延遲(例如,以 2 ms 的間隔)可見。首先使螺旋中間的粒子可見,而後從內到外的使全部其餘粒子可見。 anime.js 的 stagger 函數很是適合此功能。我認爲,交錯是該庫的最大優點之一,它使你能夠實現出色的效果。
opacity: { value: 1, duration: 50, delay: anime.stagger(2) }
爲了產生飛行軌跡的錯覺,粒子一旦出現就必須開始緩慢消失。幸運的是 anime.js 提供了屬性的關鍵幀符號:
opacity: [ { value: 1, duration: 50, delay: anime.stagger(2) }, { value: 0, duration: 1200} ],
在這裏,你能夠看到中間結果:
請參閱 CodePen 上的 js 粒子動畫 wip 2:https://codepen.io/smashingma...。
彗星蹤影出現時應該比消失前更大。爲此,我讓粒子在 500ms 內縮小到 2px 的直徑。選擇與不透明度動畫相同的時間延遲很重要,這樣每一個粒子只有在出現後纔開始收縮:
width: { value: 2, duration: 500, delay: anime.stagger(2) }, height: { value: 2, duration: 500, delay: anime.stagger(2) },
粒子動畫的典型特徵是粒子的獨立性、不可預測的行爲。最後,我經過沿 x
和 y
方向的運動將粒子帶入動畫:
translateX: { value: function() { return anime.random(-30, 30); }, duration: 1500, delay: anime.stagger(2) }, translateY: { value: function() { return anime.random(-30, 30); }, duration: 1500, delay: anime.stagger(2) }
一樣,重要的是運動開始的時間應該與粒子的出現有相同的時間延遲。
另外在這種狀況下,絕對有必要用 functions
來計算 translateX
和 translateY
的值。在這裏,咱們將參數用做基於函數的參數,其值是針對每一個目標單所獨肯定的。不然全部目標移動相同的量都會是相同的(儘管是隨機肯定的)。
你能夠在此處查看最終結果:
請參閱查看 CodePen 上的 js 動畫粒子:https://codepen.io/smashingma...。
你能夠經過簡單地調整這些值來根據本身的喜愛修改動畫。關於最後的修飾有一個小技巧:如今咱們熟悉了基於函數的參數,能夠稍微改善動畫的透明度:
opacity: [ { value: 1, duration: 50, delay: anime.stagger(2) }, { value: 0, duration: function(){return anime.random(500,1500);}} ],
如今分別爲每一個粒子設置粒子消失以前的持續時間。這可以使動畫在視覺上更加精緻。
我建議你訪問 CodePen,在這裏你能夠看到更多使人印象深入的例子。