1.canvas的save()和restore()的区别
save()只是保存的绘图上下文的设置和变换,用来保存Canvas的状态,而不是保存绘图的上下文内容。
restore()用来恢复Canvas旋转、缩放等之后的状态,当和canvas.save( )一起使用时,恢复到canvas.save( )保存时的状态。
按照我自己的话说,就是假如我们画了一个圆,用save()保存,此时并没有状态的改变操作。然后我们进行一系列的状态变换,比如旋转,接着我们又画了一条线,此时的线是在画布旋转之后位置。此时我们调用restore()方法,则会恢复到save时的状态,即未旋转的状态,现在再画一条线,这条线就会处于画布未旋转时的位置。
2.绘制图像:drawImage()
这里可以有九个参数:image元素、源图像的x坐标、y坐标、宽、高、目标图像的x坐标、y坐标、宽、高
// 用法 ,现在在坐标10,10位置处画一个图像 const image = document.images[0]; context.drawImage(image, 10, 10);
我们可以通过图像的九个参数,对图像做出不同位置的显示以及图像部分的显示。
// 现在画一个类似图像迁移的试图 context.drawImage(image, 0, 10, 50, 50, 0, 100, 40, 60);
这样会得到两个图形,其中第二个图形由于是40, 60的宽高,所以只会显示一部分。
第一个擦参数还可以是canvas元素,这样就可以将一个画布绘制在当前的画布上,画布的结果可以通过toDataURL()方法取得,注意不能在跨域的环境下使用这个方法。
3.渐变
渐变主要是通过2D上下文进行创建和改变,渐变分为线性渐变和径向渐变,他们都会返回一个对象值。
线性渐变:createLinearGradient(x1, y1, x2, y2)
径向渐变:createRadialGradient(x1, y1, r1, x2, y2, r2)
// 用法, 画一条起点10, 10 终点30, 30的线性渐变区域 const linear = context.createLinearGradient(10, 10, 30, 30); // 渐变的颜色设置是从白到黑 linear.addColorStop(0, "white"); linear.addColorStop(1, "black"); context.fillStyle = linear; context.fillRect(10, 10, 50, 50);
径向渐变的区域使用方法相似,也会返回一个对象,再去调用addColorStop()方法,进行设置颜色的渐变
// 这里使用的时候要注意坐标的变化,这里是根据画出的矩形做出的坐标的调整 const radial = context.createRadialGradient(30, 30, 10, 30, 30, 10);
4.模式,createPattern()
模式其实就是绘制重复的图像,它会返回一个样式的值。它有两个参数,分别是img元素,video元素或者canvas元素,第二个参数是一个字符串和css的属性background-repeat相似,可以是repeat,repeat-x,repeat-y,no-repeat
// 用法 const img = document.images[0]; const imgRepeat = context.createPattern(img, "repeat"); context.fillStyle = imgRepeat; // 在宽高指定的矩形区域内,进行显示重复的图片,而不是在起点为10, 10处开始重复图像 context.fillRect(10, 10, 50, 50);
5.使用图形原始数据
使用图形的原始数据就是想获得图像的宽高和rgba,通过调用getImageData(),指定四个参数(x, y, width, height),就可以获得元素数据,返回一个对象,属性值分别是宽和高以及raba组成的一个data数组
// 首先画一个画布 const draw = document.getElementById("draw"); // 判断画布元素是否支持canvas if (draw.getContext) { // 取得画布2d上下文 const context = draw.getContext("2d"); // 取得图像 const image = document.images[0]; // 调用drawImage()方法在0, 0处绘制图像 context.drawImage(image, 0, 0); // 取得图像的原始数据 const getImgData = context.getImageData(0, 0, image.width, image.height); // 获取原始图形的宽高以及rgba的数组数据 const imageWidth = getImgData.width; const imageHeight = getImgData.height; const imageRgbaArr = getImgData.data; let r, g, b, a, average // 获取数据的rgba的值 imageRgbaArr.forEach((item, index) => { r = (index === 0) && item; g = (index === 1) && item; g = (index === 2) && item; a = (index === 3) && item; if (r && g && b && a) { average = (r + g + b) / 3; imageRgbaArr[0] = average; imageRgbaArr[1] = average; imageRgbaArr[2] = average; } }) } // 调用putImageData()方法回填数据并在画板上展现出来 getImgData = imageRgbaArr; context.putImageData(getImgData, 0, 0);
取得原始图像数据的时,图像并不能来自其他域,否则js会报错。
6.图像合成
图像合成分为两个全局属性:globalAlpha和globalCompositionOperation
// 用法,globalAlpha属性默认值是0,表示绘制的透明度,默认是不透明 context.globalAlpha = 0.5; context.fillStyle = "red"; context.fillRect(10, 10, 30, 30); // 用法,globalCompositionOperation,用来表示先后两次绘制图形的位置。默认值是"source-over",即后绘制的图形在先绘制图形的上方 context.fillStyle = "red"; context.fillRect(10, 10, 30, 30); // 设置图形的合成位置,先绘制的图形在后绘制图形的上方 context.globalCompositionOperation = "destination-over"; context.fillStyle = "green"; context.fillRect(20, 20, 30, 30);
globalCompositionOperation它还有很多属性值,包括两个图形合成的时候的透明度的变换显示,可以继续在浏览器上测试,目前支持较好的有IE和firefox,在不同的浏览器上测试可能会有很大的差别
网友评论