2008-12-01 38 views
37

Tôi có phần tử canvas được định nghĩa tĩnh trong html với chiều rộng và chiều cao. Nếu tôi cố gắng sử dụng JavaScript để định lại kích thước động (thiết lập chiều rộng và chiều cao mới - hoặc trên các thuộc tính của canvas hoặc thông qua thuộc tính kiểu), tôi nhận được lỗi sau trong Firefox:Làm cách nào để thay đổi kích thước phần tử canvas html?

uncaught exception: [Exception ... "Hoạt động bất hợp pháp trên đối tượng nguyên mẫu WrappedNative" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" vị trí: "JS frame :: file: ///home/russh/Desktop/test.html :: onclick :: line 1" dữ liệu: no]

Có thể thay đổi kích thước thành phần này hoặc tôi có phải hủy phần tử đó và tạo thành phần tử mới khi đang bay không?

+0

Thực tế thông báo lỗi có vẻ như bạn đã cố thay đổi thuộc tính 'chiều rộng' hoặc' chiều cao 'của' HTMLCanvasElement.prototype' trực tiếp. Tôi không biết làm thế nào điều này có thể được thực hiện vô tình. – Robert

+0

Hãy xem triển khai của tôi: http://stackoverflow.com/a/23128583/1265753 – karaxuna

Trả lời

53

Bạn đã không xuất bản mã của mình và tôi nghi ngờ bạn đã làm điều gì đó sai. có thể thay đổi kích thước bằng cách chỉ định thuộc tính chiều rộng và chiều cao bằng cách sử dụng số:

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

Ít nhất nó cũng phù hợp với tôi. Đảm bảo bạn không chỉ định chuỗi (ví dụ: "2cm", "3in" hoặc "2.5px") và không gây rối với phong cách.

Thực ra đây là kiến ​​thức công khai có sẵn — bạn có thể đọc tất cả về nó trong the HTML canvas spec — nó rất nhỏ và thông tin bất thường. Đây là giao diện DOM toàn:

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); 
}; 

Như bạn có thể nhìn thấy nó định nghĩa 2 thuộc tính widthheight, và cả hai trong số đó là unsigned long.

+21

Lưu ý: khi bạn thay đổi kích thước canvas, dường như xóa canvas (ít nhất là trong chrome). – RobKohr

+3

có. Tôi đồng ý. Có cách nào để thay đổi kích cỡ khung hình trong khi cũng thay đổi kích thước (mở rộng) các hình ảnh bên trong nó không? – Alexis

+0

Sẽ hữu ích khi đăng một ví dụ về cách sử dụng này trên jsfiddle. –

3

này làm việc cho tôi chỉ là bây giờ:

<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> 
+0

Ở đây là trên jsfiddle: http://jsfiddle.net/J8PyU/ –

14

Tôi chỉ có vấn đề tương tự như bạn, nhưng phát hiện ra về phương pháp toDataURL, mà tỏ ra hữu ích.

Ý chính của nó là biến canvas hiện tại của bạn thành dataURL, thay đổi kích thước canvas của bạn và sau đó vẽ những gì bạn đã quay lại canvas từ dataURL bạn đã lưu.

Vì vậy, đây là mã của tôi:

var oldCanvas = canvas.toDataURL("image/png"); 
var img = new Image(); 
img.src = oldCanvas; 
img.onload = function(){ 
    canvas.height += 100; 
    ctx.drawImage(img, 0, 0); 
} 
+4

ctx.getImageData() và ctx.putImageData() là trọng lượng nhẹ hơn và được thiết kế cho tác vụ này. – fuzzyTew

+0

@fuzzyTôi khá chắc chắn rằng việc sử dụng '' 'getImageData()' '' và '' 'putImageData()' '' sẽ hiệu quả, nhưng sẽ sao chép pixel theo pixel, do đó không thu nhỏ dữ liệu hình ảnh cũ, trong khi sử dụng '' 'drawImage()' '' sẽ cho phép mở rộng. – snapfractalpop

+0

Tại sao lại sử dụng 'toDataUrl'? Điều này gây ra chuyển đổi dữ liệu không cần thiết (raw => png). Thay vào đó, bạn có thể sử dụng 'drawImage' hai lần. –

1

Đây là nỗ lực của tôi để đưa ra một câu trả lời hoàn chỉnh hơn (xây dựng trên @ john của câu trả lời).

Vấn đề ban đầu mà tôi gặp phải là thay đổi chiều rộng và chiều cao của nút canvas (sử dụng kiểu), dẫn đến nội dung chỉ bị "thu nhỏ" hoặc "thu nhỏ". Đây không phải là hiệu ứng mong muốn.

Vì vậy, giả sử bạn muốn vẽ hai hình chữ nhật có kích thước tùy ý trong canvas có kích thước 100px x 100px.

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

Để đảm bảo rằng hình chữ nhật sẽ không vượt quá kích thước của canvas và do đó không hiển thị, bạn cần đảm bảo rằng canvas đủ lớn.

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); 

Cuối cùng, đây là jsfiddle cho điều này: http://jsfiddle.net/Rka6D/4/.

13

Lưu ý rằng nếu canvas của bạn được khai báo tĩnh, bạn nên sử dụng thuộc tính widthheight, không phải kiểu, ví dụ: này sẽ làm việc:

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

Nhưng điều này sẽ không công việc:

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

Nguyên mẫu có thể là một rắc rối để làm việc với, và từ _PROTO phần của lỗi nó xuất hiện lỗi của bạn là do bởi, giả sử, HTMLCanvasElement.prototype.width, có thể là một nỗ lực để thay đổi kích thước tất cả canvases cùng một lúc.

Như một gợi ý, nếu bạn đang cố gắng để thay đổi kích thước một số bức tranh sơn dầu cùng một lúc, bạn có thể thử:

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

Trong JavaScript, thay vì gọi một nguyên mẫu, thử điều này:

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

Điều này sẽ thay đổi kích thước tất cả canvas bằng cách thêm 100 px vào kích thước của chúng, như được minh họa trong this example


Hy vọng điều này sẽ hữu ích.

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> 
Các vấn đề liên quan