Canvas 在 firefox 上绘制图像问题,在 chrome 中运行良好
Canvas Draw Image issue on firefox, works well in chrome
我认为这是某种兼容性问题。
在 chrome 中一切正常,但在 firefox 中 <canvas>
根本不绘制任何东西。
function drawStage(stageNum) {
var cap = canvasArray.length; //keeps the canvasElements
var i;
var stageImages = images["stage" + stageNum];
var stageDimensions = imageDimensions["stage" + stageNum];
//console.log("Cap is: " + cap);
for (i = 0; i < cap; i++) {
var canvas = document.getElementById(canvasArray[i]);
var canvasContext = canvas.getContext("2d");
var image = document.getElementById(stageImages[i]);
canvasContext.clearRect(0, 0, 1280, 1280);
canvasContext.drawImage(image, stageDimensions[i][0], stageDimensions[i][1], stageDimensions[i][2], stageDimensions[i][3]);
//document.getElementById(zIndexes[i][0]).style["z-index"] = zIndexes[i][stageNum];
//console.log(document.getElementById(zIndexes[i][0]).id);
}
}
编辑: here 是我制作的 "test" 代码示例的保管箱 link,更简单,1 张图像,1 canvas, 1 div, 类似(几乎相同)的脚本,在 firefox 中仍然不能工作,但在 chrome 中工作。如果你能解决那里的问题,那么这个问题也就解决了。
更新: 数组如下,根据请求,它们是不同 elements/coordinates 的简单输入。不过我向你保证,数组本身没有问题,在 chrome 中一切正常。函数中的 DrawImage() 方法导致了我要说的问题。 (数组下方有进一步解释)
images 是 <img>
元素的(全局)id 数组。
var images = {
stage1: ["character1Base", "character2Base", "character3Base", "character4Base", "character5Base", "character6Base", "character3BotImg"],
stage2: ["character1Sit", "character2Base", "character3Base", "character4Base", "character5Base", "character6Base", "character3BotImg"],
stage3: ["character1Sit", "character2Drink", "character3Base", "character4Base", "character5Base", "character6Base", "character3BotImg"],
stage4: ["character1Sit", "character2Drink", "character3Base", "character4Base", "character5Base", "character6Doll", "character3BotImg"],
stage5: ["character1Sit", "character2Drink", "character3Eat", "character4Base", "character5Base", "character6Doll", "character3EatBot"],
stage6: ["character1Sit", "character2Stand", "character3Eat", "character4Base", "character5Base", "character6Doll", "character3EatBot"],
stage7: ["character1Sit", "character2Stand", "character3Eat", "character4Sit", "character5Base", "character6Doll", "character3EatBot"],
stage8: ["character1Sit", "character2Stand", "character3Eat", "character4Sit", "character5Sit", "character6Doll", "character3EatBot"],
stage9: ["character1Sit", "character2Eat", "character3Eat", "character4Sit", "character5Sit", "character6Doll", "character3EatBot"],
stage10: ["character1Drink", "character2Eat", "character3Eat", "character4Sit", "character5Sit", "character6Doll", "character3EatBot"]
};
imageDimensions 是 well、dimensions、posX、posY、sizeX 和 sizeY 的(全局)数组。
var imageDimensions = {
stage1: [[0, 0, 233, 485], [0, 0, 153, 407], [20, 0, 220, 200], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 0, 220, 180]],
stage2: [[105, 35, 180, 440], [0, 0, 153, 407], [20, 0, 220, 200], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 0, 220, 180]],
stage3: [[105, 35, 180, 440], [0, 0, 153, 407], [20, 0, 220, 200], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 0, 220, 180]],
stage4: [[105, 35, 180, 440], [0, 0, 153, 407], [20, 0, 220, 200], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 0, 220, 180]],
stage5: [[105, 35, 180, 440], [0, 0, 153, 407], [3, 7, 226, 180], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 9, 220, 180]],
stage6: [[105, 35, 180, 440], [0, 0, 172, 490], [3, 7, 226, 180], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 9, 220, 180]],
stage7: [[105, 35, 180, 440], [0, 0, 172, 490], [3, 7, 226, 180], [70, 0, 341, 380], [0, 0, 315, 391], [0, 0, 480, 435], [1, 9, 220, 180]],
stage8: [[105, 35, 180, 440], [0, 0, 172, 490], [3, 7, 226, 180], [70, 0, 341, 380], [18, 72, 305, 422], [0, 0, 480, 435], [1, 9, 220, 180]],
stage9: [[105, 35, 180, 440], [0, 0, 173, 473], [3, 7, 226, 180], [70, 0, 341, 380], [18, 72, 305, 422], [0, 0, 480, 435], [1, 9, 220, 180]],
stage10: [[105, 32, 162, 440], [0, 0, 173, 473], [3, 7, 226, 180], [70, 0, 341, 380], [18, 72, 305, 422], [0, 0, 480, 435], [1, 9, 220, 180]]
};
解释:
该功能旨在以不同的元素在屏幕上绘制,
属于这些元素的字符。它们绘制于 canvas
(稍后也会在 canvas 中进行动画处理)。 stageNum
即
该函数采用的唯一参数决定了将绘制什么。
有人知道问题出在哪里吗? (我读过一些类似的帖子,但所有问题都是鼠标位置的 layerX、layerY,但是我在这里根本没有使用 mouseover / mousein / mouseout,仍然没有绘制元素。
您的问题是您尝试绘制的图像是 svg 图像,并且这些 svg 文档具有相对的 width
和 height
属性。
浏览器无法为其必须绘制的图像设置高度或宽度,因此无法将其呈现给 canvas。 (它能够在文档中进行估计,因为它可以与某物相关,但不能在 canvas 中)。
因此解决方案是在您的 svg 文件中设置绝对 width
和 height
属性,
或者更复杂,首先将其绘制成 <iframe>
或 <object>
,然后绘制一个序列化版本,您将在其中设置这些属性。
function initialize() {
var canvas = document.getElementById("char1Canvas");
var canvasContext = canvas.getContext("2d");
var image = document.getElementById("char1Img");
resizeSVG(image, function(e){
canvasContext.clearRect(0, 0, 1280, 1280);
canvasContext.drawImage(this, 0, 0);
});
};
var resizeSVG = function(svgImg, callback){
// create an iframe
var iframe = document.createElement('iframe');
// so we don't see it
iframe.height = 0;
iframe.width = 0;
iframe.onload = function(){
var doc = iframe.contentDocument;
var svg = doc.querySelector('svg');
// get the computed width and height of your img element
// should probably be tweaked
var bbox = svgImg.getBoundingClientRect();
// if it's a relative width
if (svg.width.baseVal.unitType !== 1) {
svg.setAttribute('width', bbox.width);
}
// or a relative height
if (svg.height.baseVal.unitType !== 1) {
svg.setAttribute('height', bbox.height);
}
// serialize our updated svg
var svgData = (new XMLSerializer()).serializeToString(svg);
var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);
// create a new Image Object that ill be draw on the canvas
var img = new Image();
img.onload = callback;
img.src = svgURL;
// remove the iframe
document.body.removeChild(iframe);
};
iframe.src = svgImg.src;
document.body.appendChild(iframe);
}
我认为这是某种兼容性问题。
在 chrome 中一切正常,但在 firefox 中 <canvas>
根本不绘制任何东西。
function drawStage(stageNum) {
var cap = canvasArray.length; //keeps the canvasElements
var i;
var stageImages = images["stage" + stageNum];
var stageDimensions = imageDimensions["stage" + stageNum];
//console.log("Cap is: " + cap);
for (i = 0; i < cap; i++) {
var canvas = document.getElementById(canvasArray[i]);
var canvasContext = canvas.getContext("2d");
var image = document.getElementById(stageImages[i]);
canvasContext.clearRect(0, 0, 1280, 1280);
canvasContext.drawImage(image, stageDimensions[i][0], stageDimensions[i][1], stageDimensions[i][2], stageDimensions[i][3]);
//document.getElementById(zIndexes[i][0]).style["z-index"] = zIndexes[i][stageNum];
//console.log(document.getElementById(zIndexes[i][0]).id);
}
}
编辑: here 是我制作的 "test" 代码示例的保管箱 link,更简单,1 张图像,1 canvas, 1 div, 类似(几乎相同)的脚本,在 firefox 中仍然不能工作,但在 chrome 中工作。如果你能解决那里的问题,那么这个问题也就解决了。
更新: 数组如下,根据请求,它们是不同 elements/coordinates 的简单输入。不过我向你保证,数组本身没有问题,在 chrome 中一切正常。函数中的 DrawImage() 方法导致了我要说的问题。 (数组下方有进一步解释)
images 是 <img>
元素的(全局)id 数组。
var images = {
stage1: ["character1Base", "character2Base", "character3Base", "character4Base", "character5Base", "character6Base", "character3BotImg"],
stage2: ["character1Sit", "character2Base", "character3Base", "character4Base", "character5Base", "character6Base", "character3BotImg"],
stage3: ["character1Sit", "character2Drink", "character3Base", "character4Base", "character5Base", "character6Base", "character3BotImg"],
stage4: ["character1Sit", "character2Drink", "character3Base", "character4Base", "character5Base", "character6Doll", "character3BotImg"],
stage5: ["character1Sit", "character2Drink", "character3Eat", "character4Base", "character5Base", "character6Doll", "character3EatBot"],
stage6: ["character1Sit", "character2Stand", "character3Eat", "character4Base", "character5Base", "character6Doll", "character3EatBot"],
stage7: ["character1Sit", "character2Stand", "character3Eat", "character4Sit", "character5Base", "character6Doll", "character3EatBot"],
stage8: ["character1Sit", "character2Stand", "character3Eat", "character4Sit", "character5Sit", "character6Doll", "character3EatBot"],
stage9: ["character1Sit", "character2Eat", "character3Eat", "character4Sit", "character5Sit", "character6Doll", "character3EatBot"],
stage10: ["character1Drink", "character2Eat", "character3Eat", "character4Sit", "character5Sit", "character6Doll", "character3EatBot"]
};
imageDimensions 是 well、dimensions、posX、posY、sizeX 和 sizeY 的(全局)数组。
var imageDimensions = {
stage1: [[0, 0, 233, 485], [0, 0, 153, 407], [20, 0, 220, 200], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 0, 220, 180]],
stage2: [[105, 35, 180, 440], [0, 0, 153, 407], [20, 0, 220, 200], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 0, 220, 180]],
stage3: [[105, 35, 180, 440], [0, 0, 153, 407], [20, 0, 220, 200], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 0, 220, 180]],
stage4: [[105, 35, 180, 440], [0, 0, 153, 407], [20, 0, 220, 200], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 0, 220, 180]],
stage5: [[105, 35, 180, 440], [0, 0, 153, 407], [3, 7, 226, 180], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 9, 220, 180]],
stage6: [[105, 35, 180, 440], [0, 0, 172, 490], [3, 7, 226, 180], [0, 150, 505, 210], [0, 0, 315, 391], [0, 0, 480, 435], [1, 9, 220, 180]],
stage7: [[105, 35, 180, 440], [0, 0, 172, 490], [3, 7, 226, 180], [70, 0, 341, 380], [0, 0, 315, 391], [0, 0, 480, 435], [1, 9, 220, 180]],
stage8: [[105, 35, 180, 440], [0, 0, 172, 490], [3, 7, 226, 180], [70, 0, 341, 380], [18, 72, 305, 422], [0, 0, 480, 435], [1, 9, 220, 180]],
stage9: [[105, 35, 180, 440], [0, 0, 173, 473], [3, 7, 226, 180], [70, 0, 341, 380], [18, 72, 305, 422], [0, 0, 480, 435], [1, 9, 220, 180]],
stage10: [[105, 32, 162, 440], [0, 0, 173, 473], [3, 7, 226, 180], [70, 0, 341, 380], [18, 72, 305, 422], [0, 0, 480, 435], [1, 9, 220, 180]]
};
解释:
该功能旨在以不同的元素在屏幕上绘制,
属于这些元素的字符。它们绘制于 canvas
(稍后也会在 canvas 中进行动画处理)。 stageNum
即
该函数采用的唯一参数决定了将绘制什么。
有人知道问题出在哪里吗? (我读过一些类似的帖子,但所有问题都是鼠标位置的 layerX、layerY,但是我在这里根本没有使用 mouseover / mousein / mouseout,仍然没有绘制元素。
您的问题是您尝试绘制的图像是 svg 图像,并且这些 svg 文档具有相对的 width
和 height
属性。
浏览器无法为其必须绘制的图像设置高度或宽度,因此无法将其呈现给 canvas。 (它能够在文档中进行估计,因为它可以与某物相关,但不能在 canvas 中)。
因此解决方案是在您的 svg 文件中设置绝对 width
和 height
属性,
或者更复杂,首先将其绘制成 <iframe>
或 <object>
,然后绘制一个序列化版本,您将在其中设置这些属性。
function initialize() {
var canvas = document.getElementById("char1Canvas");
var canvasContext = canvas.getContext("2d");
var image = document.getElementById("char1Img");
resizeSVG(image, function(e){
canvasContext.clearRect(0, 0, 1280, 1280);
canvasContext.drawImage(this, 0, 0);
});
};
var resizeSVG = function(svgImg, callback){
// create an iframe
var iframe = document.createElement('iframe');
// so we don't see it
iframe.height = 0;
iframe.width = 0;
iframe.onload = function(){
var doc = iframe.contentDocument;
var svg = doc.querySelector('svg');
// get the computed width and height of your img element
// should probably be tweaked
var bbox = svgImg.getBoundingClientRect();
// if it's a relative width
if (svg.width.baseVal.unitType !== 1) {
svg.setAttribute('width', bbox.width);
}
// or a relative height
if (svg.height.baseVal.unitType !== 1) {
svg.setAttribute('height', bbox.height);
}
// serialize our updated svg
var svgData = (new XMLSerializer()).serializeToString(svg);
var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);
// create a new Image Object that ill be draw on the canvas
var img = new Image();
img.onload = callback;
img.src = svgURL;
// remove the iframe
document.body.removeChild(iframe);
};
iframe.src = svgImg.src;
document.body.appendChild(iframe);
}