HTML5 Canvas 뷰포트의 너비 100 % 높이?


151

뷰포트의 너비와 높이를 100 % 차지하는 캔버스 요소를 만들려고합니다.

내 예제 에서 발생하는 것을 볼 수 있지만 Chrome과 FireFox에 스크롤 막대를 추가하고 있습니다. 여분의 스크롤 막대를 방지하고 창의 너비와 높이를 캔버스 크기로 정확하게 제공하려면 어떻게해야합니까?



다소 재미있는 Fonejacker 코미디 스케치를 떠올리게합니다
Francis Booth

답변:


258

캔버스를 항상 전체 화면 너비와 높이로 만들려면 브라우저의 크기를 조정할 때도 캔버스를 window.innerHeight 및 window.innerWidth로 크기를 조정하는 함수 내에서 그리기 루프를 실행해야합니다.

예 : http://jsfiddle.net/jaredwilli/qFuDr/

HTML

<canvas id="canvas"></canvas>

자바 스크립트

(function() {
    var canvas = document.getElementById('canvas'),
            context = canvas.getContext('2d');

    // resize the canvas to fill browser window dynamically
    window.addEventListener('resize', resizeCanvas, false);

    function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            /**
             * Your drawings need to be inside this function otherwise they will be reset when 
             * you resize the browser window and the canvas goes will be cleared.
             */
            drawStuff(); 
    }
    resizeCanvas();

    function drawStuff() {
            // do your drawing stuff here
    }
})();

CSS

* { margin:0; padding:0; } /* to remove the top and left whitespace */

html, body { width:100%; height:100%; } /* just to be sure these are full screen*/

canvas { display:block; } /* To remove the scrollbars */

이것이 캔버스를 브라우저의 전체 너비와 높이로 올바르게 만드는 방법입니다. drawStuff () 함수에서 캔버스에 그리기위한 모든 코드를 넣어야합니다.


2
패딩을 제거하고 너비, 높이를 100 %로 설정해야하는 이유는 무엇입니까?
코스

3
브라우저가 기본적으로 사용하는 사용자 스타일 시트를 재정의하기위한 것이라고 생각합니다. 일종의 정규화 또는 재설정 CSS 파일을 사용하는 경우 이미 처리되어 있기 때문에 필요하지 않습니다.
jaredwilli

2
꽤 많은 크기 조정이 필요한 경우; 예를 들어 세로 / 가로 장치의 debounce경우 크기를 조정 하고 싶을 경우 브라우저가 넘치게됩니다.
dooburt

24
display: block: 스크롤 막대를 제거 할뿐만 아니라 일반적으로 블록 내부의 텍스트 행 아래에 추가되는 문서 본문 높이에서 2px를 제거합니다. 그래서 +1
Neptilo

2
jQuery가없는 경우
Félix Gagnon-Grenier

26

뷰포트 단위 (CSS3)를 사용해 볼 수 있습니다 .

canvas { 
  height: 100vh; 
  width: 100vw; 
  display: block;
}

5
추가 display: block;하고 작업을 수행합니다.
superlukas

18
나는 이것을 시도했고 크롬과 파이어 폭스에서 캔버스는 단순히 전체 뷰포트로 확장 된 이미지를 보여줍니다. 새로 그려진 요소도 늘어납니다.
Vivian River

8
@Daniel이 옳 습니다 . 이 답변은 잘못되었습니다 . 캔버스 컨텍스트의 내부 크기가 아니라 DOM 요소의 크기를 설정합니다. 차이점 은 관련 질문에 대한 답변을 참조하십시오 .
Dan Dascalescu

19
이 방법은 작동하지 않으며 텍스트를 늘립니다. 당신은 불행하게도 JS를 사용 할 수 있습니다.
i336_

16

