programing

CSS를 사용하면 캔버스가 늘어나지만 '너비'와 '높이' 속성은 정상입니다.

yellowcard 2023. 11. 1. 22:16
반응형

CSS를 사용하면 캔버스가 늘어나지만 '너비'와 '높이' 속성은 정상입니다.

2개의 캔버스가 있는데, 하나는 HTML 속성을 사용합니다.width그리고.height크기를 맞추기 위해 다른 하나는 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>

Competeur1은 표시해야 하지만 Competeur2는 표시되지 않습니다.콘텐츠는 300x300 캔버스에 자바스크립트를 이용하여 그려집니다.

디스플레이 차이가 나는 이유는 무엇입니까?

alt text

아무래도.width그리고.height속성은 캔버스의 좌표계의 너비 또는 높이를 결정하는 반면 CSS 속성은 표시될 상자의 크기만 결정합니다.

이는 HTML 규격에서 다음과 같이 설명됩니다.

canvaselement에는 element의 비트맵 크기를 제어할 수 있는 두 가지 속성이 있습니다.width그리고.height. 지정된 경우 이러한 특성에는 유효한 음이 아닌 정수의 값이 있어야 합니다.음수가 아닌 정수를 구문 분석하는 규칙을 사용하여 숫자 값을 구해야 합니다.속성이 없거나 값을 구문 분석하여 오류를 반환하는 경우 기본값을 대신 사용해야 합니다.width기본값을 300으로 지정합니다.height기본값은 150입니다.

설정 방법width그리고.height캔버스에서는 다음을 사용할 수 있습니다.

canvasObject.setAttribute('width', '150');
canvasObject.setAttribute('height', '300');

위해서<canvas>요소, CSS 규칙width그리고.height페이지에 그려질 캔버스 요소의 실제 크기를 설정합니다.반면에 HTML 속성은width그리고.height캔버스 API가 사용할 좌표계 또는 '그리드'의 크기를 설정합니다.

예를 들어, 다음을 생각해 보겠습니다(jsfiddle).

var ctx = document.getElementById('canvas1').getContext('2d');
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 30, 30);

var ctx2 = document.getElementById('canvas2').getContext('2d');
ctx2.fillStyle = "red";
ctx2.fillRect(10, 10, 30, 30);
canvas {
  border: 1px solid black;
}
<canvas id="canvas1" style="width: 50px; height: 100px;" height="50" width="100"></canvas>
<canvas id="canvas2" style="width: 100px; height: 100px;" height="50" width="100"></canvas>

둘 다 캔버스 요소의 내부 좌표를 기준으로 동일한 것을 그렸습니다.그러나 두 번째 캔버스에서는 CSS 규칙에 의해 캔버스 전체가 더 넓은 영역으로 확장되기 때문에 빨간색 직사각형의 폭이 두 배가 될 것입니다.

참고: CSS가 다음을 규정하는 경우width및/또는height지정되지 않으면 브라우저는 HTML 속성을 사용하여 이러한 값의 1단위가 페이지에서 1px가 되도록 요소의 크기를 조정합니다.이러한 특성을 지정하지 않으면 기본값은 a입니다.width300그리고.height150.

CSS에서 너비와 높이를 설정하면 캔버스가 늘어납니다.캔버스의 치수를 동적으로 조작하려면 다음과 같이 자바스크립트를 사용해야 합니다.

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

브라우저는 CSS 너비와 높이를 사용하지만 캔버스 요소는 캔버스 너비와 높이에 따라 확장됩니다.자바스크립트에서 cs 너비와 높이를 읽고 캔버스 너비와 높이를 설정합니다.

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

샤니멀 교정

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

캔버스는 이미지를 버퍼 단위로 렌더링하므로 너비와 높이를 지정하면 HTML은 버퍼 크기와 길이가 변경되지만 CSS를 사용하면 버퍼의 크기는 변경되지 않습니다.이미지를 확대하는 것.

HTML 크기 조정을 사용합니다.

캔버스 크기 변경 -> 버퍼 크기 변경 -> 렌더링

CSS 크기 조정 사용

캔버스 크기 변경 -> 렌더링

버퍼 길이는 변경되지 않은 상태로 유지되므로 컨텍스트가 영상을 렌더링할 때 영상이 크기가 조정된 캔버스에 표시됩니다(단, 변경되지 않은 버퍼에 렌더링됨).

CSS는 캔버스 요소의 너비와 높이를 설정하여 그려지는 모든 것을 치우치게 하는 좌표 공간에 영향을 줍니다.

바닐라 자바스크립트로 가로와 세로를 설정하는 방법은 다음과 같습니다.

canvas.width = numberForWidth

canvas.height = numberForHeight

저는 CSS가 캔버스 크기를 지정하는 데 훨씬 더 좋은 기계를 가지고 있고 CSS는 자바스크립트나 HTML이 아닌 스타일링을 결정해야 한다고 생각합니다. 그렇기 때문에 캔버스 문제를 해결하기 위해서는 HTML에서 너비와 높이를 설정하는 것이 중요합니다.

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 모듈이 로드되고 윈도우 크기가 조정될 때마다 캔버스 버퍼를 업데이트합니다.수동으로 지정하여 작업을 수행합니다.width그리고.height그리고 의 값으로 캔버스의. 버퍼를 업데이트하는 더 좋은 방법이 있을지도 모르지만, 나는 이 솔루션이 @SamB, @CoderNaveed, @AnthonyGedeon, @Bluerain, @Ben Jackson, @Manolo, @XaviGuardia, @Russel Harkins, @fermar에 의해 제안된 것보다 더 낫다고 믿습니다.

  1. 요소는 HTML이 아닌 CSS로 스타일링됩니다.
  2. 와는 달리elem.style.width&elem.style.height@Manolo에 의해 사용되는 트릭 또는 @XaviGuardia에 의해 사용되는 JQuery와 동등한 것, 그것은 효과가 있을 것입니다.canvas크기는 다음과 같이 용법으로 지정됩니다.flex아니면grid항목.
  3. @Russel Harkings의 솔루션과 달리 이 솔루션은 크기 조정도 처리합니다.비록 그의 대답이 정말 깨끗하고 쉽기 때문에 마음에 듭니다.
  4. WASM은 미래!하하 :D

P.S. 엄청 많습니다..unwrap()러스트는 발생 가능한 실패를 명시적으로 처리하기 때문입니다.

추신:

    {
        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 미디어 쿼리와 같이 동적 동작을 원하는 경우 캔버스 너비 및 높이 속성을 사용하지 마십시오.CSS 규칙을 사용한 다음 캔버스 렌더링 컨텍스트를 얻기 전에 CSS 너비 및 높이 속성을 지정합니다.

var elem = document.getElementById("mycanvas");

elem.width = elem.style.width;
elem.height = elem.style.height;

var ctx1 = elem.getContext("2d");
...

언급URL : https://stackoverflow.com/questions/2588181/canvas-is-stretched-when-using-css-but-normal-with-width-height-attributes

반응형