canvas API ,通俗的canvas基础知识(五)

时间:2022-09-24 14:24:55

前几期讲的都是路径图形的绘图,这节我们要讲的是如何在画布上操作图片,因为图形画不了漂亮妹子(画图高手忽略不计),想画美女怎么办?跟我来:

想要在画布中插入一张图片,我们需要的方法是这位大侠:

drawImage()  在画布上绘制图像,画布或视频

这位大侠可谓是武功高强啊,其绝学之多,内力之深,堪称高手中的高手,那我们来看看它都有些什么绝学:

秘籍一:

drawImage(img,x,y) 在画布上定位一张图片

参数:img 表示引入的图片对象,x,y表示引入的坐标

ps:img在这里表示的是图片的对象而不是图片的路径,说明不能直接来引用图片,而是需要操作DOM的方式来引用

上面的提示说了图片的特殊性,那我们该如何来获取图片呢?我们先来一个最简单的:

<canvas width="500" height="400" id="canvas">
<span>亲,您的浏览器不支持canvas,换个浏览器试试吧!</span>
</canvas>
<img src="2.jpg" alt="" id="img">

我们在页面上放一张图(当年的奶茶妹,当年的哦),然后获取这张图,再放到画布上

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var oImg = document.getElementById("img");
ctx.drawImage(oImg,10,10);

canvas API ,通俗的canvas基础知识(五)

看,在画布外的奶茶妹就到我们的画布上去了,可惜的是,现在的奶茶妹已经不是当前的奶茶妹了,有同学会说,我只想让我的奶茶妹在我的画布上(怎么是我的奶茶妹),不想让她在别的地方被看见,我要怎么做呢?机灵的同学一定想得到,我把外面的图片隐藏起来不就行了吗?直接隐藏行不行呢?

<img src="2.jpg" alt="" id="img" style="display:none;">

canvas API ,通俗的canvas基础知识(五)

右边的奶茶妹不见了,只有我的画布上有可以的奶茶妹,恩恩,这是我想要的,说明这样有这个图片在页面上,能够获取到这个DOM元素即可,至于图片到底显不显示,不重要,那图片的隐藏方式就很多了,自身隐藏,放到一个div中div隐藏,放到canvas标签中(因为支持canvas的浏览器里面的东西是不显示的)等等,也可以用纯js的方式来添加图片:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var aImg = new Image();
aImg.src = '2.jpg';
ctx.onload = function(){
ctx.drawImage(aImg,10,10,400,300);
}

canvas API ,通俗的canvas基础知识(五)

秘籍二:

drawImage(img,x,y,w,h)  在画布上定位图片,并规定图片的宽高

参数:img 表示引入的图片对象,x,y表示引入的坐标 ,w,h表示规定图片的大小

有同学会说,奶茶妹是好,但是我的画布太小,奶茶妹太大(哪里大了),图片太大,都基本上把我的画布都占满了,如果我在画布上画别的图形,岂不是玷污了奶茶妹了,能把她变小吗?哈哈,drawImage具备孙悟空的变换本领,能大能小,不信,看这里:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var oImg = document.getElementById("img");
ctx.drawImage(oImg,10,10,200,150);

canvas API ,通俗的canvas基础知识(五)

看,上面的奶茶妹一下子就变小了,哎呀,太小了,看不清楚,而且我只想看奶茶妹,不想看到别的糟同学,可以吗?当然可以

秘籍三

drawImage(img,sX,sY,sWidth,sHeight,x,y,width,height)  剪切画布,并在画布上定位被剪切的部分

参数:img 表示引入的图片对象,sX,sY表示剪切的其实坐标,sWidth,sHeight表示剪切的宽度和高度,x,y表示在画布上放置图片的坐标 ,width,height表示需要使用的图片的宽高

上面的参数虽多,但是还是很好理解的,我们来看看如何将奶茶妹剪切下来:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var oImg = document.getElementById("img");
ctx.drawImage(oImg,150,0,150,300,10,10,400,300);

canvas API ,通俗的canvas基础知识(五)

纳里,奶茶妹怎么变成了胖子?再看一下参数,发现此时最后面的width和height已和前面的w,h代表的意思不一样了,现在的表示裁剪下来的图片需要显示多大,如果比裁剪的宽高大,则会被拉伸,比裁剪的宽高小,则会被缩小,恩,我们调成跟裁剪尺寸一样看一下:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var oImg = document.getElementById("img");
ctx.drawImage(oImg,150,0,150,300,10,10,150,300);

