我正在开发一个小地图编辑器,只是为了有趣地了解HTML5 Canvas并且更好一些。
我想做什么
我正在尝试加载3项:
我写了一个函数“drawItem(item)”,它应该在画布上绘制一个项目:
drawItem = function(item) {
var imageObj = new Image();
imageObj.onload = function() {
var pattern = context.createPattern(imageObj, 'repeat');
context.rect(gridSize*item.position[0], gridSize*item.position[1], gridSize, gridSize);
context.fillStyle = pattern;
context.fill();
};
imageObj.src = item.img;
};
项目对象是什么样的:
itemOne = {
img : 'https://lh3.googleusercontent.com/ZX4Zl7JT1gkgOVA9FbMFnMAw7TC9bBCVMSGWKFTmOW88vDTgcCOb7tBBo60nxoSdHQ=s190',
position : [0, 0] //these get multiplied with "gridSize" in the drawItem-function
};
现在问题出在这里:
如果我使用item-object调用此函数,则会正确绘制对象。
如果我使用3个不同的物品对象调用此功能3次(参见JS-Fiddle),那么2个摇滚物品似乎在它上面有一个妖精。那是错的。
JS-小提琴
“问题”
有谁知道这个问题?我一直在谷歌搜索几个小时,但由于我不确定要搜索什么,所以很难找到。
非常感谢! 鲍里斯
答案 0 :(得分:2)
您可以使用drawImage
drawItem = function(item) {
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, gridSize*item.position[0], gridSize*item.position[1])
};
imageObj.src = item.img;
};
答案 1 :(得分:2)
你可能应该使用drawImage作为另一个回答者说,但为了完整起见,让我告诉你为什么你的原始代码是错误的。
在此代码中:
var pattern = context.createPattern(imageObj, 'repeat');
context.rect(gridSize*item.position[0], gridSize*item.position[1], gridSize, gridSize);
context.fillStyle = pattern;
context.fill();
您正在向当前路径添加rect
,然后填充当前路径。
当您致电rect
然后fill
,然后使用不同的矩形调用rect
然后再次调用fill
时,第二个fill
命令正在填充<你所定义的rects> strong 。
这是因为rect
总是在当前路径上添加一个额外的矩形。
因此修复代码的一种方法是添加一行,调用beginPath()
,这将重置路径,这样每次绘制时都不会继续添加代码:
var pattern = context.createPattern(imageObj, 'repeat');
context.beginPath();
context.rect(gridSize*item.position[0], gridSize*item.position[1], gridSize, gridSize);
context.fillStyle = pattern;
context.fill();
所以看起来应该是这样的: http://jsfiddle.net/rSVkb/6/
答案 2 :(得分:1)
如果您确实想继续使用模式,则需要切换为使用fillRect
而不是创建矩形并使用fill
:
drawItem = function(item) {
var imageObj = new Image();
imageObj.onload = function() {
var pattern = context.createPattern(imageObj, 'repeat');
context.fillStyle = pattern;
context.fillRect(gridSize*item.position[0], gridSize*item.position[1], gridSize, gridSize);
};
imageObj.src = item.img;
};
.fill
将当前模式应用于已经填充的整个上下文。继续使用模式将允许您连续绘制多个像:
itemOne = {
img : 'https://lh3.googleusercontent.com/ZX4Zl7JT1gkgOVA9FbMFnMAw7TC9bBCVMSGWKFTmOW88vDTgcCOb7tBBo60nxoSdHQ=s190',
position : [0, 0], //these get multiplied with "gridSize" in the drawItem-function
howManyX: 2,
howManyY: 1
};
// And then in drawImage
context.fillRect(gridSize*item.position[0], gridSize*item.position[1], gridSize*(item.howManyX || 1), gridSize*(item.howManyY || 1));
并将其用作fillRect
中最后两个参数的修饰符。
或者,您可以对this等项目执行多次positions
。您也可以使用.drawImage
执行此操作,但模式只需要进行一次。这个jsperf表明使用模式可以更快。