iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
3

WES BOS系列影片
Alex快速導讀系列影片

今天的練習重點是抓取DOM容器的座標與mousemove事件
我們要做一個文字陰影與滑鼠互動的效果
要做出這個效果,首先必須先清楚容器中的座標距離是如何計算的
需要知道的知識
HTMLElement.offsetWidth: 該DOM元素除去margin的寬度
HTMLElement.offsetHeight: 該DOM元素除去margin的高度
MouseEvent.offsetX: 滑鼠於該元素指向的座標X
MouseEvent.offsetY: 滑鼠於該元素指向的座標Y

以上解釋是個人理解,可能不夠詳細,有錯誤再請指正。

由HTML的結構中,可以看到在<div class="hero">容器中
還有一個<h1 contenteditable>?WOAH!</h1>的容器
在這樣的狀況下,MouseEvent的offsetX與offsetY,將會不同,
我們可以先利用下方的程式碼來看看
首先,先抓取這兩個容器
然後是在父容器中設置監聽器

  const hero = document.querySelector(".hero");
  const text = hero.querySelector("h1");
  
  function addShadow(e) {
    let { offsetX: x, offsetY: y } = e;
    console.log(x, y);
    text.style.textShadow = `${x}px ${y}px 0 rgba(255,0,255,0.7)`;
  }
  
  hero.addEventListener("mousemove", addShadow);

結果發現,MouseEvent的offsetX與offsetY,在hero跟text中,會不相同
滑鼠位於text時offsetX與offsetY會變小,處理這種狀況
就要針對滑鼠位於text時,加上父容器的長寬

  function addShadow(e) {
    let { offsetX: x, offsetY: y } = e;
    console.log(x, y);
    if (this !== e.target) {
      x = x + e.target.offsetLeft;
      y = y + e.target.offsetTop;
    }
    text.style.textShadow = `${x}px ${y}px 0 rgba(255,0,255,0.7)`;
  }
    

現在我們排除了子容器的干擾
接下來就需要設定shadow本身的位置了
假設陰影本身的位置要偏移100px

  const xWalk = Math.round((x / width) * 100 - 100 / 2);
  const yWalk = Math.round((y / height) * 100 - 100 / 2);
  text.style.textShadow = `${xWalk}px ${yWalk}px 0 rgba(255,0,255,0.7)`;

製作四散的陰影

  text.style.textShadow = `
  ${xWalk}px ${yWalk}px 0 rgba(255,0,255,0.7),
  ${xWalk * -1}px ${yWalk}px 0 rgba(0,255,255,0.7),
  ${yWalk}px ${xWalk * -1}px 0 rgba(0,255,0,0.7),
  ${yWalk * -1}px ${xWalk}px 0 rgba(0,0,255,0.7)`;

最後可以將偏移的px值,調整成變數

  const walk = 100;
  const xWalk = Math.round((x / width) * walk - walk / 2);
  const yWalk = Math.round((y / height) * walk - walk / 2);

今天的練習完成囉,完整的程式碼請直接點擊下方codePen連結
codePen
或者也可以直接到WES BOS的網站下載打包好的檔案
javascript30


上一篇
Day22: LocalStorage(二)
下一篇
Day24: Sort Without Articles
系列文
實作經典 JavaScript 3030
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言