55

我在 html 中静态定义了一个具有宽度和高度的画布元素。如果我尝试使用 JavaScript 动态调整它的大小(设置新的宽度和高度 - 在画布的属性上或通过样式属性)我在 Firefox 中收到以下错误:

未捕获的异常:[异常...“对 WrappedNative 原型对象的非法操作”nsresult:“0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)”位置:“JS 框架 :: file:///home/russh/Desktop/test.html :: onclick ::第 1 行”数据:无]

是否可以调整这个元素的大小,或者我必须销毁它并动态创建一个新元素?

4

7 回答 7

74

你没有发布你的代码,我怀疑你做错了什么。可以通过使用数字分配宽度和高度属性来更改大小:

canvasNode.width  = 200; // in pixels
canvasNode.height = 100; // in pixels

至少它对我有用。确保您没有指定字符串(例如,“2cm”、“3in”或“2.5px”),并且不要弄乱样式。

实际上这是一个公开的知识——你可以在HTML canvas 规范中阅读所有关于它的信息——它非常小而且信息量非常大。这是整个 DOM 接口:

interface HTMLCanvasElement : HTMLElement {
           attribute unsigned long width;
           attribute unsigned long height;

  DOMString toDataURL();
  DOMString toDataURL(in DOMString type, [Variadic] in any args);

  DOMObject getContext(in DOMString contextId);
};

如您所见,它定义了 2 个属性widthheight,它们都是unsigned long.

于 2008-12-01T17:02:01.847 回答
22

请注意,如果您的画布是静态声明的,则应使用widthandheight属性,而不是样式,例如。这将起作用:

<canvas id="c" height="100" width="100" style="border:1px"></canvas>
<script>
    document.getElementById('c').width = 200;
</script>

但这不起作用

<canvas id="c" style="width: 100px; height: 100px; border:1px"></canvas>
<script>
    document.getElementById('c').width = 200;
</script>
于 2011-12-01T22:46:59.673 回答
14

我刚刚遇到了和你一样的问题,但是发现了 toDataURL 方法,它被证明是有用的。

它的要点是将你当前的画布变成一个 dataURL,改变你的画布大小,然后从你保存的 dataURL 中将你的内容重新绘制到画布中。

所以这是我的代码:

var oldCanvas = canvas.toDataURL("image/png");
var img = new Image();
img.src = oldCanvas;
img.onload = function (){
    canvas.height += 100;
    ctx.drawImage(img, 0, 0);
}
于 2011-04-02T15:12:12.507 回答
5
<div id="canvasdiv" style="margin: 5px; height: 100%; width: 100%;">
    <canvas id="mycanvas" style="border: 1px solid red;"></canvas>
</div>
<script>
$(function(){
    InitContext();
});
function InitContext()
{
var $canvasDiv = $('#canvasdiv');

var canvas = document.getElementById("mycanvas");
canvas.height = $canvasDiv.innerHeight();
canvas.width = $canvasDiv.innerWidth();
}
</script>
于 2013-02-04T08:24:42.193 回答
4

这刚刚对我有用:

<canvas id="c" height="100" width="100" style="border:1px solid red"></canvas>
<script>
var c = document.getElementById('c');
alert(c.height + ' ' + c.width);
c.height = 200;
c.width = 200;
alert(c.height + ' ' + c.width);
</script>
于 2008-12-01T17:04:09.610 回答
1

这是我提供更完整答案的努力(基于@john 的答案)。

我遇到的最初问题是更改画布节点的宽度和高度(使用样式),导致内容只是“缩放”或“缩小”。这不是预期的效果。

因此,假设您想在 100 x 100 像素的画布中绘制两个任意大小的矩形。

<canvas width="100" height="100"></canvas>

为确保矩形不会超过画布的大小并因此不可见,您需要确保画布足够大。

var $canvas = $('canvas'),
    oldCanvas,
    context = $canvas[0].getContext('2d');

function drawRects(x, y, width, height)
{
  if (($canvas.width() < x+width) || $canvas.height() < y+height)
  {
    oldCanvas = $canvas[0].toDataURL("image/png")
    $canvas[0].width = x+width;
    $canvas[0].height = y+height;

    var img = new Image();
    img.src = oldCanvas;
    img.onload = function (){
      context.drawImage(img, 0, 0);
    };
  }
  context.strokeRect(x, y, width, height);
}


drawRects(5,5, 10, 10);
drawRects(15,15, 20, 20);
drawRects(35,35, 40, 40);
drawRects(75, 75, 80, 80);

最后,这是 jsfiddle:http: //jsfiddle.net/Rka6D/4/

于 2011-11-15T21:18:03.803 回答
0

Prototypes can be a hassle to work with, and from the _PROTO part of the error it appears your error is caused by, say, HTMLCanvasElement.prototype.width, possibly as an attempt to resize all the canvases at once.

As a suggestion, if you are trying to resize a number of canvases at once, you could try:

<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<script type="text/javascript">
    ...
</script>

In the JavaScript, instead of invoking a prototype, try this:

$$ = function(){
    return document.querySelectorAll.apply(document,arguments);
}
for(var i in $$('canvas')){
    canvas = $$('canvas')[i];
    canvas.width = canvas.width+100;
    canvas.height = canvas.height+100;
}

This would resize all the canvases by adding 100 px to their size, as is demonstrated in this example


Hope this helped.

于 2013-01-15T01:42:17.167 回答