canvas API ,通俗的canvas基础知识(五)

对对,就是这样的,后面的x,y表示裁剪的图片显示的位置,我们调到中间看看

ctx.drawImage(oImg,150,0,150,300,150,10,150,300);

canvas API ,通俗的canvas基础知识(五)

所以在使用裁剪功能的时候,要特别注意,图片的坐标和宽高和原来的意思有区别了

秘籍四

drawImage(video,x,y,w,h)  在画布上定位视频,并规定视频的宽高

参数:video表示引入是视频对象 ,x,y表示视频引入的坐标 ,w,h表示规定视频的大小

其实这里跟引入图片是一样的,只不过它是可以引入视频的,但是这里的引入只是视频的某一帧,所以,当我们直接引入时,是没有什么反应的:

<canvas width="500" height="400" id="canvas">
<span>亲,您的浏览器不支持canvas,换个浏览器试试吧!</span>
</canvas>
<video id="video1" controls width="270">
<source src="http://www.w3school.com.cn/example/html5/mov_bbb.mp4" type='video/mp4'>
<source src="http://www.w3school.com.cn/example/html5/mov_bbb.ogg" type='video/ogg'>
<source src="http://www.w3school.com.cn/example/html5/mov_bbb.webm" type='video/webm'>
</video>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var oVideo = document.getElementById("video1");
ctx.drawImage(oVideo,10,10,270,135);

canvas API ,通俗的canvas基础知识(五)

当视频设置为autoplay时:

canvas API ,通俗的canvas基础知识(五)

可以看到,右侧视频在播放,左侧没有什么反应,那怎么来播放视频呢?我们可以加一个定时器,然后每隔20秒执行一次绘画,这样一帧一帧的执行,连续起来就是一个视频了,其实视频的原理也是如此:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var oImg = document.getElementById("img");
var oVideo = document.getElementById("video1");
var timer = setInterval(function(){
ctx.drawImage(oVideo,10,10,270,135);
},20)

canvas API ,通俗的canvas基础知识(五)

不想让画布外的视频显示的方法跟图片是一样的,这里我就不细说了

除了drawImage具有裁剪功能外,还有一个方法可以裁剪——clip(),不同的是drawImage是裁剪图片,而clip只能裁剪图形,我们具体来看一下clip吧:

clip() 从原始画布中剪切任意形状和尺寸

ps:一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。您也可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)。

提示这里很重要,一定要看清楚,就好比是一张很大的油画布,现在我们用一个木框架子框一部分,然后就只能在这个框里画画了,框外面的就不能来画,恩,就是这个意思,当我们用restore()方法恢复画布是时候,就好比是把木框架子取掉了,这样就可以在别的地方画了,当然画好的这部分就不要动了

举个栗子:

不用clip裁剪:

