做者:©liyuechun
簡介:JavaScript30 是 Wes Bos 推出的一個 30 天挑戰。項目免費提供了 30 個視頻教程、30 個挑戰的起始文檔和 30 個挑戰解決方案源代碼。目的是幫助人們用純 JavaScript 來寫東西,不借助框架和庫,也不使用編譯器和引用。如今你看到的是這系列指南的第 8 篇。完整中文版指南及視頻教程在 從零到壹全棧部落。javascript
用 HTML5 中的 Canvas 的路徑繪製實現一個繪畫板,可供鼠標畫畫,顏色呈彩虹色漸變,畫筆大小一樣呈漸變效果。這部分不涉及 CSS 內容,所有由 JS 來實現。css
Canvas:html
模板骨架java
基本屬性git
getContext()
github
strokeStyle
編程
fillStyle
canvas
fillRect
瀏覽器
lineCap
微信
lineJoin
路徑繪製
beginPath()
lineTo()
moveTo()
鼠標事件處理:
mousemove
mousedown
mouseup
mouseout
獲取 HTML 中的 <canvas>
元素,並設定寬度和高度
.getContext('2d')
獲取上下文,下面以 ctx 表示
設定 ctx 基本屬性
描邊和線條顏色
線條寬度
線條末端形狀
繪畫效果
設定一個用於標記繪畫狀態的變量
鼠標事件監聽,不一樣類型的事件將標記變量設爲不一樣值
編寫發生繪製時觸發的函數,設定繪製路徑起點、終點
線條彩虹漸變效果(運用 hsl 的 h
值的變化,累加)
線條粗細漸變效果(設定一個範圍,當超出這個範圍時,線條粗細進行逆向改變
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>HTML5 Canvas 實現彩虹畫筆繪畫板</title> <script type="text/javascript"> function draw() { var canvas = document.getElementById('tutorial'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); } } </script> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body> <canvas id="tutorial" width="150" height="150"></canvas> </body> </html>
canvas> 元素
<canvas id="tutorial" width="150" height="150"></canvas>
canvas
看起來和 img
元素很相像,惟一的不一樣就是它並無 src
和alt
屬性。實際上,canvas
標籤只有兩個屬性——width
和height
。這些都是可選的,而且一樣利用 DOM properties
來設置。當沒有設置寬度和高度的時候,canvas
會初始化寬度爲300
像素和高度爲150
像素。該元素能夠使用CSS來定義大小,但在繪製時圖像會伸縮以適應它的框架尺寸:若是CSS的尺寸與初始畫布的比例不一致,它會出現扭曲。
渲染上下文(The rendering context)
var canvas = document.getElementById('tutorial'); var ctx = canvas.getContext('2d');
canvas
元素創造了一個固定大小的畫布,它公開了一個或多個渲染上下文,其能夠用來繪製和處理要展現的內容。
canvas
起初是空白的。爲了展現,首先腳本須要找到渲染上下文,而後在它的上面繪製。canvas
元素有一個叫作 getContext()
的方法,這個方法是用來得到渲染上下文和它的繪畫功能。getContext()
只有一個參數,上下文的格式。對於2D圖像而言,基本教程,你能夠使用CanvasRenderingContext2D
檢查支持性
替換內容是用於在不支持 canvas
標籤的瀏覽器中展現的。經過簡單的測試getContext()
方法的存在,腳本能夠檢查編程支持性。
var canvas = document.getElementById('tutorial'); if (canvas.getContext){ //支持 var ctx = canvas.getContext('2d'); // drawing code here } else { //不支持 // canvas-unsupported code here }
一開始,讓咱們來看個簡單的例子,咱們繪製了兩個有趣的長方形,其中的一個有着alpha透明度。咱們將在接下來的例子裏深刻探索一下這是如何工做的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>HTML5 Canvas 實現彩虹畫筆繪畫板</title> <script type="text/javascript"> function draw() { var canvas = document.getElementById('tutorial'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.fillStyle = "rgb(200,0,0)"; ctx.fillRect (10, 10, 55, 50); ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; ctx.fillRect (30, 30, 55, 50); } } </script> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body onload="draw();"> <canvas id="tutorial" width="300" height="300"></canvas> </body> </html>
效果圖:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>HTML5 Canvas</title> <style> html, body { margin: 0; overflow: hidden; } canvas { overflow: hidden; } </style> </head> <body> <canvas id="draw" width="800" height="800" style="overflow:auto;"></canvas> <script> // 1.獲取canvas節點 const canvas = document.querySelector('#draw'); if (canvas.getContext) { //支持 var ctx = canvas.getContext('2d'); // drawing code here } else { //不支持 // canvas-unsupported code here console.log("canvas-unsupported code here"); } canvas.width = window.innerWidth; canvas.height = window.innerHeight; let isDrawing = false; let lastX = 0; let lastY = 0; ctx.lineWidth = 90; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.strokeStyle = "#f00"; ctx.fillStyle = "#f00"; let hue = 0; let direction = true; let x = 0; let y = 0; function draw(e) { if (!isDrawing) return; x = e.offsetX; y = e.offsetY; // 彩虹效 ctx.strokeStyle = `hsl(${ hue }, 90%, 50%)`; if (hue >= 360) hue = 0; hue++; // 控制筆觸大小 if (ctx.lineWidth > 120 || ctx.lineWidth < 10) { direction = !direction; } if (direction) { ctx.lineWidth++; } else { ctx.lineWidth--; } // 控制繪製路徑 ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(x, y); ctx.stroke(); [lastX, lastY] = [x, y]; } canvas.addEventListener('mousedown', (e) => { isDrawing = true; [lastX, lastY] = [e.offsetX, e.offsetY]; }); canvas.addEventListener('mousemove', draw); canvas.addEventListener('mouseup', () => isDrawing = false); canvas.addEventListener('mouseout', () => isDrawing = false); </script> </body> </html>
canvas.width = window.innerWidth; canvas.height = window.innerHeight;
lineCap
:筆觸的形狀,有 round | butt | square 圓、平、方三種。
lineJoin
:線條相交的樣式,有 round | bevel | miter 圓交、斜交、斜接三種。
lineWidth
:線條的寬度
strokeStyle
:線條描邊的顏色
fillStyle
:填充的顏色
beginPath()
:新建一條路徑
stroke()
:繪製輪廓
moveTo()
:(這次)繪製操做的起點
lineTo()
:路徑的終點
在這個挑戰中,涉及到改變線條的顏色,如何實現彩虹的漸變效果?咱們須要利用 HSL 色彩模式,首先能夠去這個網站 http://mothereffinghsl.com 感覺一下 HSL 不一樣色彩值對應的效果。
H(hue) 表明色調,取值爲 0~360,專業術語叫色相
S 是飽和度,能夠理解爲摻雜進去的灰度值,取值爲 0~1
L 則是亮度,取值也是 0~1,或者百分比。
這之中 H 值從 0 到 360 的變化表明了色相的角度的值域變化,利用這一點就能夠實現繪製時線條顏色的漸變了,只須要在它的值超過 360 時恢復到 0 從新累加便可。
let hue = 0; ctx.strokeStyle = `hsl(${ hue }, 100%, 50%)`; if(hue >= 360) hue = 0; hue++;
除此以外,若是想實現黑白水墨的顏色,能夠將顏色設置爲黑色,經過透明度的改變來實現深淺不一的顏色。
// 控制筆觸大小 if (ctx.lineWidth > 120 || ctx.lineWidth < 10) { direction = !direction; } if (direction) { ctx.lineWidth++; } else { ctx.lineWidth--; }
上面的代碼中,根據線條的寬度的變化來控制direction
的值,根據direction
的值來控制線寬是增長仍是減小。
// 控制繪製路徑 ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(x, y); ctx.stroke(); // 座標重置 [lastX, lastY] = [x, y];
canvas.addEventListener('mousedown', (e) => { <!--開始繪圖--> isDrawing = true; <!--繪圖起始座標初始化--> [lastX, lastY] = [e.offsetX, e.offsetY]; }); <!--鼠標移動時,調用draw方法--> canvas.addEventListener('mousemove', draw); <!--鼠標擡起時,將isDrawing置爲false--> canvas.addEventListener('mouseup', () => isDrawing = false); <!--當鼠標不在可繪圖區域範圍內時,將isDrawing置爲fals--> canvas.addEventListener('mouseout', () => isDrawing = false);
社羣品牌:從零到壹全棧部落
定位:尋找共好,共同窗習,持續輸出全棧技術社羣
業界榮譽:IT界的邏輯思惟
文化:輸出是最好的學習方式
官方公衆號:全棧部落
社羣發起人:春哥(從零到壹創始人,交流微信:liyc1215)
技術交流社區:全棧部落BBS
全棧部落完整系列教程:全棧部落完整電子書學習筆記
關注全棧部落官方公衆號,每晚十點接收系列原創技術推送 |
---|