第八天的目標是在畫面上創造一塊畫布,畫布的功能是利用滑鼠點擊及拖曳畫出線條,線條需會變色及放大縮小
Github 檔案位置:08 - Fun with HTML5 Canvas
網頁一開始的樣子如下,就是白的
可以先去看看 最後的成品
將程式的要求拆分步驟後,我們需要做的事情如下
一樣用之前學到的東西加上監聽,再設個 isDrawing
確認是否在螢幕內按下時才會偵測到
const canvas = document.querySelector('#draw');
let isDrawing = false;
canvas.addEventListener('mousedown', function(e){
console.log(e)
isDrawing = true;
})
canvas.addEventListener('mousemove', function(e){
if(!isDrawing) return;
console.log(e);
})
canvas.addEventListener('mouseup', () => isDrawing = false)
canvas.addEventListener('mouseout', () => isDrawing = false)
我們點擊看看
接下來要正式開始畫圖了,canvas 的直線畫圖方式是給起始點和線的終點,再藉由線連起來
由於我們在點擊時才會開始畫圖,可能會在畫布上任意位置開始,因此我們需先在觸發 mousedown
時紀錄 x, y 位置
let drawX = 0, drawY = 0;
canvas.addEventListener('mousedown', function(e){
// console.log(e);
isDrawing = true;
[drawX, drawY] = [e.offsetX, e.offsetY];
})
這邊依序介紹四句函式
ctx.beginPath()
產生畫圖路徑(初始化)ctx.moveTo(x, y)
將畫筆移到目前位置(初始化)ctx.lineTo()
產生線條連接畫筆位置到目標位置(尚未畫)ctx.stroke()
畫實際的線段上去(預設為黑色)[drawX, drawY] = [e.offsetX, e.offsetY]
重新設定滑鼠所在的 (x, y)
值canvas.addEventListener('mousemove', function(e){
if(!isDrawing) return;
// console.log(e);
ctx.beginPath();
ctx.moveTo(drawX, drawY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[drawX, drawY] = [e.offsetX, e.offsetY];
})
到這裡我們就可以在頁面上畫圖了
接下來我們要設定畫筆的各種屬性
一樣依序介紹四項屬性
ctx.strokeStyle = '#BADA55';
指定畫筆的顏色ctx.lineJoin = 'round';
使線條的轉角為圓形ctx.lineCap = 'round';
使畫筆的筆尖為圓形ctx.lineWidth = 50;
指定畫筆的粗細ctx.strokeStyle = '#BADA55';
ctx.lineJoin = 'round'; // 轉角為圓形
ctx.lineCap = 'round'; // 畫筆為圓形
ctx.lineWidth = 50;
我們就可以看到畫筆被賦上的屬性帶來的影響
接下來我們希望畫筆有更多的特效,所以利用簡單的方式讓畫筆放大縮小再放大,並且會隨著 hsl 色盤而變換顏色
let lineWidth = -100;
let colorDeg = 0;
canvas.addEventListener('mousemove', function(e){
if(!isDrawing) return;
// console.log(e);
ctx.lineWidth = Math.abs(lineWidth);
ctx.strokeStyle = `hsl(${colorDeg}, 100%, 50%)`;
ctx.beginPath();
ctx.moveTo(drawX, drawY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[drawX, drawY] = [e.offsetX, e.offsetY];
lineWidth < 100 ? lineWidth += 1.5 : lineWidth = -100;
colorDeg < 360 ? colorDeg += 1 : colorDeg = 0;
})
const canvas = document.querySelector('#draw');
const ctx = canvas.getContext('2d');
ctx.strokeStyle = '#BADA55';
ctx.lineJoin = 'round'; // 轉角為圓形
ctx.lineCap = 'round'; // 畫筆為圓形
let isDrawing = false;
let drawX = 0;
let drawY = 0;
let lineWidth = -100;
let colorDeg = 0;
canvas.addEventListener('mousedown', function(e){
// console.log(e);
isDrawing = true;
[drawX, drawY] = [e.offsetX, e.offsetY];
})
canvas.addEventListener('mousemove', function(e){
if(!isDrawing) return;
// console.log(e);
ctx.lineWidth = Math.abs(lineWidth);
ctx.strokeStyle = `hsl(${colorDeg}, 100%, 50%)`;
ctx.beginPath();
ctx.moveTo(drawX, drawY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[drawX, drawY] = [e.offsetX, e.offsetY];
lineWidth < 100 ? lineWidth += 1.5 : lineWidth = -100;
colorDeg < 360 ? colorDeg += 1 : colorDeg = 0;
})
canvas.addEventListener('mouseup', () => isDrawing = false)
canvas.addEventListener('mouseout', () => isDrawing = false)
以上是第八天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<
Let's build something fun with HTML5 Canvas - #JavaScript30 8/30
[ Alex 宅幹嘛 ] 深入淺出 Javascript30 快速導覽 | Day 8:Fun with HTML5 Canvas
MDN Web Docs