致懂得努力的我們
夫君子之行,靜以修身,儉以養德。非淡泊無以明志,非寧靜無以致遠。夫學須靜也,才須學也,非學無以廣才,非志無以成學。
淫慢則不能勵精,險躁則不能治性。年與時馳,意與日去,遂成枯落,多不接世,悲守窮廬,將復何及!
2018.12.12晚上 帶大家一起實現你畫我猜的畫板
猜猜我畫的什麼?
主要內容
- Canvas api講解
- 繪畫
- 橡皮擦
- 圖片生成
- 本地儲存
- 畫筆切換
公開課時間:12月12日 晚上 20:00~21:30
教室地址:北京昌平區回龍觀東大街地鐵A口出,向西走100米(緊鄰同仁堂)二樓201教室
Canvas簡述
Canvas 是HTML5新增的元素,讓我們通過JavaScript指令碼來繪製影像, 可以用JavaScript在上面繪製各種圖表、動畫等。
基於Canvas的一些庫:
-
chartjs(圖表)www.chartjs.org/
-
EaselJSwww.createjs.cc/easeljs/
Canvas基本用法
建立一個畫布
<
canvas id="canvas" width="300" height="300">
<
p>
你的瀏覽器不支援Canvas<
/p>
<
/canvas>
複製程式碼
如果你的瀏覽器不支援canvas標籤,則標籤內的文字會被顯示出來
canvas是內聯元素(inline)跟img元素很相像,唯一不同的是它沒有src和alt屬性,canvas標籤(除了選擇器)只有width和height兩個屬性,canvas 如果不設定寬高,預設 300*150。
獲取渲染上下文
var canvas = document.querySelector('#canvas')// 獲取2D畫布的渲染上下文var ctx = canvas.getContext('2d')複製程式碼
context.getContext() 獲取渲染上下文,該物件提供了用於在畫布上繪圖的方法和屬性
提示:在未來,如果 canvas 標籤擴充套件到支援 3D 繪圖,getContext() 方法可能允許傳遞一個 “3d” 字串引數。
console.log(ctx) // 2D渲染上下文物件複製程式碼
從畫一條直線開始
JS
// 通過canvas元素設定寬高canvas.width = 400canvas.height = 400// 設定線條寬度ctx.lineWidth = 10// 設定畫筆開始繪製座標(落筆點)ctx.moveTo(100, 100)// 連線點ctx.lineTo(300, 300)// 設定繪製顏色ctx.strokeStyle = 'red'// 根據moveTo和lineTo定製的路徑 進行繪製ctx.stroke()複製程式碼
頁面效果
繪製路徑
canvas繪圖是基於路徑的,肉眼看不到,先進行路徑繪製 然後再通過 fill(填充)或 stroke(描邊)等方法進行填充或繪製。
涉及api講解
-
lineWidth設定當前繪製線條的寬度。預設值: 1畫素
-
moveTo(x, y)相當於畫筆落筆點 開始一條路徑 相對於畫布左上角 x軸座標 y軸座標
-
lineTo(x, y)指定連線點座標,自動和上一個座標點進行連線 繪製路徑 相對於畫布左上角 x軸座標 y軸座標
-
strokeStyle設定通過stroke 繪製描邊的顏色。預設值: #000
-
stroke根據moveTo和lineTo定製的路徑 進行繪製描邊
繪製幾何圖形
繪製三角形
HTML
<
canvas id="canvas" width="600" height="600">
<
/canvas>
複製程式碼
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')// 設定繪製線條寬度ctx.lineWidth = 10// 設定繪製線條顏色ctx.strokeStyle = 'red'// 設定填充顏色ctx.fillStyle = 'pink'// 開始一條全新的繪製路徑ctx.beginPath()// 制定路徑ctx.moveTo(300, 50)ctx.lineTo(550, 500)ctx.lineTo(50, 500)// 閉合路徑ctx.closePath()// 進行填充ctx.fill()// 進行繪製ctx.stroke()複製程式碼
頁面效果
涉及api講解
-
fillStyle設定填充色 預設值:#000
-
fill根據fillStyle 對當前路徑進行填充
-
beginPath開始一條全新的繪製路徑
-
closePath閉合當前路徑,建立從當前點到開始點的路徑
路徑相關方法講解
1.beginPath 開始一個全新繪製的路徑
假如我要繪製幾條顏色不同的平行線條
HTML
<
canvas id="canvas" width="600" height="600">
<
/canvas>
複製程式碼
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')ctx.moveTo(100, 100)ctx.lineTo(500, 100)ctx.strokeStyle = 'yellow'ctx.stroke()ctx.moveTo(100, 200)ctx.lineTo(500, 200)ctx.strokeStyle = 'red'ctx.stroke()ctx.moveTo(100, 300)ctx.lineTo(500, 300)ctx.strokeStyle = 'blue'ctx.stroke()複製程式碼
不加beginPath情況下,後面stroke 會從最初路徑開始座標重新繪製一遍 導致之前路徑描邊顏色發生疊加
在每一次moveTo之前 加上beginPath方法 開始一個全新路徑
JS
// 通常習慣在第一次的時候也加上beginPath 讓程式碼看上去一致ctx.beginPath()ctx.moveTo(100, 100)ctx.lineTo(500, 100)ctx.strokeStyle = 'yellow'ctx.stroke()ctx.beginPath()ctx.moveTo(100, 200)ctx.lineTo(500, 200)ctx.strokeStyle = 'red'ctx.stroke()ctx.beginPath()ctx.moveTo(100, 300)ctx.lineTo(500, 300)ctx.strokeStyle = 'blue'ctx.stroke()複製程式碼
新增beginPath後
效果如下:
2.closePath
假如我們繪製一個幾何圖形如上, closePath會建立從當前結束點到開始點的路徑 形成閉合路徑
JS
ctx.lineWidth = 10ctx.strokeStyle = 'red'ctx.fillStyle = 'pink'ctx.beginPath()ctx.moveTo(300, 50)ctx.lineTo(550, 500)ctx.lineTo(50, 500)ctx.fill()ctx.stroke()複製程式碼
不加closePath時 是這樣
新增上closePath
JS
ctx.lineWidth = 10ctx.strokeStyle = 'red'ctx.fillStyle = 'pink'ctx.beginPath()ctx.moveTo(300, 50)ctx.lineTo(550, 500)ctx.lineTo(50, 500)// 閉合路徑ctx.closePath()ctx.fill()ctx.stroke()複製程式碼
新增closePath
效果如下:
closePath例子:
JS
ctx.lineWidth = 10ctx.strokeStyle = 'red'ctx.beginPath()ctx.moveTo(300, 100)ctx.lineTo(500, 500)ctx.lineTo(300, 500)ctx.closePath()ctx.lineTo(100, 500)ctx.stroke()複製程式碼
效果如下:
繪製矩形
rect(x, y, width, height)
建立一個矩形,需要通過stroke() 進行繪製
JS
var canvas = document.querySelector('canvas')var ctx = canvas.getContext('2d')ctx.strokeStyle = 'red'ctx.beginPath()ctx.rect(100, 100, 300, 300)ctx.stroke()複製程式碼
效果如下:
strokeRect(x, y, width, height)
根據strokeStyle指定顏色進行矩形描邊,繪製無填充色的矩形。同 rect+stroke 一樣效果
JS
var canvas = document.querySelector('canvas')var ctx = canvas.getContext('2d')ctx.beginPath()ctx.lineWidth = 10ctx.strokeStyle = 'red'ctx.rect(100, 100, 300, 300)ctx.stroke()複製程式碼
效果如下:
fillRect(x, y, width, height)
繪製具有填充色的矩形
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')ctx.beginPath()ctx.fillStyle = 'blue'ctx.fillRect(100, 100, 300, 300)複製程式碼
效果如下:
完整繪製一個矩形
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')ctx.lineWidth = 10ctx.fillStyle = 'blue'ctx.strokeStyle = 'red'// 方式一ctx.fillRect(100, 100, 200, 200)ctx.strokeRect(100, 100, 200, 200)// 方式二ctx.rect(320, 100, 200, 200)ctx.fill()ctx.stroke()複製程式碼
繪製帶陰影矩形
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')// 陰影模糊度ctx.shadowBlur = 20// 陰影顏色ctx.shadowColor = 'black'// 繪製帶藍色填充色的矩形ctx.fillStyle = 'blue'ctx.fillRect(100, 100, 200, 200)複製程式碼
線條相關屬性
lineCap
設定線條兩端線帽的樣式 context.lineCap=“butt|round|square”;
注意:”round” 和 “square” 值會使線條略微變長。
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')ctx.lineWidth = 20ctx.beginPath()ctx.moveTo(100, 100)ctx.lineTo(500, 100)// 預設值ctx.lineCap = 'butt'ctx.stroke()ctx.beginPath()ctx.moveTo(100, 200)ctx.lineTo(500, 200)// 兩末端圓形線帽ctx.lineCap = 'round'ctx.stroke()ctx.beginPath()ctx.moveTo(100, 300)ctx.lineTo(500, 300)// 兩末端方形線帽ctx.lineCap = 'square'ctx.stroke()複製程式碼
效果如下:
繪製圓形
arc
JavaScript 語法:
context.arc(x,y,r,sAngle,eAngle,counterclockwise);
複製程式碼
引數
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')ctx.lineWidth = 10ctx.beginPath()ctx.arc(300, 300, 100, 0, Math.PI * 2, false)ctx.strokeStyle = 'blue'ctx.fillStyle = 'red'ctx.fill()ctx.stroke()複製程式碼
效果如下:
開始角與結束角:
繪製半圓
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')ctx.lineWidth = 10ctx.beginPath()// 逆時針繪製ctx.arc(300, 300, 100, 0.5 * Math.PI, 1.5 * Math.PI, true)ctx.strokeStyle = 'green'ctx.fillStyle = 'red'ctx.fill()ctx.stroke()複製程式碼
效果如下:
繪製五角星
JS
var canvas = document.querySelector('#canvas')var ctx = canvas.getContext('2d')// 計算x軸座標值// X = Math.cos(弧度) * 半徑 + 圓心x軸座標var cx = function(i, r, x, d) {
return Math.cos((d + i * 72) / 180 * Math.PI) * r + x
}// 計算y軸座標值// Y = Math.sin(弧度) * 半徑 + 圓心y軸座標var sy = function (i, r, y, d) {
return -Math.sin((d + i * 72) / 180 * Math.PI) * r + y
}/** * @desc 繪製五角星 * @param {Object
} ctx 2d渲染上下文 * @param {Number
} r 內圓半徑 * @param {Number
} R 外圓半徑 * @param {Number
} x 圓心x軸位置 * @param {Number
} y 圓心y軸位置 * @param {Color
} fillColor 填充色 * @param {Color
} strokeColor 描邊色 * */function drawStart(ctx, r, R, x, y, fillColor, strokeColor) {
ctx.fillStyle = fillColor ctx.strokeStyle = strokeColor ctx.beginPath() // 繪製五個角 for (var i = 0;
i <
5;
i++) {
// 繪製外圓路徑 ctx.lineTo( cx(i, R, x, 18), sy(i, R, y, 18)) // 繪製內圓路徑 ctx.lineTo( cx(i, r, x, 54), sy(i, r, y, 54))
} ctx.closePath() ctx.fill() ctx.stroke()
}drawStart(ctx, 100, 200, 300, 300, 'red', 'white')複製程式碼
效果如下:
五角星數學知識補下
// 求弧度// 為L = n(圓心角度數)× π × r(半徑)/180(角度制)// 對邊與斜邊的比叫做正弦(sine),記作sin// 鄰邊與斜邊的比叫做餘弦(cosine),記作cos// 對邊與鄰邊的比叫做正切(tangent),記作tan// JS Math.sin() 與 Math.cos() 用法// Math.sin(x) x 的正玄值。返回值在 -1.0 到 1.0 之間// Math.cos(x) x 的餘弦值。返回的是 -1.0 到 1.0 之間的數// 這兩個函式中的X 都是指的“弧度”而非“角度”,// 弧度的計算公式為:2 * PI / 360 * 角度// 30° 角度 的弧度 = 2 * PI / 360 * 30// 如何得到圓上每個點的座標?// 在圓的座標系中 半徑r為斜邊 x軸為鄰邊 y軸為對邊// 正弦 = y / r// 餘弦 = x / r// 解決思路:根據三角形的正弦、餘弦來得值// 假設一個圓的圓心座標是(a, b),半徑為r// X = 圓心x軸座標 + 弧度的餘弦值 * 半徑// 則圓上每個點的X座標= a + Math.cos(2 * Math.PI / 360) * r// Y = 圓心y軸座標 + 弧度的正弦值 * 半徑// Y座標 = b + Math.cos(2 * Math.PI / 360) * r// 計算x軸座標值// X = Math.cos(弧度) * 半徑 + 圓心x軸座標var cx = function(i, r, x, d) {
return Math.cos((d + i * 72) / 180 * Math.PI) * r + x
}// 計算y軸座標值// Y = Math.sin(弧度) * 半徑 + 圓心y軸座標var sy = function (i, r, y, d) {
return -Math.sin((d + i * 72) / 180 * Math.PI) * r + y
}ctx.lineTo(X, Y)複製程式碼