창 크기를 조정할 때 캔버스의 크기를 동적으로 조정하는 방법에 대한 일반적인 질문에 대답하겠습니다. 허용 된 답변은 너비와 높이가 모두 100 %로 가정 된 경우를 적절하게 처리하며 이는 캔버스의 종횡비를 변경합니다. 많은 사용자는 가로 세로 비율을 그대로 유지하면서 창 크기를 조정할 때 캔버스 크기를 조정하려고합니다. 정확한 질문은 아니지만 "적합"하여 질문을 좀 더 일반적인 맥락에 넣습니다.

창에는 가로 세로 비율 (너비 / 높이)이 있으며 캔버스 객체도 마찬가지입니다. 이 두 종횡비가 서로 관련되기를 원하는 방법은 분명해야 할 한 가지입니다. 그 질문에 대한 "하나의 크기가 모두 맞습니다"라는 대답은 없습니다. 필요.

html canvas 객체는 width 속성과 height 속성을 가지고 있습니다. 그런 다음 동일한 객체의 CSS에도 너비와 높이 속성이 있습니다. 이 두 너비와 높이는 다르며 둘 다 다른 것들에 유용합니다.

너비와 높이 속성을 변경하는 것은 항상 캔버스의 크기를 변경할 수있는 한 가지 방법이지만, 모든 크기를 다시 칠해야하며 시간이 걸리고 항상 필요한 것은 아닙니다. CSS 속성을 통해이 경우 캔버스를 다시 그리지 않습니다.

창 크기 조정에서 발생할 수있는 4 가지 사례가 있습니다 (모두 전체 화면 캔버스로 시작)

1 : 너비를 100 %로 유지하고 종횡비를 그대로 유지하려고합니다. 이 경우 캔버스를 다시 그릴 필요가 없습니다. 창 크기 조정 핸들러가 필요하지 않습니다. 당신이 필요한 전부

$(ctx.canvas).css("width", "100%");

여기서 ctx는 캔버스 컨텍스트입니다. 바이올린 : resizeByWidth

2 : 너비와 높이를 모두 100 %로 유지하고 가로 / 세로 비율의 변경으로 인해 이미지가 늘어날 수 있습니다. 이제 캔버스를 다시 그릴 필요는 없지만 창 크기 조정 핸들러가 필요합니다. 처리기에서

$(ctx.canvas).css("height", window.innerHeight);

바이올린 : messWithAspectratio

3 : 너비와 높이를 모두 100 %로 유지하려고하지만 가로 세로 비율 변경에 대한 대답은 이미지를 늘리는 것과 다릅니다. 그런 다음 다시 그려서 허용 된 답변에 요약 된 방식으로해야합니다.

바이올린 : 다시 그리기

4 : 페이지로드시 너비와 높이가 100 %가 되길 원하지만 그 후에는 일정하게 유지됩니다 (창 크기 조정에 대한 반응 없음).

바이올린 : 고정

모드가 설정된 63 행을 제외하고 모든 바이올린에는 동일한 코드가 있습니다. 바이올린 코드를 복사하여 로컬 컴퓨터에서 실행할 수도 있습니다.이 경우? string = redraw와 같이 querystring 인수를 통해 모드를 선택할 수 있습니다


1
참고하시기 바랍니다 : $(ctx.canvas).css("width", "100%");동일하다 $(canvas).css("width", "100%"); (문맥의 캔버스 그냥 캔버스)
브래드 켄트

@BradKent 당신이 원하는 "canvas-things"를 수행하는 헬퍼 함수를 ​​호출 할 때, 인수로 1) 캔버스 객체를 전달하고, 2) 캔버스 컨텍스트를 전달하고, 3) 둘 다 전달할 수 있습니다. 나는 3)을 좋아하지 않고 ctx.canvas, 훨씬 짧다 canvas.getContext('2d'). 그래서 나는 2)를한다. 따라서 canvas라는 변수는 없지만 ctx.canvas가 있습니다. 그것이 ctx.canvas의 출처입니다.
mathheadinclouds

9

http://jsfiddle.net/mqFdk/10/

<!DOCTYPE html>
<html>
<head>
    <title>aj</title>
</head>
<body>

    <canvas id="c"></canvas>

