# JS30 Day16 ## CSS Text Shadow Mouse Move Effect ###### tags: `JS 30` by Angelina --- ### 主題:我要成為忍者哈特利 --- ### 忍術影分身之術 [逆逆逆逆逆逆](https://dustinhsiao21.github.io/Javascript30-dustin/16%20-%20Mouse%20Move%20Shadow/) --- ### 第一步 忍術無限輸出術 --- ```javascript= const hero = document.querySelector('.hero') const text = hero.querySelector('h1') hero.addEventListener('mousemove', shadow) function shadow(e) { console.log(e) } ``` --- 宣告 -> 監聽 -> 執行函式 --- ### 第二步 忍術監視術 嘿嘿嘿 --- ```javascript= const hero = document.querySelector('.hero') const text = hero.querySelector('h1') hero.addEventListener('mousemove', shadow) function shadow(e) { const width = hero.offsetWidth const height = hero.offsetHeight console.log(width, height) console.log('e =>', e.offsetX, e.offsetY) } ``` --- 定義關注的參數 hero.offsetWidth & hero.offsetHeight 顯示 hero 原本的寬高 (不會因為滑鼠修正) e.offsetX & e.offsetY 才會是滑鼠移動時的位置 --- ### 第三步 可惡,一定又是煙捲搞的鬼 --- ```javascript= const hero = document.querySelector('.hero') const text = hero.querySelector('h1') hero.addEventListener('mousemove', shadow) function shadow(e) { const { offsetWidth: width, offsetHeight: height } = hero let { offsetX: x, offsetY: y } = e console.log(x, y) } ``` --- ES6 的語法簡化 問題發生 滑鼠碰到 hero 時,會只計算該元素內的座標,移出元素範圍時,又恢復正常 --- ### 第四步 普通的忍者,是絕對想不到這個妙計的 --- ```javascript= const hero = document.querySelector('.hero') const text = hero.querySelector('h1') hero.addEventListener('mousemove', shadow) 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; } console.log(this, e.target) console.log(x, y) } ``` --- 若 DOM element 被事件綁定 this 代表的是該 Dom element e.target 被觸發的那個 Dom element --- 當事件綁在父元素上,觸發到子元素時 this => 回傳父元素 e.target => 回傳子元件 --- 解決問題 計算 hero 內的座標時 加上 e.target.offsetLeft & e.target.offsetTop --- 補充資源:[圖解offsetLeft、offsetTop、offsetWidth和offsetHeight](https://emn178.pixnet.net/blog/post/95297028) --- ### 第五步 忍術座標術 --- ```javascript= const hero = document.querySelector('.hero') const text = hero.querySelector('h1') const walk = 100 hero.addEventListener('mousemove', shadow) 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)) console.log("x = " + x + " width = " + width) console.log(xWalk) } ``` --- 處理動畫顯示距離 =>宣告動畫顯示的基準點 以 const walk = 100 為例 Math.round((實際的位置/全部的長度)*100 - (100 / 2)) => Math.round 四捨五入 => 中心點為(0.0) => 左上及右下分別為(-50, -50)及(50,50) --- ### 第六步 伊賀忍術飛影術 --- ```javascript= const hero = document.querySelector('.hero') const text = hero.querySelector('h1') const walk = 100 hero.addEventListener('mousemove', shadow) 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 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) ` } ``` --- 顯示動畫 調自己最尬以的顏色 --- ### 參考資料 1. [JS30-Day16-Mouse Move Shadow](https://ithelp.ithome.com.tw/articles/10195564) 2. [Mouse Move Shadow](https://github.com/dustinhsiao21/Javascript30-dustin/tree/master/16%20-%20Mouse%20Move%20Shadow) --- 你以為成為忍者有這麼簡單? --- 忍者初階班測驗 開始 --- 當事件綁在父元素上,觸發到子元素時 this 回傳什麼? --- e.target 又回傳什麼? --- 下列哪個忍術,剛剛都沒出現過? 忍術影分身之術 忍術胡說八道術 伊賀忍術飛影術 --- 初級忍術班 考試通過 # PASS PASS PASS --- 請隨時關注 # 安安忍者教室 --- 教你一步一步成為 # 宇宙第一天下無敵武功蓋世哈哈忍者至尊教父!!! --- 忍術胡說八道術 下台一鞠躬
{"metaMigratedAt":"2023-06-16T04:51:50.391Z","metaMigratedFrom":"Content","title":"JS30 Day16","breaks":true,"contributors":"[{\"id\":\"e66977c1-c757-4957-8123-cd26044bbbba\",\"add\":4242,\"del\":150}]"}
    571 views