2016-03-30 182 views
0

我正在使用Pixel Grid Canvas在JavaScript中繪製東西。我將所有的東西都按照它的樣子運行,但只能在Firefox上運行,並且只能在刷新頁面後才能使用。異步加載問題

我的問題是:爲什麼這隻會給刷新後正確的輸出,我該怎麼做才能使它在第一次嘗試時具有正確的輸出。

function PixelGridCanvas(){ 
 
\t this.init = function(canvas, ps, gs, pc, gc){ 
 
\t \t this.ctx = canvas.getContext("2d"); 
 
\t \t this.pixelSize = ps; 
 
\t \t this.gridSize = gs; 
 
\t \t 
 
\t \t this.gridWidth = canvas.width/ps; 
 
\t \t this.gridHeight = canvas.height/ps; 
 
\t \t 
 
\t \t if(this.gridWidth <= 1) this.gridWidth = 1; 
 
\t \t if(this.gridHeight <= 1) this.gridHeight = 1; 
 
\t \t 
 
\t \t this.pixelColor = pc; 
 
\t \t this.gridColor = gc; 
 
\t }; 
 
\t 
 
\t this.clearCanvas = function(){ 
 
\t \t \t 
 
\t \t \t this.ctx.fillStyle = this.pixelColor; 
 
\t \t \t this.ctx.fillRect(0,0, (this.gridWidth * this.pixelSize) - this.pixelSize, (this.gridHeight * this.pixelSize) - this.pixelSize); 
 
\t \t \t 
 
\t \t \t this.ctx.fillStyle = this.gridColor; 
 
\t \t \t var drawLine = false; 
 
\t \t \t 
 
\t \t \t for(var i = 0; i < this.gridWidth * 2; i++){ 
 
\t \t \t \t if(drawLine) this.ctx.fillRect(i * this.pixelSize,0, this.pixelSize, ((this.gridHeight * this.pixelSize) * 2) + this.pixelSize); 
 
\t \t \t \t drawLine = !drawLine; 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t var drawLine = false; 
 
\t \t \t for(var i = 0; i < this.gridHeight * 2; i++){ 
 
\t \t \t \t if(drawLine) this.ctx.fillRect(0,i * this.pixelSize, ((this.gridWidth * this.pixelSize) * 2) - this.pixelSize, this.pixelSize); 
 
\t \t \t \t drawLine = !drawLine; 
 
\t \t \t } 
 
\t }; 
 
\t 
 
\t this.drawImageAt = function(src, destx, desty){ 
 
\t \t console.log("drawImage"); 
 
\t \t var img = new Image(); 
 
\t \t img.src = src; 
 
\t \t var icanvas = document.createElement('canvas'); 
 
\t \t icanvas.width = img.width; 
 
\t \t icanvas.height = img.height; 
 
\t \t var ictx = icanvas.getContext('2d'); 
 
\t \t ictx.drawImage(img, 0, 0, img.width, img.height); 
 
\t \t 
 
\t \t for(var x = 0; x < icanvas.width; x++){ 
 
\t \t \t for(var y = 0; y < icanvas.height; y++){ 
 
\t \t \t \t 
 
\t \t \t \t //console.log("pixel"); 
 
\t \t \t \t 
 
\t \t \t \t var pixel = ictx.getImageData(x, y, 1, 1); 
 
\t \t \t \t var data = pixel.data; 
 
\t \t \t \t var rgba = 'rgba(' + data[0] + ',' + data[1] + 
 
\t \t \t \t \t \t \t ',' + data[2] + ',' + data[3] + ')'; 
 
\t \t \t \t \t \t \t 
 
\t \t \t \t this.ctx.fillStyle = rgba; 
 
\t \t \t \t this.ctx.fillRect((destx * this.pixelSize) + (x * this.pixelSize) + (x * this.pixelSize), (desty * this.pixelSize) + (y * this.pixelSize) + (y * this.pixelSize), this.pixelSize, this.pixelSize); 
 
\t \t \t \t 
 
\t \t \t } 
 
\t \t } 
 
\t }; 
 
\t 
 
\t this.drawImage = function(src){ 
 
\t \t this.drawImageAt(src,0,0); 
 
\t }; 
 
}
<html> 
 
\t <head> 
 
\t <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> 
 
\t <script src="js/pgc/main.js"></script> 
 
\t 
 
\t <script> 
 
\t $(document).ready(function() { 
 
\t \t var c = document.getElementById("myCanvas"); 
 
\t \t var pgc = new PixelGridCanvas(); 
 
\t \t pgc.init(c, 2, 2, "#eeeeee", "#ffffff"); 
 
\t \t 
 
\t \t pgc.clearCanvas(); 
 
\t \t pgc.drawImage("imgs/test1.png"); 
 
\t \t 
 
\t \t pgc.drawImageAt("imgs/test1.png", 50,50); 
 
\t }); 
 
\t </script> 
 
\t \t 
 
\t </head> 
 
\t <body> 
 
\t \t <canvas id="myCanvas" width="320" height="320"></canvas> 
 
\t \t 
 
\t \t 
 
\t </body> 
 
</html>

這裏有一個鏈接在我的個人網站運行: http://pgc.00ffff3.com/

編輯:

封閉在該圖像的onload事件繪製功能,但它仍然做同樣的事情。我理解這個錯誤嗎?

this.drawImageAt = function(src, destx, desty){ 
 
\t \t console.log("drawImage"); 
 
\t \t var img = new Image(); 
 
\t \t 
 
\t \t img.onload = function() { 
 
\t \t \t var icanvas = document.createElement('canvas'); 
 
\t \t \t icanvas.width = img.width; 
 
\t \t \t icanvas.height = img.height; 
 
\t \t \t var ictx = icanvas.getContext('2d'); 
 
\t \t \t ictx.drawImage(img, 0, 0, img.width, img.height); 
 
\t \t \t 
 
\t \t \t for(var x = 0; x < icanvas.width; x++){ 
 
\t \t \t \t for(var y = 0; y < icanvas.height; y++){ 
 
\t \t \t \t \t 
 
\t \t \t \t \t //console.log("pixel"); 
 
\t \t \t \t \t 
 
\t \t \t \t \t var pixel = ictx.getImageData(x, y, 1, 1); 
 
\t \t \t \t \t var data = pixel.data; 
 
\t \t \t \t \t var rgba = 'rgba(' + data[0] + ',' + data[1] + 
 
\t \t \t \t \t \t \t \t ',' + data[2] + ',' + data[3] + ')'; 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t this.ctx.fillStyle = rgba; 
 
\t \t \t \t \t this.ctx.fillRect((destx * this.pixelSize) + (x * this.pixelSize) + (x * this.pixelSize), (desty * this.pixelSize) + (y * this.pixelSize) + (y * this.pixelSize), this.pixelSize, this.pixelSize); 
 
\t \t \t \t \t 
 
\t \t \t \t } 
 
\t \t \t } 
 
\t \t } 
 
\t \t 
 
\t \t img.src = src; 
 
\t };

+0

問題的標題仍然保留一個選項來關閉**「爲什麼這段代碼不工作」的原因。 –

回答

1

主要的原因是因爲你的圖像加載是異步的所以您的代碼工作,你的圖像,您嘗試繪製它之前必須加載。您可以預先加載JS中的圖像,然後在所有圖像加載成功時觸發drawImageAt方法。

+0

請參閱編輯。我嘗試使用.onload,但它沒有奏效。謝謝你嘗試,雖然 – CyanPrime

+0

現在,它不工作刷新。 –

+0

好的,在添加onload之後,「this」指向錯誤的位置。通過在onload之前添加「var me = this」來修復它。非常感謝你的幫助:D – CyanPrime