一、基本用法
1、要使用 <canvas>
元素,必须先设置其 width 和 height 属性,指定可以绘图的区域大小。
<canvas id="drawing" width=" 100" height="100">A drawing of something.</canvas>
注意:
(1)不支持 <canvas>
的浏览器将会忽略容器并在其中渲染后备内容,而支持 <canvas>
的浏览器将会忽略在容器中包含的内容,渲染 canvas
(2)如果不添加任何样式或者不绘制任何图形,在页面中是看不到该元素的。
2、渲染上下文(The rendering context)
为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。
<canvas>
元素创造了一个固定大小的画布,它公开了一个或多个渲染上下文,其可以用来绘制和处理要展示的内容。
// 获取canvas元素
var canvas = document.getElementById("drawing");
// 获取2D上下文
var ctx = canvas.getContext("2d");
注意:2D 上下文的坐标开始于 <canvas>
元素的左上角,原点坐标是(0,0)
二、绘制矩形
fillRect()
方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在(x, y) ,它的宽度和高度分别由 width
和 height
确定,填充样式由当前的 fillStyle
决定。
示例:
//设置填充样式,填充的默认颜色为黑色
ctx.fillStyle = "#ccc";
//绘制矩形
ctx.fillRect(0, 0, canvas.width, canvas.height);
效果:
三、填充渐变色
Canvas 中专门设置颜色渐变的类 CanvasGradient。 它分为两种,一种是createLinearGradient()
,即线性渐变;另一种是 createRadialGradient()
,即径向渐变。
在设置之前,需要了解它们的使用方法:
CanvasGradient.addColorStop(offset(0-1),color),
参数: offset
是偏移值,它的值在 0-1
之间,color
是要渐变的颜色
1、线性渐变
线性渐变 createLinearGradient(x0, y0, x1, y1)
,创建一个沿参数坐标指定的直线的渐变。
它需要传递4个参数,x0,y0分别代表起始点的坐标,x1,y1分别代表结束点的坐标,返回值是一个 CanvasGradient 类型的对象。
示例:
var gradient = ctx.createLinearGradient(20, 0, 100, 0);
gradient.addColorStop(0, "#ccc");
gradient.addColorStop(0.5, "#fff");
gradient.addColorStop(1, "#ccc");
ctx.fillStyle = gradient;
效果:
2、径向渐变
径向渐变 createRadialGradient(x0, y0, r0, x1, y1, r1)
,需要传递的参数有6
个,x0, y0, r0分别代表起始圆的圆心和半径,x1, y1, r1分别代表结束圆的圆心和半径。
示例:
var gradient = ctx.createRadialGradient(50, 50, 50, 50, 50, 0);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "green");
ctx.fillStyle = gradient;
效果:
四、绘制图片
使用 drawImage()
方法把一幅图像绘制到画布上。
语法:三种参数组合
(1)ctx.drawImage(image, dx, dy); 绘制起点的x和y坐标
如:ctx.drawImage(image, 10, 10);
(2)ctx.drawImage(image, dx, dy, dWidth, dHeight); 绘制目标的宽、高
如:ctx.drawImage(image, 50, 10, 20, 30); 表示绘制出来的图像大小会变成 20×30 像素
(3)ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
参数:共9个,分别是:
参数 | 说明 |
---|---|
image | 要绘制的图像 |
sx | 源图像的 x 坐标 |
sy | 源图像的 y 坐标 |
sWidth | 源图像的宽度 |
sHeight | 源图像的高度 |
dx | 目标图像的 x 坐标 |
dy | 目标图像的 y 坐标 |
dWidth | 目标图像的宽度 |
dHeight | 目标图像的高度 |
图示:
注意:使用 .complete === true 和 .onload 可确定Image 何时加载完成。
示例:
//新建一个Image对象
var img = new Image();
//设置Image的src
img.src = "https://mdn.mozillademos.org/files/5397/rhino.jpg";
//确定Image加载完毕后,将Image画到canvas上
img.onload = () => {
var left = (canvas.width - 40) / 2; //居中
var top = (canvas.height - 40) / 2
// 参数:图片 左0px 上50px 宽40px 高40px
ctx.drawImage(img, left, top, 40, 40);
};
效果:
五、绘制文字
绘制文本主要有两个方法: fillText()
绘制文本 和 strokeText()
文本描边。
这两个方法都可以接收 4 个参数:要绘制的文本字符串、x 坐标、y 坐标和可选的最大像素宽度。如果第四个参数提供了最大宽度,文本会进行缩放以适应最大宽度。
在调用 fillText() 或 strokeText() 方法时,先要设置 font
、textAlign
、textBaseline
这3个属性。
属性 | 说明 | 可选值 |
---|---|---|
ctx.fillStyle | 设置文本样式 | 例如文本颜色 #ccc 等 |
ctx.font | 设置文本字体大小、字体 | |
ctx.textAlign | 设置文本对其方式 | 可选值有 “start” 、 “end” 、 “left” 、 “right” 和 “center” 。 建议使用"start" 和 “end” ,不要使用 “left” 和 “right” ,因为前两者的意思更稳妥,能同时适合从左到右和从右到左显示(阅读)的语言 |
ctx.textBaseline | 设置文本基线 | 可选值有:“top”、“hanging”、 “middle” 、 “alphabetic”、“ideographic” 和 “bottom” |
示例:
ctx.fillStyle = "#000"; // 文字填充颜色
ctx.font = "bold 14px Arial";
ctx.fillText("文字", 0, 20);
效果:
注意:如果要绘制图片和文字,则要把文字绘制的方法写在绘制图片之后,例如:
var img = new Image();
img.src = "https://mdn.mozillademos.org/files/5397/rhino.jpg";
img.onload = () => {
var left = (canvas.width - 40) / 2;
var top = (canvas.height - 40) / 2;
ctx.drawImage(img, left, top, 40, 40);
ctx.fillStyle = "#000"; // 文字填充颜色
ctx.font = "bold 14px Arial";
ctx.fillText("文字", 0, 20);
};
文字换行:
参考这篇博客:https://m.w3cschool.cn/article/28537786.html
六、绘制圆弧路径
圆弧路径的圆心在 (x, y) 位置,半径为 r ,根据anticlockwise (默认为顺时针)指定的方向从 startAngle 开始绘制,到 endAngle 结束。
语法: ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
参数:
参数 | 说明 |
---|---|
x | 圆心的x轴坐标 |
y | 圆心的y轴坐标 |
radius | 圆弧的半径 |
startAngle | 圆弧起点(x轴方向开始计算、单位是弧度) |
endAngle | 圆弧终点(单位是弧度) |
anticlockwise | 绘制方向(可选Boolean,true是逆时针绘制圆弧、反之,顺时针绘制) |
可设置 strokeStyle 边框颜色、lineWidth 边框宽度
示例:
ctx.beginPath();
ctx.arc(20, 35, 10, 0, Math.PI * 2);
ctx.fillStyle = "green";
ctx.strokeStyle = "#ccc"; //边框颜色
ctx.lineWidth = 2; //边框宽度
ctx.fill();
ctx.stroke();
效果:
七、使用图像数据
通过 getImageData()
取得原始图像数据。方法接收4 个参数:要取得其数据的画面区域的 x 和 y 坐标以及该区域的像素宽度和高度
var imageData = context.getImageData(10, 5, 50, 50);
返回的对象是 ImageData 的实例。每个 ImageData 对象都有三个属性: width 、 height 和data 。其中 data 属性是一个数组,保存着图像中每一个像素的数据。
在 data 数组中,每一个像素用4 个元素来保存,分别表示红、绿、蓝和透明度值
var data = imageData.data,
red = data[0],
green = data[1],
blue = data[2],
alpha = data[3];
数组中每个元素的值都介于 0 到 255 之间(包括 0 和 255)
示例:
// 创建 canvas元素
var canvas = document.createElement("canvas");
// 获取2D上下文
var ctx = canvas.getContext("2d");
// 设置画布宽高
canvas.width = 100;
canvas.height = 100;
// 给画布填充颜色
ctx.fillStyle = "green";
// 将画布的左上角放在(0, 0),把它的大小设置成宽200高200
ctx.fillRect(0, 0, 200, 200);
八、html2canvas
html2canvas 介绍:
(1)通过获取 HTML 的某个元素,然后生成 Canvas,从而让用户保存为图片
(2)工作原理:将当页面渲染成一个 Canvas 图片,通过读取 DOM 并将不同的样式应用到这些元素上。
(3)不需要来自服务器任何渲染,整张图片都是在客户端浏览器创建
支持的浏览器
- Firefox 3.5+
- Google Chrome
- Opera 12+
- IE9+
- Edge
- Safari 6+
使用场景:
生成海报:一个背景图+动态获取的文字+微信头像拼接成一张图片,用户可长按保存最终图片
数据大屏:可用于做大屏的图片生成,通过静态图片生成来分享数据
注意事项
不是所有的页面元素都可以进行转换的,下面是一些不支持转换的情况:
(1)不支持 iframe
(2)不支持跨域图片(可以先将线上图片转换成 base64格式,然后用base64作为图片路径)
(3)不支持 flash
不支持 transform、transition过渡、animation动画(备注:transform初始布局是可以的,但是不能参与动画类的操作)
安装下载:
方法一:NPM
下载:npm install --save html2canvas
引入:import html2canvas from “html2canvas”
方法二:下载 .js 文件
到官网上将 html2canvas.js
下载到本地(官网地址:http://html2canvas.hertzen.com/)
在页面中引用
<script type="text/javascript" src="js/html2canvas.js"></script>
示例
页面代码
<div id="container">
<div id="capture" style="width: 200px; padding: 20px" ref="capture">
<h4 style="color: #000; text-align: center">Hello World</h4>
</div>
<button type="button" name="button" @click="convert()">下载图片</button>
</div>
引入:
import html2canvas from "html2canvas";
Methods方法
methods: {
convert() {
html2canvas(this.$refs.capture, {
backgroundColor: "#ccc", //默认值是 #fff,如果想要背景透明,则设置为null
// scale: 1, //修改渲染时的放大倍数(默认为 1),将其调大可以解决低分辨率设备下生成的图片模糊问题
}).then((canvas) => {
// 将canvas转化为base64格式
var imgUrl = canvas.toDataURL("image/png", 1);
// 下载图片
var alink = document.createElement("a");
alink.href = imgUrl;
alink.download = "图片" + new Date().getTime(); //图片名+时间戳
alink.click();
});
},
},