Just Do It - 開啓canvas之旅

致懂得努力的咱們

夫君子之行,靜以修身,儉以養德。非淡泊無以明志,非寧靜無以至遠。夫學須靜也,才須學也,非學無以廣才,非志無以成學。git

淫慢則不能勵精,險躁則不能治性。年與時馳,意與日去,遂成枯落,多不接世,悲守窮廬,將復何及!github

2018.12.12晚上 帶你們一塊兒實現你畫我猜的畫板

猜猜我畫的什麼?canvas

主要內容api

  • Canvas api講解
  • 繪畫
  • 橡皮擦
  • 圖片生成
  • 本地保存
  • 畫筆切換

公開課時間: 12月12日 晚上 20:00~21:30瀏覽器

在線地址: ke.qq.com/course/5868…bash

教室地址: 北京昌平區回龍觀東大街地鐵A口出,向西走100米(緊鄰同仁堂)二樓201教室微信

Canvas簡述

Canvas 是HTML5新增的元素,讓咱們經過JavaScript腳原本繪製圖像, 能夠用JavaScript在上面繪製各類圖表、動畫等。函數

基於Canvas的一些庫:學習

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 = 400
canvas.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 = 10
ctx.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 = 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()
複製代碼

添加closePath

效果以下:

closePath例子:

JS

ctx.lineWidth = 10
ctx.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 = 10
ctx.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 = 10
ctx.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 = 20
ctx.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 = 10
ctx.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 = 10
ctx.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)
複製代碼

該文章配套源碼地址

github.com/Lwenli1224/…

獲取更多學習資源

珠峯微信號
珠峯公衆號
相關文章
相關標籤/搜索