Anthony Chao

JS30 day16 Text Shadow Mouse Move Effect

#Javascript

JS30 day16 - JS30 day16 Text Shadow Mouse Move Effect

作業內容

今天教學的內容是根據滑鼠的移動來讓文字的陰影跟著移動,在這裡面我目前認為還有很難發現的雷 (this 跟 e.target 不同),整體而言我覺得效果滿酷的! 可以看看這個CodePen

學到什麼

  • JS

    1. ES6 語法糖:
    const width = hero.offsetWidth
    const height = hero.offsetHeight
    // ES6 語法上面兩行可以變成下面這樣
    const { offsetWidth: width, offsetHeight: height } = hero
    1. 一開始的 JS 長這樣:
    const hero = document.querySelector('.hero')
    const text = document.querySelector('h1')
    
    function shadow(e){
      const { offsetWidth: width, offsetHeight: height } = hero
      let { offsetX: x, offsetY: y } = e
      console.log(x,y)
    }
    
    hero.addEventListener('mousemove', shadow)

    奇怪的是這時候如果把滑鼠移到 h1 左上方,座標會接近 0 這是因為這時候我們的 event taget 是 h1 而不是 hero!

    console.log(this, e.target)
    function shadow(e){
      console.log(this, e.target) // 如果在 h1 上面的話,this 仍然是 hero,但 e.target 是 h1
    }

    因此方法要改寫成

    function shadow(e){
      const { offsetWidth: width, offsetHeight: height } = hero
      let { offsetX: x, offsetY: y } = e
      if(this !== e.target){
        x = x + e.target.offsetLeft
        y = y + e.target.offsetTop
      }
    }

    這樣寫的話,如果 target 變成 h1 就會加上 h1 左上角的 x 跟 y 座標,達到統一效果

參考資料: https://github.com/wesbos/JavaScript30

code 內容:

HTML:

<div class="hero">
  <h1 contenteditable>🔥WOAH!</h1>
</div>

CSS:

html {
  color: black;
  font-family: sans-serif;
}

body {
  margin: 0;
}

.hero {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  color: black;
}

h1 {
  text-shadow: 10px 10px 0 rgba(0,0,0,1);
  font-size: 100px;
}

JS:

const hero = document.querySelector('.hero')
const text = document.querySelector('h1')
const walk = 100; //100px

function shadow(e){
  const { offsetWidth: width, offsetHeight: height } = hero
  let { offsetX: x, offsetY: y } = e

  if(this !== e.target){
    x = x + e.target.offsetLeft
    y = y + e.target.offsetTop
  }
  
  const xWalk = Math.round((x / width * walk) - (walk / 2))
  const yWalk = Math.round((y / height * walk) - (walk / 2))
  
  text.style.textShadow = `${xWalk}px ${yWalk}px 0 red`
}

hero.addEventListener('mousemove', shadow)