Как изменить размер HTML-элемента холста? - PullRequest
44 голосов
/ 01 декабря 2008

У меня есть элемент холста, определенный статически в HTML с шириной и высотой. Если я пытаюсь использовать JavaScript для динамического изменения его размера (устанавливая новую ширину и высоту - либо для атрибутов холста, либо через свойства стиля), я получаю следующую ошибку в Firefox:

необработанное исключение: [Exception ... "Недопустимая операция с объектом-прототипом WrappedNative" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" расположение: "JS frame :: file: ///home/russh/Desktop/test.html onclick :: строка 1 "данные: нет]

Можно ли изменить размер этого элемента или я должен уничтожить его и создать новый элемент на лету?

Ответы [ 7 ]

63 голосов
/ 01 декабря 2008

Вы не опубликовали свой код, и я подозреваю, что вы что-то делаете не так. можно изменить размер, назначив атрибуты ширины и высоты с помощью чисел:

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

По крайней мере, у меня это работает. Убедитесь, что вы не назначаете строки (например, «2 см», «3 дюйма» или «2,5 пикселя») и не путаетесь со стилями.

На самом деле это общедоступные знания & mdash; Вы можете прочитать все об этом в спецификации HTML canvas & mdash; это очень маленький и необычайно информативный. Это весь интерфейс 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 атрибута width и height, и оба они unsigned long.

20 голосов
/ 02 декабря 2011

Обратите внимание, что если ваш холст объявлен статически, вы должны использовать атрибуты width и height, а не стиль, например. это будет работать:

<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>
14 голосов
/ 02 апреля 2011

У меня была такая же проблема, как и у вас, но я узнал о методе 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);
}
5 голосов
/ 04 февраля 2013
<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>
4 голосов
/ 01 декабря 2008

Это сработало для меня только сейчас:

<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>
1 голос
/ 16 ноября 2011

Вот мое усилие дать более полный ответ (основываясь на ответе @ john).

Первоначальная проблема, с которой я столкнулся, заключалась в изменении ширины и высоты узла холста (с использованием стилей), в результате чего содержимое просто "увеличивалось" или "уменьшалось". Это не был желаемый эффект.

Итак, скажем, вы хотите нарисовать два прямоугольника произвольного размера на холсте размером 100 на 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/.

0 голосов
/ 15 января 2013

Прототипы могут быть хлопотными для работы, и из части _PROTO ошибки, кажется, ваша ошибка вызвана, скажем, HTMLCanvasElement.prototype.width, возможно, как попытка изменить размер всех полотен одновременно. *

В качестве рекомендации, если вы пытаетесь изменить размер нескольких полотен одновременно, вы можете попробовать:

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

В JavaScript вместо вызова прототипа попробуйте следующее:

$$ = 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;
}

Это позволит изменить размер всех полотен, добавив к их размеру 100 пикселей, как показано в этом примере


Надеюсь, это помогло.
...