</body>
</html>

CSS로

body { 
       margin: 0; 
       padding: 0
     }
#c { 
     position: absolute; 
     width: 100%; 
     height: 100%; 
     overflow: hidden
   }

이것은 작동하지만 정의 된 너비와 높이없이 캔버스를 남겨 둡니다. 캔버스 너비와 높이는 내가 믿는 요소에서 정의해야합니다.
aherrick

@aherrick : 아니요, 캔버스 요소에 명시적인 너비 / 높이를 설정하지 않아도 작동합니다. 이 코드는 잘 작동합니다.
Jon Adams

18
실제로, 캔버스 요소에는 명시적인 너비 / 높이 세트가 필요합니다. 그것이 없으면 기본적으로 브라우저 사전 설정 (크롬에서는 300x150px) 크기로 설정됩니다. 캔버스에 대한 모든 도면은이 크기로 해석 된 다음 뷰포트 크기의 100 %로 조정됩니다. 캔버스에 무언가 를 그려서 내가 의미하는 바를 확인하십시오. 왜곡 될 수 있습니다.
Mark Kahn

캔버스를 100 % 너비와 높이로 만들려고하면 전혀 중요하지 않습니다. 당신은 어쨌든 크기를 조정 단지
jaredwilli

1
canvas 요소의 고유 치수는 좌표 공간의 크기와 같으며 숫자는 CSS 픽셀로 해석됩니다. 그러나 스타일 시트를 사용하여 요소 크기를 임의로 지정할 수 있습니다. 렌더링하는 동안 이미지는이 레이아웃 크기에 맞게 조정됩니다.
jaredwilli

8

나는이 질문에 대한 답을 찾고 있었지만 받아 들인 대답은 나를 깨뜨렸다. 분명히 window.innerWidth를 사용하는 것은 이식성이 없습니다. 일부 브라우저에서는 작동하지만 Firefox가 마음에 들지 않는 것을 알았습니다.

Gregg Tavares는이 문제를 직접 해결하는 훌륭한 리소스를 여기에 게시했습니다. http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (패턴 4 번 및 4 번 참조)

window.innerWidth 대신 canvas.clientWidth를 사용하면 잘 작동하는 것 같습니다.

Gregg의 제안 된 렌더 루프는 다음과 같습니다.

function resize() {
  var width = gl.canvas.clientWidth;
  var height = gl.canvas.clientHeight;
  if (gl.canvas.width != width ||
      gl.canvas.height != height) {
     gl.canvas.width = width;
     gl.canvas.height = height;
     return true;
  }
  return false;
}

var needToRender = true;  // draw at least once
function checkRender() {
   if (resize() || needToRender) {
     needToRender = false;
     drawStuff();
   }
   requestAnimationFrame(checkRender);
}
checkRender();

2

(動靜 能量의 답변으로 확대)

몸을 채우도록 캔버스의 스타일을 지정하십시오. 캔버스로 렌더링 할 때 크기를 고려하십시오.

http://jsfiddle.net/mqFdk/356/

<!DOCTYPE html>
<html>
<head>
    <title>aj</title>
</head>
<body>

    <canvas id="c"></canvas>

</body>
</html>

CSS :

body { 
       margin: 0; 
       padding: 0
     }
#c { 
     position: absolute; 
     width: 100%; 
     height: 100%; 
     overflow: hidden
   }

자바 스크립트 :

function redraw() {
    var cc = c.getContext("2d");
    c.width = c.clientWidth;
    c.height = c.clientHeight;
    cc.scale(c.width, c.height);

    // Draw a circle filling the canvas.
    cc.beginPath();
    cc.arc(0.5, 0.5, .5, 0, 2*Math.PI);
    cc.fill();
}

// update on any window size change.
window.addEventListener("resize", redraw);

// first draw
redraw();

1

모바일의 경우 사용하는 것이 좋습니다

canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;

방향을 세로로 변경하면 "뷰포트"가 늘어납니다. 전체 예보기

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.