See the Pen
顏色測驗 by 喇賽人 (@weber87na)
on CodePen.
今天朋友傳個眼力測驗, 心血來潮就來模擬看看大概怎麼寫, 這次直接在 codepen 用 ts 來寫看看
遇到第一個特別的點就是 2d array 的宣告, 在 js 只要宣告 [] 即可, but ts 就麻煩些, 要寫成 let arr: number[][] = [];
接著把 2d array 塞滿, 這裡先在外層迴圈設定 arr[y] = [] 表示塞入 [[]] , 讓他變成 2d
接著把每個格子寫 0 即可
1 2 3 4 5 6 7 8 9 10 11 12
| let arr: number[][] = [];
function fillArr(arr: number[][]) { for (let y = 0; y < size; y++) { arr[y] = []; for (let x = 0; x < size; x++) { arr[y][x] = 0; } }
return arr; }
|
再來則是取得兩數之間的數, 不過這次看到一個很炫炮的寫法
如果 +1 就可以取得 1 - 16 (size * size) 中的亂數
1 2 3
| function genNum() { return ((Math.random() * (size * size)) | 0) + 1; }
|
接著是亂數取得一格要設定為異色的格子, 這裡練下遞迴
首先看到 inner function 這裡面為遞迴主要邏輯
先將 y 設定為 -1, 每次執行則往前推進, 最後會得到正確的 Y (高度)值
x 則是小於等於 size 則回傳, 否則遞迴每次減去 size, 最後就可以得到答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function genPos() { let y = -1; let n = genNum(); console.log("n:", n); let x = pos(n) - 1;
let reuslt = { x: x, y: y }; console.log("pos:", reuslt); return reuslt;
function pos(num: number) { y++; if (num <= size) return num; else { return pos(num - size); } } }
|
再來比較特別的是如何取得 canvas 與 2d array 的相對位置轉換
首先取得目前 canvas 的滑鼠位置
1 2 3 4 5 6
| function getMousePosition(event: MouseEvent) { const rect = canvas.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; return { x, y }; }
|
接著在點選格子的時候利用 Math.floor(y / cellH) 這樣就可以計算出轉換結果
1 2 3
| const { x, y } = getMousePosition(event); const theY = Math.floor(y / cellH); const theX = Math.floor(x / cellW);
|
最後就是將 hex 轉為 rgb 然後把需要設為異色的做顏色加減, 便可完成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| function hexToRgb(hex: string) { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = 1; canvas.height = 1;
ctx!.fillStyle = hex; ctx!.fillRect(0, 0, 1, 1);
const data = ctx!.getImageData(0, 0, 1, 1).data; const r = data[0]; const g = data[1]; const b = data[2];
const increase = 10 - level * 2; let newR = r + increase; if (newR >= 255) newR = 255;
let newG = g + increase; if (newG >= 255) newG = 255;
let newB = b + increase; if (newB >= 255) newB = 255;
return `rgb(${newR}, ${newG}, ${newB})`; }
|
後來覺得 html 147 色實在太噁心了, 玩不到兩關就 gg, 所以選些比較中間的, 又額外做了這個, 然後挑出比較中間的顏色
See the Pen
Html147色 by 喇賽人 (@weber87na)
on CodePen.