Warum tut Leinwand putImageData nicht funktionieren, wenn ich angeben Zielort?
Versuchen, die Dokumentation für den Canvas-Kontext ist putImageData () - Methode, die ich gefunden habe, Dinge wie diese:
Kontext.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
(aus http://www.w3schools.com/tags/canvas_putimagedata.asp)
Entsprechend der Dokumentation habe ich gelesen, dass x und y einen index in der Quelle Bild, in der Erwägung, dass dirtyX und dirtyY geben Sie Koordinaten im Ziel-canvas zu zeichnen, wo das Bild. Doch, wie sehen Sie aus dem nachfolgenden Beispiel (und JSFiddle) ein Aufruf putImageData(imgData,x,y) arbeitet, während putImageData(imgData, 0, 0, locX, locY) nicht. Ich bin mir nicht sicher, warum.
EDIT:
Ich denke, meine eigentliche Frage ist, warum in der oberen Zeile wird das Bild schwarz, und es gibt nur 7 Zeilen, nicht 8. Die Bilder sollten beginnen Sie an der oberen linken Ecke der Leinwand. Sie beginnen auf der linken Seite (und haben 8 Spalten). Warum Sie nicht starten Sie an der Spitze?
Antwort:, dass aufgrund der Division durch 0, die auf dieser Linie, wenn yLoc 0:
xoff = imgWidth / (yLoc/3);
Der JSFiddle:
Code:
<html>
<head>
<title>Canvas tutorial</title>
<script type="text/javascript">
var canvas;
var context; //The canvas's 2d context
function setupCanvas()
{
canvas = document.getElementById('myCanvas');
if (canvas.getContext)
{
context = canvas.getContext('2d');
context.fillStyle = "black"; //this is default anyway
context.fillRect(0, 0, canvas.width, canvas.height);
}
}
function init()
{
loadImages();
startGating();
}
var images = new Array();
var gatingTimer;
var curIndex, imgWidth=0, imgHeight;
//Load images
function loadImages()
{
for (n = 1; n <= 16; n++)
{
images[n] = new Image();
images[n].src = "qxsImages/frame" + n + ".png";
// document.body.appendChild(images[n]);
console.log("width = " + images[n].width + ", height = " + images[n].height);
}
curIndex = 1;
imgWidth = images[1].width;
imgHeight = images[1].height;
}
function redrawImages()
{
if (imgWidth == 0)
return;
curIndex++;
if (curIndex > 16)
curIndex = 1;
//To do later: use images[1].width and .height to layout based on image size
for (var x=0; x<8; x++)
{
for (var y=0; y<8; y++)
{
//if (x != 1)
// context.drawImage(images[curIndex], x*150, y*100);
// context.drawImage(images[curIndex], x*150, y*100, imgWidth/2, imgHeight/2); //scale
// else
self.drawCustomImage(x*150, y*100);
}
}
}
function drawCustomImage(xLoc, yLoc)
{
//create a new pixel array
imageData = context.createImageData(imgWidth, imgHeight);
pos = 0; //index position into imagedata array
xoff = imgWidth / (yLoc/3); //offsets to "center"
yoff = imgHeight / 3;
for (y = 0; y < imgHeight; y++)
{
for (x = 0; x < imgWidth; x++)
{
//calculate sine based on distance
x2 = x - xoff;
y2 = y - yoff;
d = Math.sqrt(x2*x2 + y2*y2);
t = Math.sin(d/6.0);
//calculate RGB values based on sine
r = t * 200;
g = 125 + t * 80;
b = 235 + t * 20;
//set red, green, blue, and alpha:
imageData.data[pos++] = Math.max(0,Math.min(255, r));
imageData.data[pos++] = Math.max(0,Math.min(255, g));
imageData.data[pos++] = Math.max(0,Math.min(255, b));
imageData.data[pos++] = 255; //opaque alpha
}
}
//copy the image data back onto the canvas
context.putImageData(imageData, xLoc, yLoc); //Works... kinda
// context.putImageData(imageData, 0, 0, xLoc, yLoc, imgWidth, imgHeight); //Doesn't work. Why?
}
function startGating()
{
gatingTimer = setInterval(redrawImages, 1000/25); //start gating
}
function stopGating()
{
clearInterval(gatingTimer);
}
</script>
<style type="text/css">
canvas { border: 1px solid black; }
</style>
</head>
<body onload="setupCanvas(); init();">
<canvas id="myCanvas" width="1200" height="800"></canvas>
</body>
</html>
- Was sollte gezeigt werden? Läuft das Beispiel hier bekam ich einen schwarzen hintergrund mit einigen blauen Bilder mit den weißen Kreisen drin. Könnte Sie post ein Bild mit dem zu erwartenden Ergebnis (oder etwas ähnliches)?
- In der oberen Zeile des Bildes ist schwarz, sollte aber einige der blau/weiß-Bilder in es.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie hatte gerade Ihre Koordinaten rückwärts.
Live-Demo
xLoc
, undyLoc
sind, wo Sie setzen es, und0,0,imgWidth,imgHeight
ist die Daten-Sie setzen auf die Leinwand.Ein weiteres Beispiel , die dies zeigen.
Viele der online-docs scheint ein bisschen widersprüchlich, aber für die sieben param version
dx und dy sind Ihrem Ziel, in den nächsten vier Parameter sind die dirty rect-Parameter, im Grunde controlling was Sie zeichnen von die Quelle canvas. Eine der ausführlichsten Beschreibungen, die ich finden kann, wurde in dem Buch HTML5 Unleashed von Simon Sarris (pg. 165).
xoff = imgWidth / (yLoc / 3);
division durch 0 wirft die ganze Obere Reihe, nichts zu tun mitputImageData
zum Glück. jsfiddle.net/loktar/WZynM/5, ich änderte es zuxoff = imgWidth/3
nur zu illustrieren.Dass mit dieser vor kurzem habe ich entdeckt, dass Loktar oben getroffen hat, auf ein SEHR wichtiges Thema. Im Grunde, einige Dokumentation dieser Methode online ist falsch, ein besonders gefährliches Beispiel dafür ist W3Schools, zu denen eine Reihe von Menschen wird es wiederum für die Referenz.
Ihre Dokumentation besagt Folgendes:
Inhalt:
Argumente:
Als Loktar Staaten vor, die RICHTIGE synopsis ist wie folgt:
Richtige Synopsis:
Argumente:
Verwenden Sie die richtige synopsis oben, und Sie haben nicht die Probleme, die aufgetreten sind oben.
Gebe ich einen großen Hut Spitze Loktar für finden zunächst, aber ich dachte, es treffend zu liefern eine erweiterte Antwort im Fall, dass andere in das selbe problem.