今日任務: 跟著滑鼠位移大小,產生不同大小的陰影
為了知道位移大小,先取得滑鼠位置
offsetWidth、offsetHeight: 「元素本身」的寬度/高度,並完整了包含了邊界、捲軸及padding。
取得hero的寬高
const hero = document.querySelector('.hero');
const width = hero.offsetWidth;
const height = hero.offsetHeight;
詳細說明可以看這邊
前面程式可以簡寫成:
const hero = document.querySelector('.hero');
const { offsetWidth: width, offsetHeight: height } = hero;
offsetX
、offsetY
: 指滑鼠到外層容器的距離
滑鼠在文字外的時候,位置為(e.offsetX, e.offsetY)
(滑鼠到外層容器的距離)
點擊綠色位置會是(0,0)
點擊紫色位置會是(342,360)
在文字h1內的時候
點擊藍色位置又會是(0,0)
Day13時,有學過offsetLeft/offsetTop
: 元素本身相對於母元素的水平/垂直距離。
在今天的例子中,e.target是滑鼠所在位置的元素(可能是hero或h1),this則是監聽對象hero
當滑鼠點到hero(h1外的範圍),滑鼠位置為
(e.offsetX
, e.offsetY
)
當滑鼠點到h1時,滑鼠位置為
(e.offsetX + e.target.offsetLeft
, e.offsetY + e.target.offsetTop
)
const hero = document.querySelector('.hero');
const text = document.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;
}
}
所以陰影應該要多少呢,這邊設300(越大陰影就越遠)
const walk = 300; //300px
(x / width)為滑鼠x位移大小
相對於hero寬度
的百分比
(y / height)為滑鼠y位移大小
相對於hero高度
的百分比
再乘上walk,得到陰影位移大小
原點在左上角(0,0),想改以畫面中心為原點,所以要/2
本來陰影位移是0到100,變成-50到50(正負座標都能移動)
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 = (x / width) * walk - walk / 2;
const YWalk = (y / height) * walk - walk / 2;
console.log(XWalk, YWalk);
}
數值太長
Math.round()
會回傳四捨五入後的整數
const XWalk = Math.round((x / width) * walk - walk / 2);
const YWalk = Math.round((y / height) * walk - walk / 2);
將數值放上陰影css
text.style.textShadow = `${XWalk}px ${YWalk}px 0 red`;
加上更多陰影與顏色
text.style.textShadow =
`${XWalk}px ${YWalk}px 0 red,
${XWalk * -1}px ${YWalk * -1}px 0 green,
${YWalk}px ${XWalk}px 0 blue,
${YWalk * -1}px ${XWalk * -1}px 0 pink`;
完整原始碼
const hero = document.querySelector('.hero');
const text = document.querySelector('h1');
const walk = 300; //300px
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 red,
${XWalk * -1}px ${YWalk * -1}px 0 green,
${YWalk}px ${XWalk}px 0 blue,
${YWalk * -1}px ${XWalk * -1}px 0 pink`;
}
今日學習到的:
offsetWidth
/ offsetHeight
: 「元素本身」的寬度/高度,並完整了包含了邊界、捲軸及paddingoffsetX
/ offsetY
: 指到外層容器的距離offsetLeft
/ offsetTop
: 元素本身相對於母元素的水平/垂直距離。e.target
: 觸發事件的元素this
: 被監聽的對象本身,也就是 element.addEventListener() 的 elementMath.round()
會回傳四捨五入後的整數效果連結:連結
參考連結:
pjchender:JavaScript ES6 中的物件解構賦值(object destructuring)
什麼是 clientHeight, clientWidth, offSetHeight, offsetWidth, scrollHeight, scrollWidth, scrollTop, scrollLeft
pjchender: this 和 e.target 在 eventHandler 中的差異