共用的 HTML 與 CSS 說明

範例中共同的部份只有 HTML 與 CSS,如下。

特別說明的部份:

  • mix-blend-mode: darken:CSS 色混合模式,有點類似 PhotoShop 的圖層的圖層濾鏡。
  • pointer-events: none:穿越上層的元素,當滑鼠點按不會觸發事件。

監聽 mousemove 事件來觸發取得 xy 座標,做為樣式 translate 屬性變化時所產生的 transform 動畫

JavaScript 的部份如下。

運行的結果如下,在觸發上會以連續觸發的方式,讓跟著移動的色塊很緊密的跟著,比較沒有運動上的快慢變化。

See the Pen 滑鼠跟隨的元素-1-監聽 mousemove 觸發取得 xy 座標,做為樣式 translate 屬性變化所產生的動畫 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


增加 requestAnimationFrame 方法讓函式連續觸發自已產生微廷遲 + 元素中心定位

重點解說:

  • offsetWidth:元素的佈局寬度,測量包含元素的邊框 (border)、水平線上的內邊距 (padding)、豎直方向捲軸 (scrollbar)(如果存在的話)、以及 CSS 設定的寬度 (width) 的值。
  • offsetHeight:與上面的 offsetWidth 差不多,只是用來取得元素垂值的資訊。
  • settings.mouseX = e.pageXsettings.mouseY = e.pageY:透過 document.addEventListener("mousemove") 的監聽方法,會將滑鼠取得的座標位置傳向 settings 物件下的 mouseXmouseY
  • const animate = () => {} 的函式與執行,會因為 requestAnimationFrame(animate) 動畫方法的觸發,本身這個方法只會執行一次而本身不會執行,但把 animate 函式當成參數傳入執行後,函式會自已不斷的觸發執行,讓動畫進行更新。
  • settings.xPos += (settings.mouseX - settings.xPos) / settings.speed;
    • settings.mouseX 是由 document.addEventListener("mousemove") 觸發所傳入的滑鼠當前的座標。
    • 自訂義的 settings.xPos 是動畫元素的座標,受到滑鼠移動後會先減去計算,接著在除於所設定的速度 settings.speed (值是 15),會將計算的結果傳向 settings.xPos 動畫元素的座標做賦值的動作。
  • cursor.style.transform = `translate(${settings.xPos - cursorWidth / 2}px, ${settings.yPos - cursorHeight / 2}px)`
    • settings.xPos 因為值的計算而改變後,就可以傳向 transform 的 CSS 動畫屬性,當 translate 屬性產生變化後就會產生動畫了,也因為定位因 translate (位移) 將 x 與 y 的部份計算過,所以產生有點類似延遲的效果產生。
    • cursorWidth / 2cursorHeight / 2,是用來取跟隨元素自身的高度與寬度的正中間。
    • 取得跟隨元素自身的高度與寬度的正中間後,接著向 settings.xPos 水平與 settings.yPos 垂直相減,這樣就會讓跟隨元素的定位扣掉自先的高和寬。

完整範例如下:

See the Pen 滑鼠跟隨的元素-2-增加 transform by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

參考資料: