javascript 画布 - IndexSizeError:索引或大小为负或大于允许的数量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19338032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Canvas - IndexSizeError: Index or size is negative or greater than the allowed amount
提问by brandongray
So in Firefox I'm getting this error in the console when using drawImage on a canvas element.
因此,在 Firefox 中,当在画布元素上使用 drawImage 时,我在控制台中收到此错误。
"IndexSizeError: Index or size is negative or greater than the allowed amount"
Everything is working fine in Chrome. Common causes for this I found were returning negative values or trying to draw the image to the canvas before the image is actually loaded. Neither of which seem to be the case. What am I missing here?
在 Chrome 中一切正常。我发现这种情况的常见原因是返回负值或尝试在实际加载图像之前将图像绘制到画布上。这两种情况似乎都不是。我在这里错过了什么?
Any ideas would be greatly appreciated. http://jsfiddle.net/Ra9KQ/3/
任何想法将不胜感激。http://jsfiddle.net/Ra9KQ/3/
var NameSpace = NameSpace || {};
NameSpace.Pixelator = (function() {
var _cache = {
'wrapper' : null,
'canvas' : null,
'ctx' : null,
'img' : new Image()
},
_config = {
'canvasWidth' : 250,
'canvasHeight' : 250,
'isPlaying' : false,
'distortMin' : 3,
'distortMax' : 100,
'distortValue' : 100, // matches distortMax by default
'initDistortValue' : 3,
'speed' : 2.5,
'delta' : 2.5, // delta (+/- step), matches speed by default
'animation' : null,
'origImgWidth' : null,
'origImgHeight' : null,
'imgHeightRatio' : null,
'imgWidthRatio' : null,
'newImgWidth' : null,
'newImgHeight' : null
},
_init = function _init() {
_setupCache();
_setupCanvas();
_setupImage();
},
_setupCache = function _setupCache() {
_cache.wrapper = $('#dummy-wrapper');
_cache.canvas = document.getElementById('dummy-canvas');
_cache.ctx = _cache.canvas.getContext('2d');
},
_setupCanvas = function _setupCanvas() {
_cache.ctx.mozImageSmoothingEnabled = false;
_cache.ctx.webkitImageSmoothingEnabled = false;
_cache.ctx.imageSmoothingEnabled = false;
},
_setupImage = function _setupImage() {
_cache.img.onload = function() {
_adjustImageScale();
_pixelate();
_assignEvents();
};
_cache.img.src = _cache.canvas.getAttribute('data-src');
},
_adjustImageScale = function _adjustImageScale() {
var scaledHeight,
scaledWidth;
_config.origImgWidth = _cache.img.width;
_config.origImgHeight = _cache.img.height;
_config.imgHeightRatio = _config.origImgHeight / _config.origImgWidth;
_config.imgWidthRatio = _config.origImgWidth / _config.origImgHeight;
scaledHeight = Math.round(250 * _config.imgHeightRatio);
scaledWidth = Math.round(250 * _config.imgWidthRatio);
if (scaledHeight < 250) {
_config.newImgHeight = 250;
_config.newImgWidth = Math.round(_config.newImgHeight * _config.imgWidthRatio);
} else if (scaledWidth < 250) {
_config.newImgWidth = 250;
_config.newImgHeight = Math.round(_config.newImgWidth * _config.imgHeightRatio);
}
},
_assignEvents = function _assignEvents() {
_cache.wrapper.on('mouseenter', _mouseEnterHandler);
_cache.wrapper.on('mouseleave', _mouseLeaveHandler);
},
_mouseEnterHandler = function _mouseEnterHandler(e) {
_config.delta = -_config.speed;
if (_config.isPlaying === false) {
_config.isPlaying = true;
_animate();
}
},
_mouseLeaveHandler = function _mouseLeaveHandler(e) {
_config.delta = _config.speed;
if (_config.isPlaying === false) {
_config.isPlaying = true;
_animate();
}
},
_pixelate = function _pixelate(val) {
var size = val ? val * 0.01 : 1,
w = Math.ceil(_config.newImgWidth * size),
h = Math.ceil(_config.newImgHeight * size);
console.log('w: ' + w,'h: ' + h,'_config.newImgWidth: ' + _config.newImgWidth,'_config.newImgHeight: ' + _config.newImgHeight);
_cache.ctx.drawImage(_cache.img, 0, 0, w, h);
_cache.ctx.drawImage(_cache.canvas, 0, 0, w, h, 0, 0, _config.canvasWidth, _config.canvasHeight);
},
_animate = function _animate() {
// increase/decrese with delta set by mouse over/out
_config.distortValue += _config.delta;
if (_config.distortValue >= _config.distortMax || _config.distortValue <= _config.distortMin) {
_config.isPlaying = false;
cancelAnimationFrame(_config.animation);
return;
} else {
// pixelate
_pixelate(_config.distortValue);
_config.animation = requestAnimationFrame(_animate);
}
};
return {
init: _init
};
})();
NameSpace.Pixelator.init();
采纳答案by brandongray
When you are using clipping you need to make sure that the source region is within the image (not necessary for target as this will be clipped by canvas).
当您使用剪辑时,您需要确保源区域在图像内(目标不需要,因为这将被画布剪辑)。
So if you add restriction control it should work. Here is one way of doing this (before using the clipping functionality of drawImage
):
因此,如果您添加限制控制,它应该可以工作。这是执行此操作的一种方法(在使用 的剪辑功能之前drawImage
):
if (w > _config.canvasWidth) w = _config.canvasWidth;
if (h > _config.canvasHeight) h = _config.canvasHeight;
_cache.ctx.drawImage(_cache.canvas, 0, 0, w, h,
0, 0, _config.canvasWidth, _config.canvasHeight);
Tip 1:
Normally this also applies to x and y but as these are 0 here there is no need to check.
提示 1:
通常这也适用于 x 和 y,但由于此处为 0,因此无需检查。
Tip 2:
If you need the image to be drawn narrower than you need to instead of changing source region, change the target region.
提示 2:
如果您需要将图像绘制得比您需要的更窄,而不是更改源区域,请更改目标区域。
回答by moka
Widthand Heightof image you draw when you specify size values should be larger or equal to 1. As well for performance advantages floor
all values you pass to it.
If width and/or height is 0, it will result in:
指定大小值时绘制的图像的宽度和高度应大于或等于 1。对于性能优势,floor
您传递给它的所有值也是如此。
如果宽度和/或高度为 0,它将导致:
IndexSizeError: Index or size is negative or greater than the allowed amount
In Firefox:
在 Firefox 中:
width = Math.max(1, Math.floor(width));
height = Math.max(1, Math.floor(height));
ctx.drawImage(image, x, y, width, height);
回答by Draeli
To help others, I had the same problem in canvas and I solve taking account on image load, for example :
为了帮助其他人,我在画布上遇到了同样的问题,我解决了考虑图像加载的问题,例如:
var image = new Image();
image.crossOrigin = "use-credentials";
image.onload = function(){
// here canvas behavior
};
image.src = imgSrc;
回答by Mahdi
I had the same problem but in IEand Safari. There were three things in particular that I had to fix:
我有同样的问题,但在IE和Safari 中。我特别需要解决三件事:
1) I had to set the width
and height
of the image manually.
1)我必须手动设置图像的width
和height
。
var image = new Image();
...
image.width = 34;
image.height = 34;
2) I had to avoid using negative offset when creating ol.style.Icon
. In this case I had to change my SVG icon, but that pretty much depends to your icon. So this would cause exception because of the negative offset:
2)我在创建ol.style.Icon
. 在这种情况下,我不得不更改我的 SVG 图标,但这在很大程度上取决于您的图标。所以这会因为负偏移量而导致异常:
var icon = new ol.style.Style({
"image": new ol.style.Icon({
...
"offset": [0, -50]
})
});
3) I had to roundthe width and height values. As some of them were calculated dynamically, I had values like 34.378
which were causing problems. So I had to round them and pass the Integervalue.
3)我不得不舍入宽度和高度值。由于其中一些是动态计算的,因此我有34.378
一些会导致问题的值。所以我不得不对它们进行四舍五入并传递整数值。