ctx.arc(200, 200, 80, (Math.PI/180)*0, (Math.PI/180)*360, false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.arc(150, 150, 100, (Math.PI/180)*0, (Math.PI/180)*360, false);
ctx.fill();

canvas API ,通俗的canvas基础知识(五)

使用clip裁剪:

ctx.arc(200, 200, 80, (Math.PI/180)*0, (Math.PI/180)*360, false);
ctx.clip();
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.arc(150, 150, 100, (Math.PI/180)*0, (Math.PI/180)*360, false);
ctx.fill();

canvas API ,通俗的canvas基础知识(五)

可以比较看出,后面画的圆只显示在裁剪的圆的范围中,其他的都不见了,再看一个例子:

ctx.fillRect(50,50,200,100);
ctx.clip();
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.fillRect(100,100,200,100);

我们将圆改成实心的矩形,且是用的fillRect,而不是用fill,rect,结果是:

canvas API ,通俗的canvas基础知识(五)

只显示第一个矩形,第二个矩形貌似不见了,而我们分开写:

//不用clip裁剪
ctx.rect(50,50,200,100);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.fillRect(100,100,200,100);
//使用clip裁剪
ctx.rect(50,50,200,100);
ctx.fill();
ctx.clip();
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.fillRect(100,100,200,100);
//第一个矩形不填充,只画路径
ctx.rect(50,50,200,100);
ctx.clip();
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.fillRect(100,100,200,100);
//将clip放在第二个矩形
ctx.rect(50,50,200,100);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.rect(100,100,200,100);
ctx.clip();
ctx.fill();

canvas API ,通俗的canvas基础知识(五)  canvas API ,通俗的canvas基础知识(五)  canvas API ,通俗的canvas基础知识(五)  canvas API ,通俗的canvas基础知识(五)

上面的4张图分别代码上面的4段代码的效果,从这4组对比我们可以看出:

第一:裁剪的路径必须在被裁剪图形的前面申明,如果在后面申明,则会没有效果或只有第一个图形显示;

第二:如果前面的裁剪区域要是没有填充的话,显示的部分就要2图形相交的部分,但是绘图区域还是裁剪部分的区域

下面要讲的是像素操作,相对来说比较复杂,需要大家的强大大脑来脑补和理解,何为像素操作?我们说任何在屏幕上显示的图形,图片,画面等等都是由像素构成的,最好理解的就是户外大屏幕的画面了,因为户外大屏幕分辨率比较小,相比之下像素的颗粒就比较大,可以清晰的看到画面是又密密麻麻的像素来显示的,当户外大屏幕的屏幕有部分花了的话,会看到呈现的画面就会在花掉的部分显示成别的颜色,很明显,对于我们的电脑显示器也是一个原理!

那么像素是通过什么来获取的呢?我们来一一介绍:

getImageData(x,y,w,h)  拷贝画布指定矩形的像素数据

参数:x,y表示开始复制的左上角的坐标  w,h表示将要复制的区域大小

参数很好理解,就是在什么地方复制多大一个地方,而且它返回一个ImageData对象,ImageData对象里面包含了几个参数:

data:数组集合  width :对象的宽度  height:对象的高度

后面2个好理解,这个data集合到底是什么呢?我们来举个栗子:

ctx.fillRect(0,0,100,100);
//获取矩形框的像素
var oImg = ctx.getImageData(0,0,100,100);
console.log(oImg);
console.log(oImg.data)
console.log(oImg.data.length)

canvas API ,通俗的canvas基础知识(五)      canvas API ,通俗的canvas基础知识(五)

我们画了一个100*100的实现矩形,然后获取它的像素,然后分别查看了他们代表的意思,可以看到一个很有意思的东西,就是100*100的矩形的像素点应该是10000个像素,为什么它的长度是40000,这个我们可以在data数组中可以看到端倪,一个像素点是由rgba构成的:

r : 0-255  黑-白

g : 0-255 黑-白

b : 0-255  黑-白

a : 0-255 透明-不透明

也就是说,一个像素是用这4个值组成的,那么10000个像素的长度自然就是40000了,而且对应的值在console中也能看到,好了,理解了这一点,那么就里像素操作不远了!

除了我们在已知的地方去获取像素外,我们能不能自己来创造像素区域呢?答案是肯定的:

createImageData(w,h)  表示创建一个规定尺寸的ImageData对象

createImageData(ImageData)  表示创建与指定的另一个 ImageData 对象尺寸相同的新 ImageData 对象(不会复制图像数据)

我们也来写一个例子:

var oImg = ctx.createImageData(100,100);
console.log(oImg);
console.log(oImg.data)
console.log(oImg.data.length)

canvas API ,通俗的canvas基础知识(五)

恩,跟前面的是一样的,创建了一个ImageData对象,当然画布是没有任何的效果的,因为我们只是创建了一个对象,那么我们怎么将我们创建的对象放到画布上呢?那就要用到这个方法:

putImageData(imageData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight)  方法将图像数据(从指定的 ImageData 对象)放回画布上

参数:

imageData指创建或获取的imageData对象

x,y表示imageData对象的左上角坐标

dirtyX,dirtyY 表示在画布上放置图像的坐标,以像素计,可选

dirtyWidth,dirtyHeight 表示在画布上放置的图形大小,可选

我们也举2个例子:

ctx.fillRect(0,0,100,100);
//获取矩形框的像素
var oImg = ctx.getImageData(0,0,100,100);
ctx.putImageData(oImg,100,100);

canvas API ,通俗的canvas基础知识(五)

ctx.fillRect(0,0,100,100);
//获取矩形框的像素
var oImg = ctx.getImageData(0,0,100,100);
ctx.putImageData(oImg,100,100);
ctx.putImageData(oImg,100,0,10,10,50,50);

canvas API ,通俗的canvas基础知识(五)

看,这么一对比,就知道这些参数是什么意思了,其中第二个我还得解释一下,如图小矩形,x,y依然是表示大的ImageData对象的起始坐标,dirtyX,dirtyY,dirtyWidth,dirtyHeight表示是相对于现在的x,y的起始坐标再来定义位置和大小,这么解释应该就明白了!

这就是操作像素的方法,看着很简单,也挺好理解,但是真正用起来,还是蛮费脑子的,我们先来看第一个小实例,改变像素的颜色:

实例效果,改变100*100的黑色矩形框中的第10行第10列的颜色,颜色为红色,先画个图分析一下:

canvas API ,通俗的canvas基础知识(五)

从上面的console中也可以看出,像素点是从0开始的,如果上图就是矩形的像素点的分布(画的有点烂,将就看一下),第10行,也就是第11行,第10列也就是第11列,那么前十列的像素就是矩形的宽度*10,剩下的就是11个像素,二者相加就是所有的像素,然后每个像素用4个值表示,就是总和乘以4,好具体我们看代码:

ctx.fillRect(0,0,100,100);
//获取矩形框的像素
var oImg = ctx.getImageData(0,0,100,100);
setXY(oImg,10,10,[255,0,0,255]);
//设置目标像素点的颜色
function setXY(obj,x,y,color){
var w = obj.width;
var h = obj.height;
obj.data[4*(w*y+x)] = color[0];
obj.data[4*(w*y+x)+1] = color[1];
obj.data[4*(w*y+x)+2] = color[2];
obj.data[4*(w*y+x)+3] = color[3];
}
ctx.putImageData(oImg,100,100);

canvas API ,通俗的canvas基础知识(五)

看,(10,10)坐标点的颜色就变成了红色,一个点还是不太明显,如果是一条横向的或者的纵向的,就跟明显了:

ctx.fillRect(0,0,100,100);
//获取矩形框的像素
var oImg = ctx.getImageData(0,0,100,100);
for(var i=0;i<oImg.width;i++){
setXY(oImg,i,10,[255,0,0,255]);
}
for(var i=0;i<oImg.height;i++){
setXY(oImg,10,i,[255,0,0,255]);
}
//设置目标像素点的颜色
function setXY(obj,x,y,color){
var w = obj.width;
var h = obj.height;
obj.data[4*(w*y+x)] = color[0];
obj.data[4*(w*y+x)+1] = color[1];
obj.data[4*(w*y+x)+2] = color[2];
obj.data[4*(w*y+x)+3] = color[3];
}
ctx.putImageData(oImg,100,100);

canvas API ,通俗的canvas基础知识(五)

我们经常看到那种很炫酷的粒子文字,图形的效果,既然我们可以操作像素,如果我们只显示一部分的像素点,不就是粒子效果吗?看下面的例子:

ctx.fillStyle = 'red';
ctx.arc(150,150,100,0,360*Math.PI/180,false);
ctx.fill();
//获取矩形框的像素
var oImg = ctx.getImageData(50,50,200,200);
ctx.clearRect(0,0,canvas.width,canvas.height);
var w = oImg.width;
var h = oImg.height;
var arr = randomNum(w*h,w*h/10);
var newImg = ctx.createImageData(oImg);
for(var i=0;i<arr.length;i++){
newImg.data[4*arr[i]] = oImg.data[4*arr[i]];
newImg.data[4*arr[i]+1] = oImg.data[4*arr[i]+1];
newImg.data[4*arr[i]+2] = oImg.data[4*arr[i]+2];
newImg.data[4*arr[i]+3] = oImg.data[4*arr[i]+3];
}
ctx.putImageData(newImg,50,50); //某区域的部分随机数
function randomNum(iAll,iNow){
var arr = [];
var newArr = [];
for(var i=1;i<=iAll;i++){
arr.push(i);
}
for(var i=0;i<iNow;i++){
newArr.push(arr.splice(Math.random()*(arr.length),1));
}
return newArr;
}

canvas API ,通俗的canvas基础知识(五)

上面的例子表示,我只显示当前的十分之一的像素,具体效果看这里——粒子图形

像素操作不仅仅只能操作图形,图片我们一样可以操作,这样我们就能做出更多的效果,看看下面的例子,我们将图像换成图片,看看能不能做出粒子图片:

var aImg = new Image();
aImg.src = '3.jpg'; //当图片加载完毕才能进行下面的操作
aImg.onload = function(){
draw(this);
}
function draw(obj){
ctx.drawImage(obj,0,0,400,400);
//获取矩形框的像素
var oImg = ctx.getImageData(0,0,400,400);
var w = oImg.width;
var h = oImg.height;
var arr = randomNum(w*h,w*h/2);
var newImg = ctx.createImageData(oImg);
for(var i=0;i<arr.length;i++){
newImg.data[4*arr[i]] = oImg.data[4*arr[i]];
newImg.data[4*arr[i]+1] = oImg.data[4*arr[i]+1];
newImg.data[4*arr[i]+2] = oImg.data[4*arr[i]+2];
newImg.data[4*arr[i]+3] = oImg.data[4*arr[i]+3];
}
ctx.putImageData(newImg,0,0);
} //某区域的部分随机数
function randomNum(iAll,iNow){
var arr = [];
var newArr = [];
for(var i=1;i<=iAll;i++){
arr.push(i);
}
for(var i=0;i<iNow;i++){
newArr.push(arr.splice(Math.random()*(arr.length),1));
}
return newArr;
}

canvas API ,通俗的canvas基础知识(五)

这里我用的是二分之一的像素点,十分之一太少了,看得不明显,由此我们可以知道,也是可以来操作图片的像素点的,具体效果看这里 —— 图片粒子化

既然我们可以操作图片,那可以做的事就太多了,先看看下面这个例子,图片反色(即将原图片的像素颜色用相反的颜色替代):

var aImg = new Image();
aImg.src = '1.jpg';
aImg.onload = function(){
draw(this); } function draw(obj){
ctx.drawImage(obj,0,0,400,400);
var oImg = ctx.getImageData(0,0,400,400);
var w = oImg.width;
var h = oImg.height; for(var i=0;i<h;i++){
for(var j=0;j<w;j++){
var result = [];
var color = getXY(oImg,j,i);
result[0] = 255 - color[0];
result[1] = 255 - color[1];
result[2] = 255 - color[2];
result[3] = 255;
setXY(oImg,j,i,result);
}
}
ctx.putImageData(oImg,w,0);
} function getXY(obj,x,y){
var w = obj.width;
var h = obj.height;
var d = obj.data;
var color = [];
color[0] = obj.data[4*(y*w+x)];
color[1] = obj.data[4*(y*w+x)+1];
color[2] = obj.data[4*(y*w+x)+2];
color[3] = obj.data[4*(y*w+x)+3];
return color;
} function setXY(obj,x,y,color){
var w = obj.width;
var h = obj.height;
var d = obj.data;
obj.data[4*(y*w+x)] = color[0];
obj.data[4*(y*w+x)+1] = color[1];
obj.data[4*(y*w+x)+2] = color[2];
obj.data[4*(y*w+x)+3] = color[3];
}

canvas API ,通俗的canvas基础知识(五)

是不是很有意思,具体效果可以看这里—— canvas图片反色

用这个例子,我们还可以延伸一下,让它反色后,我们再加一个倒影,美女不明显,我们用山峰那张:

var aImg = new Image();
aImg.src = '3.jpg';
aImg.onload = function(){
draw(this); }
function draw(obj){
ctx.drawImage(obj,0,0,obj.width,obj.height);
var oImg = ctx.getImageData(0,0,obj.width,obj.height);
var w = oImg.width;
var h = oImg.height; var newImg = ctx.createImageData(obj.width,obj.height) for(var i=0;i<h;i++){
for(var j=0;j<w;j++){
var result = [];
var color = getXY(oImg,j,i);
result[0] = 255 - color[0];
result[1] = 255 - color[1];
result[2] = 255 - color[2];
result[3] = 255;
setXY(newImg,j,h-i,result);
}
}
ctx.putImageData(newImg,0,h);
} function getXY(obj,x,y){
var w = obj.width;
var h = obj.height;
var d = obj.data;
var color = [];
color[0] = obj.data[4*(y*w+x)];
color[1] = obj.data[4*(y*w+x)+1];
color[2] = obj.data[4*(y*w+x)+2];
color[3] = obj.data[4*(y*w+x)+3];
return color;
} function setXY(obj,x,y,color){
var w = obj.width;
var h = obj.height;
var d = obj.data;
obj.data[4*(y*w+x)] = color[0];
obj.data[4*(y*w+x)+1] = color[1];
obj.data[4*(y*w+x)+2] = color[2];
obj.data[4*(y*w+x)+3] = color[3];
}

canvas API ,通俗的canvas基础知识(五)

细心的同学一定能看出它的原理,没错,就是在设置像素的时候,将它的像素方向反向,即此处“h-i”,具体效果看这里——canvas图片反色倒影

我们还可以做一些延伸,我们可以通过像素的透明度的参数,给它设置投影渐变,我们来看看:

var aImg = new Image();
aImg.src = '3.jpg';
aImg.onload = function(){
draw(this); }
function draw(obj){
ctx.drawImage(obj,0,0,obj.width,obj.height);
var oImg = ctx.getImageData(0,0,obj.width,obj.height);
var w = oImg.width;
var h = oImg.height; var newImg = ctx.createImageData(obj.width,obj.height); for(var i=0;i<h;i++){
for(var j=0;j<w;j++){
var result = [];
var color = getXY(oImg,j,i);
result[0] = 255 - color[0];
result[1] = 255 - color[1];
result[2] = 255 - color[2];
result[3] = 255*i/h;
setXY(newImg,j,h-i,result);
}
}
ctx.putImageData(newImg,0,h);
} function getXY(obj,x,y){
var w = obj.width;
var h = obj.height;
var d = obj.data;
var color = [];
color[0] = obj.data[4*(y*w+x)];
color[1] = obj.data[4*(y*w+x)+1];
color[2] = obj.data[4*(y*w+x)+2];
color[3] = obj.data[4*(y*w+x)+3];
return color;
} function setXY(obj,x,y,color){
var w = obj.width;
var h = obj.height;
var d = obj.data;
obj.data[4*(y*w+x)] = color[0];
obj.data[4*(y*w+x)+1] = color[1];
obj.data[4*(y*w+x)+2] = color[2];
obj.data[4*(y*w+x)+3] = color[3];
}

canvas API ,通俗的canvas基础知识(五)

核心代码就一个地方,255*i/h 给透明度乘以一个百分比的值,从0-255,也是很巧妙啊,具体效果看这里——canvas图片反色投影渐变

总结一下吧:虽然像素操作的方法不多,但是其功能之强大,是很多人都要望其项背的,关键在于人的想象力和深入的理解,要理解这样一个概念,掌握了像素操作,就好比是掌握了物体的核心本质,你就是造物者,你想造出什么东西,全凭你的想法,这里只是展示了一个很低劣的效果,旨在给大家展示一下canvas像素操作的魅力,抛砖引玉而已,后期会单独发一下canvas的像素操作的实例给大家参考,这个东西实在是太重要了!

好了,弄了几天了,终于写完了,本来想多写一点的,想想,后面再扩展吧!谢谢大家!

canvas API ,通俗的canvas基础知识(五)的更多相关文章

  1. Python基础知识&lpar;五&rpar;------字典

    Python基础知识(四)------字典 字典 一丶什么是字典 ​ dict关键字 , 以 {} 表示, 以key:value形式保存数据 ,每个逗号分隔 ​ 键: 必须是可哈希,(不可变的数据类型 ...

  2. Android学习之基础知识五—创建自定义控件

    下面是控件和布局的继承关系: 从上面我们看到: 1.所有控件都是直接或间接继承View,所有的布局都是直接或间接继承ViewGroup 2.View是Android中最基本的UI组件,各种组件其实就是 ...

  3. python基础知识五

    数据结构基本上就是---它们可以处理一些数据的结构.或者说,它们是用来存储一组相关数据的. python中有三种内建的数据结构---列表.元祖和字典. 我们将会学习如何使用它们,以及它们如何使编程变得 ...

  4. Android学习之基础知识五—编写聊天界面

    第一步:在app/build.grandle添加RecyclerView依赖库 第二步:在activity_main.xml文件中编写主界面:聊天.发送框.发送按钮三个部分 第三步:编写Message ...

  5. Android学习之基础知识五—RecyclerView(滚动控件)

    RecyclerView可以说是增强版的ListView,不仅具有ListVIew的效果,还弥补许多ListView的不足. 一.RecyclerView的基本用法 与百分比布局类似,Recycler ...

  6. Android学习之基础知识五—ListView控件(最常用和最难用的控件)

    ListView控件允许用户通过上下滑动来将屏幕外的数据拉到屏幕内,把屏幕内的数据拉到屏幕外. 一.ListView的简单用法第一步:先创建一个ListViewTest项目,在activity_mia ...

  7. Android学习之基础知识五—Android常用的七大控件

    一.TextView控件:在界面上显示一段文本信息 先看XML代码和执行效果:         代码分析: 1.android:id属性,给当前控件定义了一个唯一的标识符 2.android:layo ...

  8. 【基础知识五】神经网络NN

    常用模型:BP神经网络,RBF神经网络 一.神经元模型 |  连接权,阈值,激活函数 1. 输入信号通过带权重的连接(connection)进行传递,神经元接收到的总输入值将与神经元的阈值进行比较, ...

  9. ASP&period;NET Core 2&period;2 基础知识&lpar;五&rpar; 环境

    一.环境变量 系统启动时,会读取环境变量 ASPNETCORE_ENVIRONMENT ,并将该变量的值存储在 IHostingEnvironment.EnvironmentName 字段中.如: 新 ...

  10. 数组、栈、堆&lpar;java基础知识五&rpar;

    1.数组概述.定义格式 * A:数组概念 数组是存储同一种数据类型多个元素的集合.也可以看成是一个容器. 数组既可以存储基本数据类型,也可以存储引用数据类型. * B:数组定义格式 格式1:数据类型[ ...

随机推荐

  1. JavaScript判断变量值简单的方法

    今天在看一个动态web表单设计器的时候发现项目中的 一个写法 function sum_total(v){ if (!v) { v= 0; } } !v  这是什么写法?不过可以肯定的是,这是一种判断 ...

  2. elecworks无法连接至协同服务器

    http://jingyan.baidu.com/article/597a0643759e1c312b524385.html 在安装路径中找到Server文件夹,在文件夹中你可以看到只有一个文件[Ew ...

  3. Eclipse 修改字体

  4. Android 开发UI牛博&lbrack;转&rsqb;

    Android 新兴的UI模式——侧边导航栏 侧边导航栏也就是大家熟知的SliddingMenu,英文也叫Fly-In App Menu.Side Navigation等.当然谷歌现在已经推出类似这个 ...

  5. C&plus;&plus;中public&comma;protected&comma;private访问

    对于公有继承方式: (1)父类的public成员成为子类的public成员,允许类以外的代码访问这些成员:(2)父类的private成员仍旧是父类的private成员,子类成员不可以访问这些成员:(3 ...

  6. c&plus;&plus; 定义宏常量

    #ifndef __GAME_DATA_H__ #define __GAME_DATA_H__ #ifndef GAME_IS_CREATE_SHOP #define GAME_IS_CREATE_S ...

  7. 北京教育软件创业公司招 &period;net工程师

    北京教育软件创业公司,招 .net工程师,月工资2万左右,有合适的朋友帮忙推荐下,要求水平稍高一些的.产品目前用Winform开发的.创始人两个清华,一个北大.老板在美国待了七年回来的,爱人在清华教书 ...

  8. 如何在宿主机上查看kvm虚拟机的IP

    # arp -a ? (:3c:ce::f2: [ether] on br0 gateway (:c8:ac:d5 [ether] on br0 ? (:d4:fc: [ether] on br0 ? ...

  9. &lbrack;转&rsqb; 理解 JavaScript 中的 Array&period;prototype&period;slice&period;apply&lpar;arguments&rpar;

    假如你是一个 JavaScript 开发者,你可能见到过 Array.prototype.slice.apply(arguments) 这样的用法,然后你会问,这么写是什么意思呢? 这个语法其实不难理 ...

  10. StringBuild类

    每次拼接都会产生新的字符串对象,从而产生很多废弃的垃圾,拼的越多,垃圾越多,而利用StringBuilder来拼接字符串自始至终用的都是同一个StringBuilder容器 StringBuilder ...