接續昨天做的『文字換行』,今天利用上一篇的操作來做一個應用,
這次的應用靈感是從這個網站來的,滑到最下方,有一個填上文字、修改位置與大小,就可以下載成為賀卡的功能,偷看了一下他的程式碼是用 jQuery 完成的,這邊我用 React 帶大家試試看!
首先我們將觀察到的材料準備好
需要一個主要的 canvas 以及幾個控制項
const canvasRef = useRef(null);
const [style, setStyle] = useState({ size: 14, top: 10, left: 10 });
const [text, setText] = useState("");
const [image, setImage] = useState(new Image());
return <div>
<canvas ref={canvasRef}></canvas>
<div className="mt-8 max-w-xl mx-auto px-8">
請輸入文字
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
</div>
<div>
左右
<input
type="range"
value={style?.left}
onChange={(e) => updateStyle(e, "left")}
/>
</div>
<div>
上下
<input
type="range"
value={style?.top}
onChange={(e) => updateStyle(e, "top")}
/>
</div>
<div>
大小
<input
type="range"
value={style?.size}
onChange={(e) => updateStyle(e, "size")}
/>
</div>
<button onClick={download}>下載</button>
</div>
再來就是依據不同的控制項作出不同的處理
/** 放上背景圖 **/
useEffect(() => {
if (canvasRef.current) {
const drawImage = () => {
const base_image = new Image();
base_image.setAttribute("crossorigin", "anonymous");
base_image.src = exampleImg;
base_image.onload = () => {
setImage(base_image);
};
};
drawImage();
}
}, [canvasRef]);
/** 依照不同的控制項目對文字做改變 **/
useEffect(() => {
const drawText = async () => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.fillStyle = "#FFF";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
ctx.font = `bold ${style?.size}px Arial`;
ctx.strokeStyle = "white";
ctx.lineWidth = 3;
ctx.fillStyle = "black";
ctx.fillText(text, style?.left, style?.top);
};
drawText();
}, [text, style, image]);
const updateStyle = (e, key) => {
setStyle((prev) => ({ ...prev, [key]: e.target.value }));
};
這裡有一個很重要需要注意的地方!
在改變控制項的時候
需要隨時清掉畫面,如果不將畫面清掉,就會反覆在畫布上增加文字,造成畫面混亂
所以ctx.fillRect(0, 0, canvas.width, canvas.height);
這個是必要得存在!
再來重複複習昨天的換行功能,
將上方的 fillText
改為 canvasTextAutoLine(text, canvas, style?.left, style?.top, style?.size);
也可以將 textarea 內的 \n
作為判斷條件來達成文字換行。
今天的電子賀卡就完成啦~
也可以像上面的範例一樣,增加選擇圖片或是文字顏色來增加賀卡的豐富度~
查看完成程式碼 codesendbox