選取器使用到 getImageData
ctx.getImageData(sx, sy, sw, sh);
利用 getImageData 可以得到指定範圍內的數值
可以看到在 data 內的值即為色碼,我們只需將它拼裝成 rgba 就完成了!
在上一篇章用鉛筆繪畫時,mouseMove會回傳給我們const point = { x: e.offsetX, y: e.offsetY }
但在做選取範圍時,我們操作的判斷,是做在 點擊 事件,
並沒有直接回傳 offsetX 回來,所以我們需要自己進行計算,
利用 element的 位置與滑鼠所點擊得 clientX 來計算。
來看看程式碼吧
/**
* 提取顏色
*/
const pickColor = (e: any) => {
let rect = canvasRef.current.getBoundingClientRect();
const point = {
x: e.clientX - rect.left,
y: e.clientY - rect.top,
};
if (canvasRef.current) {
const ctx = canvasRef.current.getContext("2d");
const p = ctx.getImageData(point?.x, point?.y, 1, 1).data;
const color = `rgba(${p[0]}, ${p[1]}, ${p[2]}, ${p[3]})`;
setActiveColor(color);
}
};
我們也對上一篇的點擊滑鼠進行修改
// 滑鼠點下畫布
const handleMouseDown = (event: any) => {
setIsDrawing(true);
switch (tool) {
case "fillColor":
fillCanvas();
break;
case "pickColor":
pickColor(event);
break;
default:
break;
}
};
在上週我們建立的 toolsMap.json 做些修改
toolsMap.js
import airbrush from "../images/cursors/airbrush.png";
import eyeDropper from "../images/cursors/eye-dropper.png";
import fillBucket from "../images/cursors/fill-bucket.png";
import precise from "../images/cursors/precise.png";
import pencil from "../images/cursors/pencil.png";
import preciseDotted from "../images/cursors/precise-dotted.png";
import magnifier from "../images/cursors/magnifier.png";
const toolsMap = [
{ name: "freeFormSelec", title: "選擇任意範圍", cursor: precise },
{ name: "selec", title: "選擇", cursor: precise },
{ name: "eraser", title: "橡皮擦/彩色橡皮擦", cursor: precise },
{ name: "fillColor", title: "填入色彩", cursor: fillBucket },
{ name: "pickColor", title: "挑選顏色", cursor: eyeDropper },
{ name: "magnifier", title: "放大鏡", cursor: magnifier },
{ name: "pencil", title: "鉛筆", cursor: pencil },
{ name: "brush", title: "粉刷", cursor: preciseDotted },
{ name: "airbrush", title: "噴槍", cursor: airbrush },
{ name: "text", title: "文字", cursor: precise },
{ name: "line", title: "直線", cursor: precise },
{ name: "curve", title: "曲線", cursor: precise },
{ name: "rectangle", title: "矩形", cursor: precise },
{ name: "polygon", title: "多邊形", cursor: precise },
{ name: "ellipse", title: "橢圓形", cursor: precise },
{ name: "roundedRectangle", title: "圓角矩形", cursor: precise },
];
export default toolsMap;
利用 cursor 可以在畫布上指定對的游標圖案
CanvasBox/index.tsx
...more
<MainCanvas
...
cursor={tool}
></MainCanvas>
CanvasBox/style.tsx
import find from "lodash/find";
...
const MainCanvas = styled("canvas")<{ cursor: any }>`
background: #fff;
cursor: ${(props: { cursor: string }) => {
const active = find(toolsMap, { name: props?.cursor });
return `url(${active?.cursor}) 9 22, crosshair`;
}};
`;
Done!
明天教學如何繪製線條~!