In den vorherigen Ausgaben ging es ausschließlich um das Zeichnen von Pfadgrafiken. In diesem Abschnitt werden wir darüber sprechen, wie man Bilder auf Leinwand manipuliert, da Grafiken keine schönen Mädchen zeichnen können (dies wird von Zeichenexperten ignoriert). Was soll ich tun, wenn ich Willst du schöne Mädchen zeichnen? Folge mir:
Um ein Bild in die Leinwand einzufügen, benötigen wir als Methode diesen Helden:
drawImage() Ein Bild, eine Leinwand oder ein Video auf die Leinwand zeichnen
Dieser Held kann Es wird gesagt, dass er über so viele einzigartige Fähigkeiten und tiefe innere Stärke verfügt, dass man ihn als den Meister unter den Meistern bezeichnen kann:
Cheats 1:
drawImage(img ,x,y) Suchen Sie ein Bild auf der Leinwand
Parameter: img repräsentiert das importierte Bildobjekt, x, y repräsentiert die importierten Koordinaten
ps: img repräsentiert hier das Bildobjekt und nicht den Pfad des image , was darauf hinweist, dass das Bild nicht direkt zitiert werden kann, sondern durch Bedienung des DOM referenziert werden muss
Die oben genannten Tipps beziehen sich auf die Besonderheit des Bildes. Wie erhalten wir das Bild? Beginnen wir mit dem Einfachsten:
<canvas width="500" height="400" id="canvas"> <span>亲,您的浏览器不支持canvas,换个浏览器试试吧!</span> </canvas> <img src="2.jpg" alt="" id="img">
Wir legen ein Bild auf die Seite (das Milchtee-Mädchen von damals, oh damals), holen uns dann das Bild und bringen es auf die Leinwand
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var oImg = document.getElementById("img"); ctx.drawImage(oImg,10,10);
Sehen Sie, das Milchtee-Mädchen außerhalb der Leinwand ist jetzt leider auf unsere Leinwand gegangen Schwester ist nicht mehr das aktuelle Milchtee-Mädchen. Einige Klassenkameraden werden sagen: „Ich möchte nur, dass mein Milchtee-Mädchen auf meiner Leinwand ist“ und möchte nicht, dass sie woanders zu sehen ist Ich? Wolltuch? Clevere Schüler müssen es herausgefunden haben, kann ich die Bilder nicht einfach draußen verstecken? Ist es in Ordnung, es einfach zu verstecken?
<img src="2.jpg" alt="" id="img" style="display:none;">
Das Milchtee-Mädchen auf der rechten Seite ist weg. Ja, Ich möchte dieses Bild auf der Seite haben und das DOM-Element abrufen können. Es spielt keine Rolle, ob das Bild angezeigt wird Sie selbst und fügen Sie es in ein p ein. p wird ausgeblendet, im Canvas-Tag platziert (da der Inhalt im Browser, der Canvas unterstützt, nicht angezeigt wird) usw. Sie können Bilder auch mit reinem js hinzufügen:
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); }
Geheimtipp 2:
drawImage(img,x,y,w,h) Positionieren Sie das Bild auf der Leinwand und Geben Sie die Breite und Höhe des Bildes an
Parameter: img repräsentiert das importierte Bildobjekt, x, y repräsentiert die importierten Koordinaten, w, h repräsentiert die angegebene Bildgröße
Einige Schüler werden das sagen Milk Tea Girl ist gut, aber meine Leinwand ist zu klein, Milk Tea Girl ist zu groß (wo ist es zu groß), das Bild ist zu groß, es füllt im Grunde meine Leinwand aus. Wenn ich andere Formen auf die Leinwand zeichne, würde es das tun Wäre das nicht eine Schande für Milk Tea Girl und könnte es sie kleiner machen? Haha, drawImage hat die Transformationsfähigkeit von Sun Wukong. Es kann groß oder klein sein, schauen Sie hier:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var oImg = document.getElementById("img"); ctx.drawImage(oImg,10,10,200,150);
Schau, das Milchtee-Mädchen ist plötzlich kleiner geworden und ich kann nicht klar sehen, nicht die anderen schlechten Klassenkameraden Okay? Natürlich können Sie
Cheat-Tipp 3
drawImage(img,sX,sY,sWidth,sHeight,x,y,width,height) die Leinwand ausschneiden und den ausgeschnittenen Teil auf der Leinwand positionieren
Parameter: img repräsentiert das importierte Bildobjekt, sX, sY repräsentiert die tatsächlichen Koordinaten des Ausschnitts, sWidth, sHeight repräsentiert die Breite und Höhe des Ausschnitts, x, y repräsentiert die Koordinaten der Platzierung des Bildes auf der Leinwand, width, height repräsentiert Das zu verwendende Bild.
Obwohl es oben viele Parameter gibt, ist es dennoch leicht zu verstehen, wie man das Milchtee-Mädchen ausschneidet:
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);
Nari, warum ist das Milchtee-Mädchen dick geworden? Als ich mir die Parameter noch einmal ansah, stellte ich fest, dass die letzte Breite und Höhe zu diesem Zeitpunkt eine andere Bedeutung als die vorherigen w und h haben. Sie geben nun an, wie groß das zugeschnittene Bild angezeigt werden muss, wenn es größer als die zugeschnittene Breite und Höhe ist , es wird gezogen. Wenn es kleiner als die zugeschnittene Breite und Höhe ist, wird es auf die gleiche Größe wie die zugeschnittene Größe angepasst:
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);
Ja, das ist es. Das x und y dahinter geben die Position an, an der das zugeschnittene Bild angezeigt wird. Gehen wir in die Mitte und werfen einen Blick darauf
ctx.drawImage(oImg,150,0,150,300,150,10,150,300);
所以在使用裁剪功能的时候,要特别注意,图片的坐标和宽高和原来的意思有区别了
秘籍四
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);
当视频设置为autoplay时:
可以看到,右侧视频在播放,左侧没有什么反应,那怎么来播放视频呢?我们可以加一个定时器,然后每隔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)
不想让画布外的视频显示的方法跟图片是一样的,这里我就不细说了
除了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();
使用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();
可以比较看出,后面画的圆只显示在裁剪的圆的范围中,其他的都不见了,再看一个例子:
ctx.fillRect(50,50,200,100); ctx.clip(); ctx.beginPath(); ctx.fillStyle = 'green'; ctx.fillRect(100,100,200,100);
我们将圆改成实心的矩形,且是用的fillRect,而不是用fill,rect,结果是:
只显示第一个矩形,第二个矩形貌似不见了,而我们分开写:
//不用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();
上面的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)
我们画了一个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)
恩,跟前面的是一样的,创建了一个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);
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);
看,这么一对比,就知道这些参数是什么意思了,其中第二个我还得解释一下,如图小矩形,x,y依然是表示大的ImageData对象的起始坐标,dirtyX,dirtyY,dirtyWidth,dirtyHeight表示是相对于现在的x,y的起始坐标再来定义位置和大小,这么解释应该就明白了!
这就是操作像素的方法,看着很简单,也挺好理解,但是真正用起来,还是蛮费脑子的,我们先来看第一个小实例,改变像素的颜色:
实例效果,改变100*100的黑色矩形框中的第10行第10列的颜色,颜色为红色,先画个图分析一下:
从上面的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);
看,(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);
我们经常看到那种很炫酷的粒子文字,图形的效果,既然我们可以操作像素,如果我们只显示一部分的像素点,不就是粒子效果吗?看下面的例子:
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; }
上面的例子表示,我只显示当前的十分之一的像素,具体效果看这里——粒子图形
像素操作不仅仅只能操作图形,图片我们一样可以操作,这样我们就能做出更多的效果,看看下面的例子,我们将图像换成图片,看看能不能做出粒子图片:
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; }
这里我用的是二分之一的像素点,十分之一太少了,看得不明显,由此我们可以知道,也是可以来操作图片的像素点的,具体效果看这里 —— 图片粒子化
既然我们可以操作图片,那可以做的事就太多了,先看看下面这个例子,图片反色(即将原图片的像素颜色用相反的颜色替代):
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图片反色
用这个例子,我们还可以延伸一下,让它反色后,我们再加一个倒影,美女不明显,我们用山峰那张:
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]; }
细心的同学一定能看出它的原理,没错,就是在设置像素的时候,将它的像素方向反向,即此处“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]; }
核心代码就一个地方,255*i/h 给透明度乘以一个百分比的值,从0-255,也是很巧妙啊,具体效果看这里——canvas图片反色投影渐变
总结一下吧:虽然像素操作的方法不多,但是其功能之强大,是很多人都要望其项背的,关键在于人的想象力和深入的理解,要理解这样一个概念,掌握了像素操作,就好比是掌握了物体的核心本质,你就是造物者,你想造出什么东西,全凭你的想法,这里只是展示了一个很低劣的效果,旨在给大家展示一下canvas像素操作的魅力,抛砖引玉而已,后期会单独发一下canvas的像素操作的实例给大家参考,这个东西实在是太重要了!
好了,弄了几天了,终于写完了,本来想多写一点的,想想,后面再扩展吧!谢谢大家!
以上就是canvas API ,通俗的canvas基础知识(五) 的内容,更多相关内容请关注PHP中文网(www.php.cn)!