俗話說的好,一天一蘋果,醫生遠離我
一天一 JS,What the f*ck JavaScript?
small steps every day - 記錄著新手村日記
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 Canvas</title>
</head>
<body>
<canvas id="draw" width="800" height="800"></canvas>
<script>
</script>
<style>
html, body {
margin: 0;
}
</style>
</body>
</html>
首先,這次的範例只是Canvas的基本、滑鼠的操作,如果很喜歡 Canvas 的人,歡迎來我的 Codepen 看更多範例
繪圖基礎語法與動畫原理:https://tinyurl.com/yxftfxoz
畫布的座標系操作:https://tinyurl.com/y4s8fxjr
從事件的角度,先來寫使用者的觸發事件吧!分別是 mousedown
、mousemove
、mouseup
、mouseleave
四種事件,記得 mousemove
這個事件是會一直觸發,使用者在脫離 Canvas 這個 800x800 畫布的時候,也會觸發脫離框框事件,分別有兩種作法:一個是 mouseout
、mouseleave
,而兩者的差別在 DOM 的層級。
另外,因為要使用者按下去才能畫,因此在 mousemove
方法中,我們要假設如果狀態不能畫畫的 if(!drawing) return
,就不能畫畫
mouveseout v.s mouse leave:https://tinyurl.com/y282qc3g
<script>
const canvas = document.querySelector("#draw");
let drawing = false;
canvas.addEventListener("mousedown",()=> {
drawing = true;
})
canvas.addEventListener("mousemove",()=> {
if(!drawing) return;
console.log("move"); // 假設console視為畫畫
})
canvas.addEventListener("mouseup",()=> {
drawing = false;
})
canvas.addEventListener("mouseleave",()=> {
drawing = false;
})
</script>
透過 CanvasRenderingContext2D
來操作 Canvas 的 Context,記得不是操作它的 DOM!處理一下要畫畫線條的顏色 ctx.fillStyle
,它是透過HSL 色環來計算顏色 "hsl(0,100%,50%)"
,各欄位分別意思是(顏色、飽和度、明亮度)、調整筆畫粗細 linewidth
、筆畫收尾的形狀 lineCap
、轉折角 lineJoin
CanvasRenderingContext2D:https://tinyurl.com/y39wgnms
CanvasRenderingContext2D.fillStyle:https://tinyurl.com/y5j8zu5g
CanvasRenderingContext2D.lineWidth:https://tinyurl.com/q3pm3aw
CanvasRenderingContext2D.lineCap:https://tinyurl.com/y63rq9rf
CanvasRenderingContext2D.lineJoin:https://tinyurl.com/yxesyrbw
<script>
let ctx = canvas.getContext('2d');
ctx.strokeStyle = `hsl(0,100%,50%)`;
ctx.lineWidth = 100;
ctx.lineCap = 'round';
// 下略
</script>
現在來製作畫畫吧!(點對點的概念,按下去會是一個點,然後會連到結束時候的點成為一條線),必須將按下時的點及結束的點存起來,透過 x、y 變數存下 offsetX、offsetY
MouseEvent.offsetX:https://tinyurl.com/phhseue
MouseEvent.offsetY:https://tinyurl.com/yys9e773
<script>
const canvas = document.querySelector("#draw");
let ctx = canvas.getContext('2d');
ctx.strokeStyle = `hsl(0,100%,50%)`;
ctx.lineWidth = 50;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
let x = 0;
let y = 0;
let drawing = false;
canvas.addEventListener("mousedown",(e)=> {
drawing = true;
[x,y] = [e.offsetX, e.offsetY];
})
canvas.addEventListener("mousemove",()=> {
if(!drawing) return;
console.log("move");
})
canvas.addEventListener("mouseup",()=> {
drawing = false;
})
canvas.addEventListener("mouseleave",()=> {
drawing = false;
})
</script>
畫製 Canvas 圖的規則滿前顯易懂的,可以參考下面的範例連結(切記在製作Canvas的時候程式結束一定要有分號,不然都會出錯喔!)
CanvasRenderingContext2D.beginPath():https://tinyurl.com/ycrkznet
<script>
const canvas = document.querySelector("#draw");
let ctx = canvas.getContext('2d');
ctx.strokeStyle = `hsl(0,100%,50%)`;
ctx.lineWidth = 50;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
let drawing = false
let x = 0, y = 0;
canvas.addEventListener("mousedown",(e)=> {
drawing = true;
[x, y] = [e.offsetX, e.offsetY];
})
canvas.addEventListener("mousemove",(e)=> {
if(!drawing) return;
console.log("move");
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[x, y] = [e.offsetX, e.offsetY];
})
canvas.addEventListener("mouseup",()=> {
drawing = false;
})
canvas.addEventListener("mouseleave",()=> {
drawing = false;
})
</script>
讓顏色會隨著紅橙黃綠藍靛紫 & 粗細會持續變化:
<script>
const canvas = document.querySelector("#draw");
let ctx = canvas.getContext('2d');
colorDeg = 0;
lineWidth = 50;
dir = 1;
ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
ctx.lineWidth = lineWidth;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
let drawing = false
let x = 0, y = 0;
canvas.addEventListener("mousedown",(e)=> {
drawing = true;
[x, y] = [e.offsetX, e.offsetY];
})
canvas.addEventListener("mousemove",(e)=> {
if(!drawing) return;
console.log("move");
ctx.beginPath();
// 讓角度持續的在 0-360 變化
colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;
ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
// 從大到變小 再到變大
if (lineWidth < 1 || lineWidth > 50) {
dir *= -1;
}
lineWidth -= dir ;
ctx.lineWidth = lineWidth;
ctx.moveTo(x, y);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[x, y] = [e.offsetX, e.offsetY];
})
canvas.addEventListener("mouseup",()=> {
drawing = false;
})
canvas.addEventListener("mouseleave",()=> {
drawing = false;
})
</script>
就大功告成啦!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 Canvas</title>
</head>
<body>
<canvas id="draw" width="800" height="800"></canvas>
<script>
const canvas = document.querySelector("#draw");
let ctx = canvas.getContext('2d');
colorDeg = 0;
lineWidth = 50;
dir = 1;
ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
ctx.lineWidth = lineWidth;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
let drawing = false
let x = 0, y = 0;
canvas.addEventListener("mousedown",(e)=> {
drawing = true;
[x, y] = [e.offsetX, e.offsetY];
})
canvas.addEventListener("mousemove",(e)=> {
if(!drawing) return;
console.log("move");
ctx.beginPath();
colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;
ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
if (lineWidth < 1 || lineWidth > 50) {
dir *= -1;
}
lineWidth -= dir ;
ctx.lineWidth = lineWidth;
ctx.moveTo(x, y);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[x, y] = [e.offsetX, e.offsetY];
})
canvas.addEventListener("mouseup",()=> {
drawing = false;
})
canvas.addEventListener("mouseleave",()=> {
drawing = false;
})
</script>
<style>
html, body {
margin: 0;
}
canvas{
border: 1px solid #000;
}
</style>
</body>
</html>
本刊同步於個人網站:http://chestertang.site/
本次範例程式碼原作者來源:https://tinyurl.com/yxhsxcnl