iT邦幫忙

第 12 屆 iThome 鐵人賽

0
自我挑戰組

前端新手的學習筆記系列 第 31

Day31 - JS30 - 16 - Mouse Move Shadow

  • 分享至 

  • xImage
  •  

參考資料:
Alex老師教學
pjchender筆記
JS30-Day16-Mouse Move Shadow
鐵人賽30天結束後偷懶了幾天才繼續來練習。


隨滑鼠移動的陰影。


抓取節點並做出監聽

const hero = document.querySelector('.hero');
hero.addEventListener('mousemove', shadow);

開始製作內容

let shadow = e => {
        console.log(e);
    };

用滑鼠滑一下可以看到:(框內是要使用的屬性)
https://ithelp.ithome.com.tw/upload/images/20201019/20121534CdMoLrvWTT.png

要使用e.offsetX和e.offsetY,有以下幾種作法

let shadow = e => {
        // console.log(e);

        // 傳統作法
        let x = e.offsetX;
        let y = e.offsetY;

        // 比較新的作法 - 把offsetX, offsetY拆出來
        let { offsetX, offsetY } = e;

        // 更加新的作法- 把offsetX, offsetY拆出來後命名成x,y
        let { offsetX: x, offsetY: y } = e;
    };

看左上角接近(0,0)和右下角接近(1,1)的數值

			console.log(
            offsetX / this.offsetWidth, 
            offsetY / this.offsetHeight
            );

但這時會發現只要滑到文字上,數值就會不正確,因為是另一個座標,必須手動把距離加回去

// 觸發的座標不是hero而是內層,就補回距離
        if (e.target !== this) {
            offsetX += e.target.offsetLeft;
            offsetY += e.target.offsetTop;
        }

開始製作陰影

const text = document.querySelector('h1'); //要做出陰影的節點
 let moveLength = 100; //陰影移動距離

移動座標

let moveX = Math.floor((offsetX / this.offsetWidth) * moveLength);
let moveY = Math.floor((offsetY / this.offsetHeight) * moveLength);
 // 整數化,無條件捨去

紅色陰影*1

			text.style.textShadow=`
        ${moveX}px ${moveY}px 3px rgba(255,0,0,0.8)
        `

綠色陰影,出現位置在滑鼠反方向

text.style.textShadow = `
        ${moveX*-1}px ${moveY*-1}px 3px rgba(0,255,0,0.8)
        `;

修改陰影數據,使滑鼠滑到反方向也可以呈現

let moveX = Math.floor((offsetX / this.offsetWidth) * moveLength) * 2 - moveLength;
let moveY = Math.floor((offsetY / this.offsetHeight) * moveLength) * 2 - moveLength;
// 整數化,無條件捨去

陰影效果

			text.style.textShadow = `
        ${moveX}px ${moveY}px 1px rgba(255,0,0,0.8),
        ${moveX * -1}px ${moveY * -1}px 2px rgba(0,255,0,0.8),
        ${moveX}px ${moveY * -1}px 3px rgba(0,0,255,0.8),
        ${moveX * -1}px ${moveY}px 4px rgba(200,255,255,0.8)
        `;

視差效果

	text.style.textShadow = `
        ${moveX*-0.3}px ${moveY*-0.3}px 1px rgba(255,0,0,0.8),
        ${moveX * -1}px ${moveY * -1}px 2px rgba(0,255,0,0.8),
        ${moveX*-0.6}px ${moveY * -0.6}px 3px rgba(0,0,255,0.8)
        `;

改成箭頭函式

(function () {
    const hero = document.querySelector('.hero'); //陰影移動的範圍
    const text = document.querySelector('h1'); //要做出陰影的節點
    let moveLength = 100; //陰影移動距離

    let shadow = e => {
        // function shadow(e) {
        // 拆出滑鼠移動的座標
        // 傳統作法
        // let x = e.offsetX;
        // let y = e.offsetY;

        // 比較新的作法 - 把offsetX, offsetY拆出來
        // let { offsetX, offsetY } = e;
        let { offsetX, offsetY, target, currentTarget } = e;

        // 更加新的作法 - 把offsetX, offsetY拆出來後命名成x,y
        // let { offsetX: x, offsetY: y } = e;

        // console.log(e.target.offsetLeft);
        // console.log(e.target.offsetTop);

        // 觸發的座標不是hero而是內層,就補回距離
        // if (e.target !== this) {
        // 如果用箭頭函式,此處this可以換成e.currentTarget
        if (target !== currentTarget) {
            offsetX += target.offsetLeft;
            offsetY += target.offsetTop;
        }

        // let moveX = Math.floor((offsetX / this.offsetWidth) * moveLength) * 2 - moveLength;
        // let moveY = Math.floor((offsetY / this.offsetHeight) * moveLength) * 2 - moveLength;
        let moveX = Math.floor((offsetX / currentTarget.offsetWidth) * moveLength)  * 2 - moveLength;
        let moveY = Math.floor((offsetY / currentTarget.offsetHeight) * moveLength)  * 2 - moveLength;
        // 整數化,無條件捨去

        // text.style.textShadow = `
        // ${moveX}px ${moveY}px 1px rgba(255,0,0,0.8),
        // ${moveX * -0.5}px ${moveY * -2}px 2px rgba(0,255,0,0.8),
        // ${moveX*-0.3}px ${moveY * -0.6}px 3px rgba(0,0,255,0.8),
        // ${moveX * -1.5}px ${moveY*-0.3}px 4px rgba(200,255,255,0.8)
        // `;
        text.style.textShadow = `
        ${moveX * -0.3}px ${moveY * -0.3}px 1px rgba(255,0,0,0.8),
        ${moveX * -1}px ${moveY * -1}px 2px rgba(0,255,0,0.8),
        ${moveX * -0.6}px ${moveY * -0.6}px 3px rgba(0,0,255,0.8)
        `;
    };

    hero.addEventListener('mousemove', shadow);
})();

連結


上一篇
Day30:每天一個小練習 - JS30-15-LocalStorage
下一篇
Day32 - JS30 - 17 - Sort Without Articles
系列文
前端新手的學習筆記32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言