跳至主要内容

[JS30] Day16: CSS Text Shadow Mouse Move Effect

keywords: mouseevent, mousemove, offset, 解構賦值, Destructing

在今天的練習中會做出陰影可以跟著滑鼠移動的效果。

this 和 e.target 在 eventHandler 中的差異

element.addEventListener 中使用 thise.target 的差異:

  • this 總是會拿到被監聽的對象本身,也就是 element.addEventListener(<eventHandler>) 的 element。
  • e.target 則是指事件被觸發時的對象,有可能不是 element 本身。
const hero = document.querySelector('.hero');

hero.addEventListener('mousemove', moveShadow);

function moveShadow(e) {
console.log('this', this); // 回傳的一定是 ".hero"
console.log('e', e.target); // 回傳的可能是 ".hero" 也可能是 "h1"
}

物件的解構賦值(Object Destructing)

img

/**
* 等同於
* const heroWidth = hero.offsetWidth
* const heroHeight = hero.offsetHeight
* let offsetXAfterAdjust = e.offsetX
* let offsetYAfterAdjust = e.offsetY
**/

const { offsetWidth: heroWidth, offsetHeight: heroHeight } = hero;
let { offsetX: offsetXAfterAdjust, offsetY: offsetYAfterAdjust } = e;

JavaScript 物件 @ PJCHENder Evernote

offset

要特別留意的是 offsetLeft, offsetTop, offsetWidth, offsetHeight 是 Element 的屬性;而 offsetXoffsetY 是 Event 的屬性。

Element 屬性

  • offsetLeft, offsetTop 指該 element 到 offsetParent 的距離。
  • offsetWidth, offsetHeight 指該 element 的寬高。

Event 屬性

  • offsetX, offsetY,指滑鼠到外層容器的距離。

Browser Coordinate System │ 瀏覽器座標系統

座標轉換

  • 因為 <h1> 的外層沒有設定 position,所以它的 offsetParent 一樣會是 <body>,因此 e.target.offsetLeft 指的就是 <h1> 左側到 <body> 左側的距離(h1 <-> body)。
  • 因為 offsetX, offsetY 是 event 的屬性,所以當它進入到 <h1> 時,offsetX 指的是該滑鼠到容器(h1)外層的距離(滑鼠 <-> h1)。
  • 如果要取得++滑鼠相對於 body++ 的座標(滑鼠 <-> body),我們就用 offestX(滑鼠 <-> h1) + e.target.offsetLeft(h1 <-> body
if (this !== e.target) {
// 當 this !== e.target ,意思就是指 e.target === <h1> 的時候

offsetXAfterAdjust = offsetXAfterAdjust + e.target.offsetLeft;
offsetYAfterAdjust = offsetYAfterAdjust + e.target.offsetTop;
}

根據數值改變 textShadow

接著我們要以 text 為中心點,去改變 CSS textShadow 的值。

以 text 為中心點

  • (offsetXAfterAdjust / heroWidth) 可以取得當前滑鼠 X 在 heroWidth 的百分比,此時原點在畫面左上角
  • ((offsetXAfterAdjust / heroWidth) * walk) - (walk / 2 ) 可以讓原點變成在畫面中心
const xWalk = Math.round((offsetXAfterAdjust / heroWidth) * walk) - walk / 2;
const yWalk = Math.round((offsetYAfterAdjust / heroHeight) * walk) - walk / 2;

透過 Element.style.styleName 改變 CSS

textShadow 的屬性如下:

text-shadow: offset-x | offset-y | blur-radius(羽化) | spread-radius(擴張) | color | inset;

利用 element.style.styleName 把 xWalk 和 yWalk 的值代入 Text Shadow 中記得每個單位都要加上 px

text.style.textShadow = `${xWalk}px ${yWalk}px 10px rgba(130, 130, 130, 0.5)`;

JavaScript CSS Manipulation @ PJCHENder Codepen

完成作品

Day16: CSS Text Shadow Mouse Move Effect

參考資料