夫君子之行,静以修身,俭以养德。非淡泊无以明志,非宁静无以至远。夫学须静也,才须学也,非学无以广才,非志无以成学。git
淫慢则不能励精,险躁则不能治性。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及!github
猜猜我画的什么?canvas
主要内容api
公开课时间: 12月12日 晚上 20:00~21:30浏览器
在线地址: ke.qq.com/course/5868…bash
教室地址: 北京昌平区回龙观东大街地铁A口出,向西走100米(紧邻同仁堂)二楼201教室微信
Canvas 是HTML5新增的元素,让咱们经过JavaScript脚原本绘制图像, 能够用JavaScript在上面绘制各类图表、动画等。函数
基于Canvas的一些库:学习
chartjs(图表) www.chartjs.org/动画
Konva www.konvajs.com/docs/
EaselJS www.createjs.cc/easeljs/
建立一个画布
<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渲染上下文对象
复制代码
// 经过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(描边)等方法进行填充或绘制。
lineWidth 设置当前绘制线条的宽度。默认值:1像素
moveTo(x, y) 至关于画笔落笔点 开始一条路径 相对于画布左上角 x轴坐标 y轴坐标
lineTo(x, y) 指定链接点坐标,自动和上一个坐标点进行链接 绘制路径 相对于画布左上角 x轴坐标 y轴坐标
strokeStyle 设置经过stroke 绘制描边的颜色。默认值:#000
stroke 根据moveTo和lineTo定制的路径 进行绘制描边
<canvas id="canvas" width="600" height="600"></canvas>
复制代码
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()
复制代码
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()
复制代码
效果以下:
建立一个矩形,须要经过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()
复制代码
效果以下:
根据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()
复制代码
效果以下:
绘制具备填充色的矩形
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)
复制代码
设置线条两端线帽的样式 context.lineCap=“butt|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()
复制代码
效果以下:
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)
复制代码