Как изменить размер элемента html canvas?
У меня есть элемент холста, определенный статически в html с шириной и высотой. Если я попытаюсь использовать JavaScript для динамического изменения размера (установка новой ширины и высоты - либо по атрибутам холста, либо через свойства стиля), я получаю следующую ошибку в Firefox:
uncaught exception: [Exception... "Незаконная операция на WrappedNative prototype object" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" location: "JS frame:: file:///home/russh/Desktop/test.html:: onclick:: line 1" data: no]
Можно ли изменить размер этого элемента или мне нужно его уничтожить и создать новый элемент "на лету"?
Ответы
Ответ 1
Вы не опубликовали свой код, и я подозреваю, что вы что-то сделали неправильно. можно изменить размер, назначив атрибуты width и height с помощью чисел:
canvasNode.width = 200; // in pixels
canvasNode.height = 100; // in pixels
По крайней мере, это работает для меня. Убедитесь, что вы не назначаете строки (например, "2 см", "3 дюйма" или "2,5 пикселя" ) и не соприкасаетесь со стилями.
На самом деле это общедоступное знание -— вы можете прочитать все об этом в спецификации холста HTML — он очень маленький и необычайно информативный. Это весь интерфейс 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
.
Ответ 2
У меня была такая же проблема, как у вас, но я узнал о методе 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);
}
Ответ 3
Обратите внимание, что если ваш холст статически объявлен, вы должны использовать атрибуты 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>
Ответ 4
<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>
Ответ 5
Это сработало для меня только сейчас:
<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>
Ответ 6
Здесь мое усилие дать более полный ответ (построив ответ @john).
Первоначальная проблема, с которой я столкнулась, заключалась в изменении ширины и высоты холста node (с использованием стилей), в результате содержимое просто "увеличилось" или "сжалось". Это не было желательным эффектом.
Итак, скажем, вы хотите нарисовать два прямоугольника произвольного размера в холсте размером 100px на 100px.
<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/.
Ответ 7
Прототипы могут быть трудными для работы, и из _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 пикселей к их размеру, как показано в в этом примере
Надеюсь, это помогло.