Un canevas a 2 tailles, la dimension des pixels dans le canevas (c'est le backingstore ou drawingBuffer) et la taille d'affichage. Le nombre de pixels est défini à l'aide des attributs du canevas. En HTML
<canvas width="400" height="300"></canvas>
Ou en JavaScript
someCanvasElement.width = 400
someCanvasElement.height = 300
La largeur et la hauteur du style CSS du canevas sont séparées de cela
En CSS
canvas {
width: 500px;
height: 400px;
}
Ou en JavaScript
canvas.style.width = "500px"
canvas.style.height = "400px"
La meilleure façon de créer un canevas 1x1 pixels est de TOUJOURS UTILISER CSS pour choisir la taille, puis d'écrire un tout petit peu de JavaScript pour que le nombre de pixels corresponde à cette taille.
function resizeCanvasToDisplaySize(canvas) {
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
return true;
}
return false;
}
Pourquoi est-ce le meilleur moyen? Parce que cela fonctionne dans la plupart des cas sans avoir à changer de code.
Voici une toile de fenêtre complète:
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) {
const width = canvas.clientWidth;
const height = canvas.clientHeight;
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>
Et voici une toile en tant que flotteur dans un paragraphe
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) {
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
return true;
}
return false;
}
span {
width: 250px;
height: 100px;
float: left;
padding: 1em 1em 1em 0;
display: inline-block;
}
canvas {
width: 100%;
height: 100%;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus venenatis metus. Mauris ac nibh at odio scelerisque scelerisque. Donec ut enim <span class="diagram"><canvas id="c"></canvas></span>
vel urna gravida imperdiet id ac odio. Aenean congue hendrerit eros id facilisis. In vitae leo ullamcorper, aliquet leo a, vehicula magna. Proin sollicitudin vestibulum aliquet. Sed et varius justo.
<br/><br/>
Quisque tempor metus in porttitor placerat. Nulla vehicula sem nec ipsum commodo, at tincidunt orci porttitor. Duis porttitor egestas dui eu viverra. Sed et ipsum eget odio pharetra semper. Integer tempor orci quam, eget aliquet velit consectetur sit amet. Maecenas maximus placerat arcu in varius. Morbi semper, quam a ullamcorper interdum, augue nisl sagittis urna, sed pharetra lectus ex nec elit. Nullam viverra lacinia tellus, bibendum maximus nisl dictum id. Phasellus mauris quam, rutrum ut congue non, hendrerit sollicitudin urna.
</p>
Voici une toile dans un panneau de contrôle de grande taille
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) {
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
return true;
}
return false;
}
const $ = document.querySelector.bind(document);
const left = $(".left");
const slider = $(".slider");
let dragging;
let lastX;
let startWidth;
slider.addEventListener('mousedown', e => {
lastX = e.pageX;
dragging = true;
});
window.addEventListener('mouseup', e => {
dragging = false;
});
window.addEventListener('mousemove', e => {
if (dragging) {
const deltaX = e.pageX - lastX;
left.style.width = left.clientWidth + deltaX + "px";
lastX = e.pageX;
}
});
body {
margin: 0;
}
.frame {
display: flex;
align-items: space-between;
height: 100vh;
}
.left {
width: 70%;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
canvas {
width: 100%;
height: 100%;
}
pre {
padding: 1em;
}
.slider {
width: 10px;
background: #000;
}
.right {
flex 1 1 auto;
}
<div class="frame">
<div class="left">
<canvas id="c"></canvas>
</div>
<div class="slider">
</div>
<div class="right">
<pre>
* controls
* go
* here
<- drag this
</pre>
</div>
</div>
voici une toile en arrière-plan
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) {
const width = canvas.clientWidth;
const height = canvas.clientHeight;
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;
position: fixed;
}
#content {
position: absolute;
margin: 0 1em;
font-size: xx-large;
font-family: sans-serif;
font-weight: bold;
text-shadow: 2px 2px 0 #FFF,
-2px -2px 0 #FFF,
-2px 2px 0 #FFF,
2px -2px 0 #FFF;
}
<canvas id="c"></canvas>
<div id="content">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus venenatis metus. Mauris ac nibh at odio scelerisque scelerisque. Donec ut enim vel urna gravida imperdiet id ac odio. Aenean congue hendrerit eros id facilisis. In vitae leo ullamcorper, aliquet leo a, vehicula magna. Proin sollicitudin vestibulum aliquet. Sed et varius justo.
</p>
<p>
Quisque tempor metus in porttitor placerat. Nulla vehicula sem nec ipsum commodo, at tincidunt orci porttitor. Duis porttitor egestas dui eu viverra. Sed et ipsum eget odio pharetra semper. Integer tempor orci quam, eget aliquet velit consectetur sit amet. Maecenas maximus placerat arcu in varius. Morbi semper, quam a ullamcorper interdum, augue nisl sagittis urna, sed pharetra lectus ex nec elit. Nullam viverra lacinia tellus, bibendum maximus nisl dictum id. Phasellus mauris quam, rutrum ut congue non, hendrerit sollicitudin urna.
</p>
</div>
Parce que je n'ai pas défini les attributs, la seule chose qui a changé dans chaque échantillon est le CSS (en ce qui concerne le canevas)
Remarques:
- Ne placez pas de bordures ou de remplissage sur un élément de canevas. Le calcul de la taille à soustraire du nombre de dimensions de l'élément est gênant
$('#mycanvas').attr({width:400,height:300}).css({width:'800px',height:'600px'});
Si vous voulez que la taille visuelle soit la même que la taille des pixels, ne définissez jamais les styles, uniquement les attributs.