我有2个画布,一个使用HTML属性宽度和高度来调整它的大小,另一个使用CSS:

<canvas id="compteur1" width="300" height="300" onmousedown="compteurClick(this.id);"></canvas>
<canvas id="compteur2" style="width: 300px; height: 300px;" onmousedown="compteurClick(this.id);"></canvas>

Compteur1正常显示,但compteur2不正常。内容使用JavaScript在300x300的画布上绘制。

为什么会有显示差异?


当前回答

浏览器使用css的宽度和高度,但canvas元素根据画布的宽度和高度缩放。在javascript中,读取css的宽度和高度,并设置画布的宽度和高度。

var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();

其他回答

Shannimal校正

var el = $('#mycanvas');
el.attr('width', parseInt(el.css('width')))
el.attr('height', parseInt(el.css('height')))

浏览器使用css的宽度和高度,但canvas元素根据画布的宽度和高度缩放。在javascript中,读取css的宽度和高度,并设置画布的宽度和高度。

var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();

如果你在CSS中设置了宽度和高度,画布将被拉伸。如果你想动态地操纵画布的尺寸,你必须像这样使用JavaScript:

canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');

我相信CSS有更好的机制来指定画布的大小,CSS必须决定样式,而不是JavaScript或HTML。话虽如此,在HTML中设置宽度和高度对于解决canvas问题很重要。

CSS有一个重要的规则,允许重写属性的其他样式规则,包括HTML中的规则。通常,它的使用是不受欢迎的,但这里的使用是合法的。

在WebAssembly的Rust模块中,你可以做以下事情:

fn update_buffer(canvas: &HtmlCanvasElement) {
    canvas.set_width(canvas.client_width() as u32);
    canvas.set_height(canvas.client_height() as u32);
}

//.. 
#[wasm_bindgen(start)]
pub fn start() -> Result<(), JsValue> {
    // ...
    let canvas: Rc<_> = document
        .query_selector("canvas")
        .unwrap()
        .unwrap()
        .dyn_into::<HtmlCanvasElement>()
        .unwrap()
        .into();
    update_buffer(&canvas);
    // ...

    // create resizing handler for window
    {
        let on_resize = Closure::<dyn FnMut(_)>::new(move |_event: Event| {
            let canvas = canvas.clone();
            // ...

            update_buffer(&canvas);
            // ...
        window.add_event_listener_with_callback("resize", on_resize.as_ref().unchecked_ref())?;
        on_resize.forget();
    }
}

在那里,一旦WASM模块被加载,我们就更新画布缓冲区,然后每当窗口大小被调整时。我们通过手动指定画布的宽度和高度作为clientWidth和clientHeight的值来做到这一点。也许有更好的方法来更新缓冲区,但我相信这个解决方案比@SamB, @CoderNaveed, @Anthony Gedeon, @Bluerain, @Ben Jackson, @Manolo, @XaviGuardia, @Russel Harkins和@fermar的建议更好,因为

元素的样式是CSS,而不是HTML。 不像@Manolo使用的element .style.width & element .style.height技巧或@XaviGuardia使用的JQuery等效,它将工作于画布,其大小由使用指定为flex或网格项。 不像@Russel Harkings的解决方案,这也处理调整大小。虽然我喜欢他的答案,因为它真的是干净和简单。 WASM是未来!哈哈:D

另外,有大量的.unwrap(),因为Rust显式地处理可能的失败。

P.P.S.

    {
        let on_resize = Closure::<dyn FnMut(_)>::new(move |_event: Event| {
            let canvas = canvas.clone();
            // ...

            update_buffer(&canvas);
            // ...
        window.add_event_listener_with_callback("resize", on_resize.as_ref().unchecked_ref())?;
        on_resize.forget();
    }

使用更好的库可以更干净地完成。如。

add_resize_handler(&window, move |e: ResizeEvent| {
  let canvas = canvas.clone();
  // ...

  update_buffer(&canvas);
})

CSS设置画布元素的宽度和高度,因此它会影响坐标空间,使所有内容都倾斜绘制

下面是我如何用Vanilla JavaScript设置宽度和高度的方法

canvas.width = numberForWidth

canvas.height = numberForHeight