javascript - 异步加载问题

标签 javascript jquery html canvas

我正在开发一个 Pixel Grid Canvas,用于在 Javascript 中绘制内容。我让一切正常运行,但仅在 Firefox 上,并且仅在刷新页面后才起作用。

我的问题是:为什么这只能在刷新后给出正确的输出,我该怎么做才能使其在第一次尝试时获得正确的输出。

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

这是在我的个人网站上运行的链接: http://pgc.00ffff3.com/

编辑:

将绘制函数包含在图像的加载中,但它仍然执行相同的操作。难道是我理解错了?

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

最佳答案

主要原因是因为图像加载是异步的,因此为了使代码正常工作,必须在尝试绘制图像之前加载图像。您可以在 JS 中预加载图像,然后在所有图像加载成功后触发 drawImageAt 方法。

关于javascript - 异步加载问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36299684/

相关文章:

javascript - 如何使用 html、css 和 javascript 制作卡片 slider

javascript - 重新绘制谷歌地图以查看隐藏的移动标记

javascript - font Awesome 无法在 ie9 和 ie11 兼容模式下工作

JavaScript JSON 数据问题 - 警报未在每个循环中显示

javascript - 函数未定义

jquery - 切换不适用于所有选项卡和内联文本对齐

php - 制作链接提示 'save as'的简单方法

javascript - 如何在加载 View 之前调用函数?

Jquery Slider 无法在主页上运行

html - CSS - Google 字体 (Montserrat) 未覆盖 Bootstrap 标准字体