之前我们写的都是canvas基础类型的练习,从今天开始,就要进入更深一级的学习当中了
一、图形的组合方式
下面我们来试验几种方式
什么是源图和目标图?
源图:可以简单的理解为后画的图;
目标图:可以理解为先画的图形;
globalCompositeOperation 是设置在目标图上的
在未设置前:
source-in:设置组合方式,只保留源图的重叠部分
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext("2d");
context.beginPath();
context.arc(100,100,50,0,Math.PI*2)
context.fillStyle="red";
context.fill();
context.globalCompositeOperation = "source-in";
context.beginPath();
context.arc(150,100,50,0,Math.PI*2);
context.fillStyle="#808080";
context.fill();
设置后:
source-out:设置组合方式,只保留源图的未重叠部分
context.globalCompositeOperation = "source-out";
设置后:
destination-over:设置组合方式,当前图形在下面
context.globalCompositeOperation = "destination-over";
二、图像的处理
1、图片的加载
绘制图片只有一个方法,但方法里的参数有三种方式
载入图片
绘制图片一定要在图片加载完成之后执行
var img = new Image();
img.src = "df.jpg";
img.onload = function(){
context.drawImage(img,0,0);
}
控制图片
var img = new Image();
img.src = "df.jpg";
img.onload = function(){
context.drawImage(img,0,0,canvas.width,canvas.height);
}
裁剪图片
var img = new Image();
img.src = "df.jpg";
img.onload = function(){
context.drawImage(img,0,0,100,100,50,50,img.width,img.height);
}
2、像素
我们使用getImageData()能够获取指定区域的像素值ImageData
ImageData中3个属性:width,height和data
width和height表示访问像素区域大小
data是一个包含访问区域所有像素信息的CanvasPixeArray
CanvasPixeArray是一个一维数组
每一个像素用4个整数(r,g,b,a)值表示,范围0~255
像素操作方法
getImageData(x,y,width,height):获取像素,(x,y)像素区域原点坐标
(width,height)像素区域的宽度和高度
putImageData():
灰度
var img = new Image();
img.src = "img/beautiful.jpg";
img.onload = function(){
context.drawImage(img,0,0);
var imgData = context.getImageData(0,0,myCanvas.width,myCanvas.height);
console.log(imgData.data);
var piexls = imgData.data;
for (var i = 0; i < piexls.length;i+=4) {
var r = piexls[i];
var g = piexls[i+1];
var b = piexls[i+2];
var gray = parseInt((r+g+b)/3);
piexls[i] = gray;
piexls[i+1] = gray;
piexls[i+2] = gray;
}
反色
var canvas = document.getElementById("mycanvas");
var context=canvas.getContext("2d");
var img = new Image();
img.src = "df.jpg";
img.onload = function(){
context.drawImage(img,0,0);
//获取所有像素点
var imgData = context.getImageData(0,0,500,500);
console.log(imgData)
for(var i=0;i<imgData.data.length;i +=4){
var r = imgData.data[i];
var g = imgData.data[i+1];
var b = imgData.data[i+2];
var a = imgData.data[i+3];
//反色处理
imgData.data[i]=255-r;
imgData.data[i+1]=255-g;
imgData.data[i+2]=255-b;
}
//将改完的像素重新放到画布上
context.putImageData(imgData,100,100)
}
3、视频的处理
动画帧
requestAnimationFrame不需要使用者指定循环间隔时间,浏览器会基于当前页面是否可见、CPU的负荷情况等来自行决定最佳的帧速率,从而更合理地使用CPU。
通过setTimeout和setInterval方法来在脚本中实现动画,但是这样效果可能不够流畅,且会占用额外的资源。
1、即使向其传递毫秒为单位的参数,它们也不能达到ms的准确性。这是因为javascript是单线程的,可能会发生阻塞。
2、没有对调用动画的循环机制进行优化。
3、没有考虑到绘制动画的最佳时机,只是一味地以某个大致的事件间隔来调用循环。