Ширина и высота холста в HTML5

Можно ли исправить ширину и высоту элемента HTML5 canvas?

Обычный способ заключается в следующем:

<canvas id="canvas" width="300" height="300"></canvas>

Ответ 1

Элемент canvas DOM имеет свойства .height и .width, которые соответствуют атрибутам height="…" и width="…". Установите их в числовые значения в JavaScript-коде, чтобы изменить размер вашего холста. Например:

var canvas = document.getElementsByTagName('canvas')[0];
canvas.width  = 800;
canvas.height = 600;

Обратите внимание, что это очищает холст, хотя вы должны следовать с ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height); для обработки тех браузеров, которые не полностью очищают холст. После изменения размера вам нужно будет перерисовать любой контент, который вы хотите отобразить.

Обратите внимание, что высота и ширина - это размеры логического холста, используемые для рисования, и отличаются от атрибутов CSS style.height и style.width. Если вы не устанавливаете атрибуты CSS, внутренний размер холста будет использоваться в качестве размера его отображения; если вы установите атрибуты CSS, и они отличаются от размеров холста, ваш контент будет масштабироваться в браузере. Например:

// Make a canvas that has a blurry pixelated zoom-in
// with each canvas pixel drawn showing as roughly 2x2 on screen
canvas.width  = 400;
canvas.height = 300; 
canvas.style.width  = '800px';
canvas.style.height = '600px';

Смотрите этот живой пример холста, увеличенного на 4 раза.

var c = document.getElementsByTagName('canvas')[0];
var ctx = c.getContext('2d');
ctx.lineWidth   = 1;
ctx.strokeStyle = '#f00';
ctx.fillStyle   = '#eff';

ctx.fillRect(  10.5, 10.5, 20, 20 );
ctx.strokeRect( 10.5, 10.5, 20, 20 );
ctx.fillRect(   40, 10.5, 20, 20 );
ctx.strokeRect( 40, 10.5, 20, 20 );
ctx.fillRect(   70, 10, 20, 20 );
ctx.strokeRect( 70, 10, 20, 20 );

ctx.strokeStyle = '#fff';
ctx.strokeRect( 10.5, 10.5, 20, 20 );
ctx.strokeRect( 40, 10.5, 20, 20 );
ctx.strokeRect( 70, 10, 20, 20 );
body { background:#eee; margin:1em; text-align:center }
canvas { background:#fff; border:1px solid #ccc; width:400px; height:160px }
<canvas width="100" height="40"></canvas>
<p>Showing that re-drawing the same antialiased lines does not obliterate old antialiased lines.</p>

Ответ 2

Холст имеет 2 размера, размер пикселей в холсте (это backingstore или drawingBuffer) и размер дисплея. Количество пикселей задается с использованием атрибутов canvas. В HTML

<canvas width="400" height="300"></canvas>

Или в JavaScript

someCanvasElement.width = 400;
someCanvasElement.height = 300;

Отделяется от ширины и высоты стиля холста CSS

В CSS

canvas {  /* or some other selector */
   width: 500px;
   height: 400px;
}

Или в JavaScript

canvas.style.width = "500px";
canvas.style.height = "400px";

Возможно, лучший способ сделать холст размером 1x1 пикселей - ВСЕГДА ИСПОЛЬЗОВАТЬ CSS, чтобы выбрать размер, а затем напишите маленький бит JavaScript, чтобы количество пикселей соответствовало этому размеру.

function resizeCanvasToDisplaySize(canvas) {
   // look up the size the canvas is being displayed
   const width = canvas.clientWidth;
   const height = canvas.clientHeight;

   // If it resolution does not match change it
   if (canvas.width !== width || canvas.height !== height) {
     canvas.width = width;
     canvas.height = height;
     return true;
   }

   return false;
}

Почему это лучший способ? Потому что он работает в большинстве случаев без необходимости менять код.

Здесь полный холст окна:

const ctx = document.querySelector("#c").getContext("2d");

function render(time) {
  time *= 0.001;
  resizeCanvasToDisplaySize(ctx.canvas);
 
  ctx.fillStyle = "#DDE";
  ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  ctx.save();
 
  const spacing = 64;
  const size = 48;
  const across = ctx.canvas.width / spacing + 1;
  const down = ctx.canvas.height / spacing + 1;
  const s = Math.sin(time);
  const c = Math.cos(time);
  for (let y = 0; y < down; ++y) {
    for (let x = 0; x < across; ++x) {
      ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);
      ctx.strokeRect(-size / 2, -size / 2, size, size);
    }
  }
  
  ctx.restore();
  
  requestAnimationFrame(render);
}
requestAnimationFrame(render);

function resizeCanvasToDisplaySize(canvas) {
   // look up the size the canvas is being displayed
   const width = canvas.clientWidth;
   const height = canvas.clientHeight;

   // If it resolution does not match change it
   if (canvas.width !== width || canvas.height !== height) {
     canvas.width = width;
     canvas.height = height;
     return true;
   }

   return false;
}
body { margin: 0; }
canvas { display: block; width: 100vw; height: 100vh; }
<canvas id="c"></canvas>

Ответ 3

Большое спасибо! Наконец я решил проблему с размытыми пикселями с помощью этого кода:

<canvas id="graph" width=326 height=240 style='width:326px;height:240px'></canvas>

С добавлением "полупикселя" трюк снимает размытие линий.

Ответ 4

Лучший способ сделать это:

<canvas id="myChart" style="height: 400px; width: 100px;"></canvas>