状态保存和恢复
save()
保存画布 (canvas) 的所有状态
restore()
save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。
Canvas 状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。一个绘画状态包括:
当前应用的变形(即移动,旋转和缩放)
以及下面这些属性:strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled
当前的裁切路径(clipping path)
变形
translate(x, y)
其中x 是左右偏移量,y 是上下偏移量
设定后xy轴偏移量后,比如画矩形、圆等他的中心点需要加上偏移量,比如:
var ctx = canvas.getContext('2d');
ctx.strokeRect(0, 0, 40, 40); //画一个矩形
ctx.translate(20, 20); //x,y轴都平移20 下面的操作都会受到变形的影响
ctx.arc(0, 0, 20, 0, Math.PI * 2, true);//画圆,这里的圆心需要加上偏移量(0+20,0+20)即为(20,20)
ctx.stroke() //圆变成实体线条
ctx.fillStyle = '#2196f3' //填充颜色
ctx.fillRect(20,0,30,30) //画矩形 此时矩形的起始位置需要加上偏移量(20+20,0+20)即为(40,20)
rotate(angle)
旋转的角度 (angle),它是顺时针方向的,以弧度为单位的值
需要注意的是:默认以原点为中心旋转(0,0),如果需要改变它,可以使用translate方法
如:
var ctx = canvas.getContext('2d');
ctx.strokeRect(0, 0, 100, 100);//画矩形
ctx.translate(100,100) //改变中心点为(100,100)
for (let k = 1; k <= 12; k++) {
ctx.beginPath()
ctx.rotate(Math.PI / 6);
ctx.arc(20, 20, 20, 0, Math.PI * 2, true);
ctx.fillStyle = 'rgb(' + (20 * k) + ',' + (255 - 20 * k) + ',255)';
ctx.fill()
}
scale(x, y)
x 为水平缩放因子,y 为垂直缩放因子,如果比 1 小,会缩小图形,如果比 1 大会放大图形。默认值为 1,为实际大小。transform(a, b, c, d, e, f)
a:水平方向的缩放 b:竖直方向的倾斜偏 c:水平方向的倾斜偏移d:竖直方向的缩放e:水平方向的移动f:竖直方向的移动clip()
将当前正在构建的路径转换为当前的裁剪路径。举例:使用裁剪路径,绘制头像
var ctx = canvas.getContext('2d');
ctx.translate(60,60);
var img = new Image();
img.src = './images/1310CB021GZ.jpg';
img.onload = function() {
ctx.beginPath();
ctx.arc(0, 0, 40, 0, Math.PI * 2, true);
ctx.save();
ctx.clip();//创建圆的裁剪路径
ctx.drawImage(img,-40,-40,80,80);
ctx.restore();
ctx.closePath();
}
像素操作
ImageData对象中存储着 canvas 对象真实的像素数据,它包含以下几个只读属性
width:图片宽度,单位是像素 height:图片高度,单位是像素 data: Uint8ClampedArray 类型的一维数组包含着 RGBA 格式的整型数据,范围在 0 至 255 之间。
创建一个 ImageData 对象
var myImageData =ctx.createImageData(width, height);
得到场景像素数据
var myImageData = ctx.getImageData(left, top, width, height);
在场景中写入像素数据
ctx.putImageData(myImageData, dx, dy);
ctx.imageSmoothingEnabled
用来设置图片是否平滑的属性,true 表示图片平滑(默认值),false 表示图片不平滑。
比如:演示图片灰度
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = './assets/rhino.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
var grayscale = function() {
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);//拿到所有像素点
const data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
data[i] = avg; // red
data[i + 1] = avg; // green
data[i + 2] = avg; // blue
}
//处理 像素数据 取平均值
ctx.putImageData(imageData, 0, 0);
};
比如:颜色选择器
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = './assets/rhino.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
img.onload = function() {
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
};
var hoveredColor = document.getElementById('hovered-color');
var selectedColor = document.getElementById('selected-color');
function pick(event, destination) {
var x = event.layerX;
var y = event.layerY;
var pixel = ctx.getImageData(x, y, 1, 1);
var data = pixel.data;
const rgba = `rgba(${data[0]}, ${data[1]}, ${data[2]}, ${data[3] / 255})`;
destination.style.background = rgba;
destination.textContent = rgba;
return rgba;
}
canvas.addEventListener('mousemove', function(event) {
pick(event, hoveredColor);
});
canvas.addEventListener('click', function(event) {
pick(event, selectedColor);
});
保存图片
canvas.toDataURL('image/png')
默认设定。创建一个 PNG 图片。
canvas.toDataURL('image/jpeg', quality)
创建一个 JPG 图片。你可以有选择地提供从 0 到 1 的品质量
canvas.toBlob(callback, type, encoderOptions)
创建了一个在画布中的代表图片的 Blob 对像