---
# System prepended metadata

title: '[JS30] Day.16 CSS Text Shadow Mouse Move Effect'
tags: [JS30]

---

# [JS30] Day.16 CSS Text Shadow Mouse Move Effect
###### tags: `JS30`
## 任務 Task
當滑鼠移動畫面時，文字產生陰影並向滑鼠距離文字的方向做固定距離的移動。

==完成時間：30min==
## 步驟 Step
1. 監聽父層的 `MouseEvent` ，取得父層的長寬，及滑鼠的位置 `offsetX` `offsetY`
2. 因為滑鼠移動到子層時， `offsetX` `offsetY` 會根據子層去重設相對位置，所以要加回子層相對於`X``Y`的距離。
```javascript=
if (this !== e.target){
    x = x + e.target.offsetLeft;
    y = y + e.target.offsetTop;
}
```
3. 計算滑鼠位置相對於整個長度的百分比，並乘以指定的 `walk` 數值，再扣掉一半的 `walk` 值。
    假設： `walk = 100`  乘以百分比後得出的數值介於 `0~100` 再扣掉 `walk` 的一半後，數值介於 `-50~50`。
5. 更改 `text.style.textShadow` 就會根據滑鼠位置移動，產生位移（最大為 `walk/2`)　值的陰影效果。
## 筆記 Note
### <font color=#337EA9>HTML contenteditable</font>
* 是一種全域屬性（attribute），可讓使用者做文字的編輯。
* 很少用，因為會根據使用者產生很多不同的結果，較不受控。
### <font color=#337EA9>CSS text shadow</font>
* 產生文字的陰影。
* 語法：`text-shadow: offset-x | offset-y | blur-radius |　color`
* 比較：`box-shadow: offset-x | offset-y | blur-radius | spread-radius | color`
### <font color=#337EA9>JS Destructuring assignment（解構指定值）</font>
>MDN：The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
* 在 `react` `redux` 非常常見，是一個必學的語法，可以使程式碼更簡短並提高閱讀性。
* 當對應位置沒有值時，指定為 `undefined`。
* `Array` 語法：
```javascript=
const [a, b] = array;
const [a, , b] = array;
const [a = aDefault, b] = array;
const [a, b, ...rest] = array;
const [a, , b, ...rest] = array;
const [a, b, ...{ pop, push }] = array;
const [a, b, ...[c, d]] = array;
```
* `Object` 語法：
```javascript=
const { a, b } = obj;
const { a: a1, b: b1 } = obj;
const { a: a1 = aDefault, b = bDefault } = obj;
const { a, b, ...rest } = obj;
const { a: a1, b: b1, ...rest } = obj;
```
### <font color=#337EA9></font>
## 遇到問題 Problem
:::danger
⚠️ <font color=black>Problem</font>
:::
外擴的最大距離為 `walk` 的一半，有點不直覺。
:::info
:ok_hand: <font color=black>Revise</font>
:::
改成 `(x / width) * walk * 2 -walk`
```javascript=
const xWalk = Math.round((x / width) * walk * 2 - walk);
const yWalk = Math.round((y / height) * walk * 2 - walk);
```
這樣 `xWalk` 、 `yWalk` 的範圍就變成 `(-walk)~(walk)`，感覺比較直覺。
