1. Übersicht
Canvas API (Canvas) wird zum Generieren von Bildern in Echtzeit auf Webseiten verwendet und kann Bildinhalte bearbeiten. Im Grunde handelt es sich um eine Bitmap, die mit JavaScript manipuliert werden kann. Bevor Sie es verwenden, müssen Sie zunächst ein neues
<canvas id="myCanvas" width="400" height="200"> 您的浏览器不支持canvas!</canvas>
Wenn der Browser diese API nicht unterstützt, wird im obigen Code der Text in der Mitte des
Jeder Canvas-Knoten verfügt über ein entsprechendes Kontextobjekt (Kontextobjekt). Die Canvas-API ist für dieses Kontextobjekt definiert, daher müssen Sie dieses Objekt mithilfe der getContext-Methode abrufen.
var canvas = document.getElementById('myCanvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); }
Im obigen Code gibt die getContext-Methode den Parameter 2d an, was bedeutet, dass der Canvas-Knoten zum Generieren von 2D-Mustern (d. h. flachen Mustern) verwendet wird. Wenn der Parameter webgl ist, bedeutet dies, dass er zum Generieren von 3D-Bildern (dh dreidimensionalen Mustern) verwendet wird. Dieser Teil wird eigentlich nur als WebGL-API bezeichnet.
2. Zeichenmethode
Leinwand bietet einen flachen Raum zum Zeichnen. x stellt die vertikale Koordinate dar. Der Ursprung (0, 0) befindet sich in der oberen linken Ecke des Bildes. Die positive Richtung der x-Achse verläuft rechts vom Ursprung und die positive Richtung der y-Achse verläuft vom Ursprung nach unten.
(1) Zeichnen eines Pfades
Die Methode „beginPath“ gibt den Beginn des Zeichnens eines Pfads an, die Methode „moveTo(x, y)“ legt den Startpunkt des Liniensegments fest, die Methode „lineTo(x, y)“. Legt den Endpunkt des Liniensegments fest. Strichmethode Wird zum Einfärben transparenter Liniensegmente verwendet.
ctx.beginPath(); // 开始路径绘制 ctx.moveTo(20, 20); // 设置路径起点,坐标为(20,20) ctx.lineTo(200, 20); // 绘制一条到(200,20)的直线 ctx.lineWidth = 1.0; // 设置线宽 ctx.strokeStyle = '#CC0000'; // 设置线的颜色 ctx.stroke(); // 进行线的着色,这时整条线才变得可见
Die Methoden moveto und lineto können mehrfach verwendet werden. Schließlich können Sie auch die Methode closePath verwenden, um automatisch eine gerade Linie vom aktuellen Punkt zum Startpunkt zu zeichnen, um eine geschlossene Figur zu bilden, sodass die Methode lineto nicht einmal verwendet werden muss.
(2) Zeichnen Sie ein Rechteck
Die Methode fillRect(x, y, width, height) wird zum Zeichnen eines Rechtecks verwendet. Seine vier Parameter sind die x-Koordinate und die y-Koordinate oben links Eckscheitelpunkt des Rechtecks sowie die Breite und Höhe des Rechtecks. Mit der Eigenschaft fillStyle wird die Füllfarbe des Rechtecks festgelegt.
ctx.fillStyle = 'yellow'; ctx.fillRect(50, 50, 200, 100);
Die StrokeRect-Methode ähnelt fillRect und wird zum Zeichnen hohler Rechtecke verwendet.
ctx.strokeRect(10,10,200,100);
Die Methode „clearRect“ wird verwendet, um den Inhalt eines rechteckigen Bereichs zu löschen.
ctx.clearRect(100,50,50,50);
(3) Text zeichnen
fillText(string, x, y) wird zum Zeichnen von Text verwendet. Seine drei Parameter sind der Textinhalt, die x-Koordinate des Startpunkts, und die y-Koordinate. Vor der Verwendung müssen Sie Schriftart, Größe und Stil mit Schriftart festlegen (die Schreibmethode ähnelt dem CSS-Schriftartattribut). Ähnlich gibt es die Methode „StrokeText“, mit der leere Wörter hinzugefügt werden.
ctx.font = "Bold 20px Arial"; // 设置字体 ctx.textAlign = "left";// 设置对齐方式 ctx.fillStyle = "#008600"; // 设置填充颜色 ctx.fillText("Hello!", 10, 50); // 设置字体内容,以及在画布上的位置 ctx.strokeText("Hello!", 10, 100); // 绘制空心字
Die fillText-Methode unterstützt keinen Textzeilenumbruch, d. h. der gesamte Text erscheint in einer Zeile. Wenn Sie also mehrere Textzeilen generieren möchten, können Sie die Methode fillText nur mehrmals aufrufen.
(4) Kreise und Sektoren zeichnen
Die Bogenmethode wird zum Zeichnen von Sektoren verwendet.
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
Die x- und y-Parameter der Bogenmethode sind die Koordinaten des Kreismittelpunkts, radius ist der Radius, startAngle und endAngle sind der Startwinkel und Endwinkel des Sektors (ausgedrückt im Bogenmaß). ), Gegen den Uhrzeigersinn bedeutet, dass die Zeichnung umgekehrt erfolgen soll Ob im Uhrzeigersinn (wahr) oder im Uhrzeigersinn (falsch) gezeichnet werden soll.
So zeichnen Sie einen Vollkreis:
ctx.beginPath(); ctx.arc(60, 60, 50, 0, Math.PI*2, true); ctx.fillStyle = "#000000"; ctx.fill();
Beispiel für das Zeichnen eines Hohlkreises:
ctx.beginPath(); ctx.arc(60, 60, 50, 0, Math.PI*2, true); ctx.lineWidth = 1.0; ctx.strokeStyle = "#000"; ctx.stroke();
(5) Legen Sie die Verlaufsfarbe fest
Die Methode createLinearGradient wird verwendet, um die Verlaufsfarbe festzulegen.
var myGradient = ctx.createLinearGradient(0, 0, 0, 160); myGradient.addColorStop(0, "#BABABA"); myGradient.addColorStop(1, "#636363");
Die Parameter der Methode „createLinearGradient“ sind (x1, y1, x2, y2), wobei x1 und y1 die Startpunktkoordinaten und x2 und y2 die Endpunktkoordinaten sind. Durch unterschiedliche Koordinatenwerte können Verläufe von oben nach unten, von links nach rechts usw. erzeugt werden. Die Verwendungsmethode ist wie folgt:
ctx.fillStyle = myGradient; ctx.fillRect(10,10,200,100);
(6) Einstellen des Schattens
Eine Reihe von schattenbezogenen Methoden können zum Festlegen des Schattens verwendet werden.
ctx.shadowOffsetX = 10; // 设置水平位移 ctx.shadowOffsetY = 10; // 设置垂直位移 ctx.shadowBlur = 5; // 设置模糊度 ctx.shadowColor = "rgba(0,0,0,0.5)"; // 设置阴影颜色 ctx.fillStyle = "#CC0000"; ctx.fillRect(10,10,200,100);
3. Bildverarbeitungsmethode
drawImage-Methode
Canvas-API ermöglicht das Einfügen von Bilddateien in die Leinwand. Die Methode besteht darin, das Bild zu lesen und die drawImage-Methode zu verwenden Führen Sie eine Neuzeichnung durch.
var img = new Image(); img.src = 'image.png'; ctx.drawImage(img, 0, 0); // 设置对应的图像对象,以及它在画布上的位置
Der obige Code lädt ein PNG-Bild in die Leinwand. Die Methode drawImage() akzeptiert drei Parameter. Der erste Parameter ist das DOM-Element der Bilddatei (d. h. der -Knoten). Der zweite und dritte Parameter sind die Koordinaten der oberen linken Ecke des Bildes Das obige Beispiel (0, 0) bedeutet, dass die obere linke Ecke des Bildes in der oberen linken Ecke der Leinwand platziert wird.
Da das Laden von Bildern Zeit braucht, kann die drawImage-Methode erst aufgerufen werden, nachdem das Bild vollständig geladen ist, sodass der obige Code neu geschrieben werden muss.
var image = new Image(); image.onload = function() { var canvas = document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height; canvas.getContext('2d').drawImage(image, 0, 0); // 插入页面底部 document.body.appendChild(image); return canvas; } image.src = 'image.png';
getImageData-Methode, putImageData-Methode
getImageData-Methode kann verwendet werden, um den Inhalt von Canvas zu lesen und ein Objekt zurückzugeben, das Informationen zu jedem Pixel enthält.
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
Das imageData-Objekt verfügt über ein Datenattribut und sein Wert ist ein eindimensionales Array. Der Wert dieses Arrays besteht aus den Rot-, Grün-, Blau- und Alphakanalwerten jedes Pixels nacheinander. Die Länge des Arrays entspricht also der Pixelbreite des Bildes x der Pixelhöhe des Bildes x 4. und der Bereich jedes Werts liegt zwischen 0 und 255. Dieses Array ist nicht nur lesbar, sondern auch beschreibbar. Durch Bearbeiten der Werte dieses Arrays können Sie also den Zweck der Bildbearbeitung erreichen. Nachdem Sie dieses Array geändert haben, verwenden Sie die Methode putImageData, um den Array-Inhalt auf der Leinwand neu zu zeichnen.
context.putImageData(imageData, 0, 0);
toDataURL-Methode
Nachdem Sie die Bilddaten geändert haben, können Sie die toDataURL-Methode verwenden, um die Canvas-Daten wieder in eine allgemeine Bilddateiform umzuwandeln.
function convertCanvasToImage(canvas) { var image = new Image(); image.src = canvas.toDataURL('image/png'); return image; }
Der obige Code konvertiert Canvas-Daten in PNG-Daten-URI.
Speichermethode, Wiederherstellungsmethode
Die Speichermethode wird verwendet, um den Kontext zu speichern, und die Wiederherstellungsmethode wird verwendet, um den zuletzt gespeicherten Kontext wiederherzustellen
ctx.save(); ctx.shadowOffsetX = 10; ctx.shadowOffsetY = 10; ctx.shadowBlur = 5; ctx.shadowColor = 'rgba(0,0,0,0.5)'; ctx.fillStyle = '#CC0000'; ctx.fillRect(10,10,150,100); ctx.restore(); ctx.fillStyle = '#000000'; ctx.fillRect(180,10,150,100);
上面代码先用save方法,保存了当前设置,然后绘制了一个有阴影的矩形。接着,使用restore方法,恢复了保存前的设置,绘制了一个没有阴影的矩形。
4.动画
利用JavaScript,可以在canvas元素上很容易地产生动画效果。
var posX = 20, posY = 100; setInterval(function() { context.fillStyle = "black"; context.fillRect(0,0,canvas.width, canvas.height); posX += 1; posY += 0.25; context.beginPath(); context.fillStyle = "white"; context.arc(posX, posY, 10, 0, Math.PI*2, true); context.closePath(); context.fill(); }, 30);
上面代码会产生一个小圆点,每隔30毫秒就向右下方移动的效果。setInterval函数的一开始,之所以要将画布重新渲染黑色底色,是为了抹去上一步的小圆点。
通过设置圆心坐标,可以产生各种运动轨迹。
先上升后下降。
var vx = 10, vy = -10, gravity = 1; setInterval(function() { posX += vx; posY += vy; vy += gravity; // ... });
上面代码中,x坐标始终增大,表示持续向右运动。y坐标先变小,然后在重力作用下,不断增大,表示先上升后下降。小球不断反弹后,逐步趋于静止。
var vx = 10, vy = -10, gravity = 1; setInterval(function() { posX += vx; posY += vy; if (posY > canvas.height * 0.75) { vy *= -0.6; vx *= 0.75; posY = canvas.height * 0.75; } vy += gravity; // ... });
上面代码表示,一旦小球的y坐标处于屏幕下方75%的位置,向x轴移动的速度变为原来的75%,而向y轴反弹上一次反弹高度的40%。
5.像素处理
通过getImageData方法和putImageData方法,可以处理每个像素,进而操作图像内容。假定filter是一个处理像素的函数,那么整个对Canvas的处理流程,可以用下面的代码表示。
if (canvas.width > 0 && canvas.height > 0) { var imageData = context.getImageData(0, 0, canvas.width, canvas.height); filter(imageData); context.putImageData(imageData, 0, 0); }
以下是几种常见的处理方法:
灰度效果
灰度图(grayscale)就是取红、绿、蓝三个像素值的算术平均值,这实际上将图像转成了黑白形式。假定d[i]是像素数组中一个象素的红色值,则d[i+1]为绿色值,d[i+2]为蓝色值,d[i+3]就是alpha通道值。转成灰度的算法,就是将红、绿、蓝三个值相加后除以3,再将结果写回数组。
grayscale = function (pixels) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { var r = d[i]; var g = d[i + 1]; var b = d[i + 2]; d[i] = d[i + 1] = d[i + 2] = (r+g+b)/3; } return pixels; };
复古效果
复古效果(sepia)则是将红、绿、蓝三个像素,分别取这三个值的某种加权平均值,使得图像有一种古旧的效果。
sepia = function (pixels) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { var r = d[i]; var g = d[i + 1]; var b = d[i + 2]; d[i] = (r * 0.393)+(g * 0.769)+(b * 0.189); // red d[i + 1] = (r * 0.349)+(g * 0.686)+(b * 0.168); // green d[i + 2] = (r * 0.272)+(g * 0.534)+(b * 0.131); // blue } return pixels; };
红色蒙版效果
红色蒙版指的是,让图像呈现一种偏红的效果。算法是将红色通道设为红、绿、蓝三个值的平均值,而将绿色通道和蓝色通道都设为0。
red = function (pixels) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { var r = d[i]; var g = d[i + 1]; var b = d[i + 2]; d[i] = (r+g+b)/3; // 红色通道取平均值 d[i + 1] = d[i + 2] = 0; // 绿色通道和蓝色通道都设为0 } return pixels; };
亮度效果
亮度效果(brightness)是指让图像变得更亮或更暗。算法将红色通道、绿色通道、蓝色通道,同时加上一个正值或负值。
brightness = function (pixels, delta) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { d[i] += delta; // red d[i + 1] += delta; // green d[i + 2] += delta; // blue } return pixels; };
反转效果
反转效果(invert)是指图片呈现一种色彩颠倒的效果。算法为红、绿、蓝通道都取各自的相反值(255-原值)。
invert = function (pixels) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { d[i] = 255 - d[i]; d[i+1] = 255 - d[i + 1]; d[i+2] = 255 - d[i + 2]; } return pixels; };