我们在很多地方都会用到canvas,比如说做个图表,绘制一些动态渲染的图,做动画效果,更不用说web游戏领域了。
canvas 和 svg是html5主要的两个2d图形技术,都可以展示2d图形,二者有以下区别。
1. Canvas是用js动态生成的,向画图一样。svg一般是用其它软件制作好导出而成,使用XML静态描述
2. canvas 基于位图,适用于像素处理和动态渲染,图形放大会影响质量。svg是基于矢量的,不适用于像素处理,但放大不会影响质量
一、canvas常用属性和方法
属性 | 说明 |
---|---|
width | 设置canvas的宽度 |
heihgt | 设置高度 |
getContext(“2d”) | 获取Canvas 2D 上下文对象CanvasRenderingContext2D ,getContext(“webgl”)获取3D上下文环境 |
toDataURL() | 获取canvas对象产生的位图字符串,这是一串base64编码的图片 |
二、casvas常用绘图方法
1. 直线
cxt = document.getElementById('canvas').getContext('2d')
cxt.moveTo(20,20)
cxt.lineTo(20,50)
cxt.lineTo(50,50)
cxt.lineTo(20,20)
cxt.stroke()
2. 曲线
- 二次贝塞尔曲线
ctx.quadraticCurveTo(cpx, cpy, x, y);
绘制一条贝塞尔曲线需要三个点,起始点、控制点、终点
其中quadraticCurveTo
给出控制点和终点,起始点由moveTo
或 lineTo
函数提供
cxt.beginPath()
cxt.moveTo(20, 20)
cxt.quadraticCurveTo(50, 100, 100, 20)
cxt.stroke()
红色曲线即为二次贝塞尔曲线,其中红色为起始点和终点,蓝色为控制点
- 三次贝塞尔曲线
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
绘制一条三次贝塞尔曲线需要四个点,起始点、控制点1、控制点2、结束点。其中bezierCurveTo
给出两个控制点和终点。起始点由moveTo
或 lineTo
函数提供
cxt.moveTo(20, 100)
cxt.bezierCurveTo(60, 50, 100, 150, 140, 100)
cxt.stroke()
红色曲线即为三次贝塞尔曲线,其中红色为起始点和终点,蓝色为控制点
3. 简单几何图形
- 矩形
ctx.fillRect(x, y, width, height)
或ctx.rect(x, y, width, height)
。x,y为左上角左边
cxt.strokeRect(20,20,80,50)
cxt.fillRect(20,20,80,50)
也可以采用下面这种方法,区别是下面这种方法会改变当前路径
cxt.beginPath()
cxt.rect(10, 10, 100, 60)
cxt.fill() //cxt.stroke()
- 圆,半圆,圆弧
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
或ctx.arcTo(x1, y1, x2, y2, radius)
cxt.arc(圆心x,y,半径,开始角度 ,结束角度,顺逆时针)
cxt.arcTo(控制点x1,y1,控制点x2,y2,半径)
cxt.beginPath()
cxt.strokeStyle = 'red'
cxt.fillStyle = 'red'
//填充
cxt.beginPath()
cxt.arc(50, 50, 20, 0, Math.PI * 2)
cxt.fill()
//描边
cxt.beginPath()
cxt.arc(100, 50, 20, 0, Math.PI * 2)
cxt.stroke()
//半圆
cxt.beginPath()
cxt.arc(50, 100, 20, 0, Math.PI)
cxt.stroke()
//逆时针
cxt.beginPath()
cxt.arc(100, 100, 20, 0, Math.PI, true)
cxt.stroke()
//合并路径 使用 cxt.closePath()
cxt.beginPath()
cxt.arc(50, 150, 20, 0, Math.PI)
cxt.closePath()
cxt.stroke()
//填充
cxt.beginPath()
cxt.arc(100, 150, 20, 0, Math.PI, true)
cxt.fill()
只要控制开始角度和结束角度和顺逆时针的三个参数,就可以画出你想要的圆弧,画出更复杂的图形,如我们常用的饼图。
- 画任意正多边形
canvas没有给出画三角形,五边形等正多边形的函数,但我们可以自己定义
/**
* dx,dy 中心点坐标
* size n边形大小
* n 多边形的边数
* cxt canvas上下文环境
*/
function drawPolygon(dx, dy, size, n, cxt) {
cxt.beginPath()
let degree = (2 * Math.PI) / n
for (let i = 0;i < n;i++) {
let x = Math.cos(i * degree)
let y = Math.sin(i * degree)
cxt.lineTo(x * size + dx, y * size + dy)
}
cxt.closePath()
}
3.绘制图片
可以绘制点位图和svg
ctx.drawImage(image, dx, dy);
ctx.drawImage(image, dx, dy, dWidth, dHeight);
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
4. 线条样式
- 设置颜色
cxt.strokeStyle=color; cxt.strokeStyle=gradient;
可以设置纯色,也可以设置渐变色
//纯色值同css的颜色值设置
cxt.strokeStyle = 'blue'
cxt.strokeStyle = 'rgba(0,255,0,1)'
- 设置宽度
cxt.lineWidth = 13
- 虚线
ctx.setLineDash([])
ctx.setLineDash([1,1])
ctx.setLineDash([10, 10])
ctx.setLineDash([20, 5])
ctx.setLineDash([15, 3, 3, 3])
ctx.setLineDash([20, 3, 3, 3, 3, 3, 3, 3])
- 线段末端
ctx.lineCap = "butt"; //线段末端以方形结束
ctx.lineCap = "round"; //线段末端以圆形结束
//线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域
ctx.lineCap = "square";
- 线条链接方式
cxt.lineJoin = 'round'
cxt.lineJoin = 'bevel'
cxt.lineJoin = 'miter'
5.绘制阴影
cxt.shadowColor = "black";
cxt.shadowBlur = 10
cxt.shadowOffsetY = 10;
cxt.shadowOffsetX = 10;
cxt.fillRect(20, 20, 100, 100)
6. 文字
- cxt.font
- cxt.textAlign
- cxt.textBaseline
- cxt.fillText()
- cxt.strokeText()
cxt.font = value; //类似css
cxt.textAlign = "left" || "right" || "center" || "start" || "end";
cxt.textBaseline = "top" || "hanging" || "middle" || "alphabetic" || "ideographic" || "bottom";
cxt.fillText(text, x, y, [maxWidth]);
cxt.strokeText("Hello world", 50, 100);
cxt.fillText('lalla',100,100)