Canvas: dibuixar
Fins ara JavaScript canviava text i estils. Amb el <canvas>, una mena de "tela en blanc", podem dibuixar: rectangles, cercles, línies, colors… És la base de qualsevol joc o gràfic interactiu al navegador.
Què és el canvas
Un <canvas> és un element HTML rectangular on JavaScript pot dibuixar píxel a píxel. A l'HTML s'escriu així:
<canvas id="dibuix" width="300" height="200"></canvas>
El width i height són la mida del llenç en píxels. Per defecte és invisible (no té cap vora), però al simulador li hem afegit un contorn per veure'l.
Per dibuixar-hi, primer cal trobar l'element i demanar-li el context de dibuix. El context és l'objecte que té totes les funcions per pintar:
getContext("2d") et dona un context per a dibuix en 2D. (També hi ha "webgl" per a 3D, però això queda fora d'aquest curs.)
Per convenció, la variable que guarda el context s'anomena ctx. La veuràs així a tot arreu.
Sistema de coordenades
Una cosa que sorprèn als nous: el punt (0, 0) està a dalt-esquerra, no a baix-esquerra com a les matemàtiques. La coordenada Y creix cap avall:
(0,0) ──────► X creix │ │ ▼ Y creix cap avall
Per tant, un punt amb Y gran està més avall a la pantalla, no més amunt. Tingues-ho present quan dibuixis: si vols posar alguna cosa "a baix", la Y ha de ser més gran.
Dibuixar rectangles plens: fillRect
La funció més bàsica és ctx.fillRect(x, y, amplada, alçada). Dibuixa un rectangle ple, començant per la cantonada superior esquerra a (x, y):
Els rectangles surten en negre per defecte. Per canviar el color, modifica ctx.fillStyle abans de dibuixar:
Important: fillStyle és com una brotxa. La canvies un cop, i tots els fillRect següents fan servir aquell color, fins que la tornis a canviar.
El color pot ser un nom CSS ("red", "blue", "orange"…), un codi hexadecimal ("#ff6600"), o una notació rgb() o rgba() amb transparència:
Fixa't en la transparència del rectangle blau: es veu com el verd passa per darrere. rgba té quatre valors: vermell, verd, blau (0-255) i alfa (0 = invisible, 1 = opac).
Rectangles buits: strokeRect
Per dibuixar només el contorn (sense omplir), s'usa ctx.strokeRect. El color es controla amb ctx.strokeStyle, i el gruix de la línia amb ctx.lineWidth:
Com amb fillStyle, strokeStyle i lineWidth persisteixen fins que les canvies.
Cercles: arc
Per als cercles cal una mica més de codi. La funció ctx.arc(x, y, radi, anglesInici, anglesFi) dibuixa un arc, i per fer un cercle complet hem de donar la volta sencera (0 fins a 2π):
Cal seguir aquest patró sempre per dibuixar formes corbes:
ctx.beginPath()— «comença un nou camí».ctx.arc(x, y, radi, 0, 2 * Math.PI)— descriu el cercle.ctx.fill()per omplir-lo (octx.stroke()per al contorn).
Sense beginPath(), els cercles consecutius es connecten i fan figures rares. 2 * Math.PI són els 360° en radians — així es completa la volta. Math.PI és el nombre PI (≈ 3.14159), una constant que ja existeix.
Esborrar el canvas: clearRect
Per esborrar un rectangle (deixar-lo transparent), s'usa ctx.clearRect(x, y, w, h). Per esborrar tot el canvas, esborres un rectangle de la mida total:
Aquesta funció serà clau al capítol següent: per fer animacions, esborrem el frame anterior i tornem a dibuixar al nou lloc.
Combinant amb bucles
Aquí és on tot el que has après pren sentit. Un bucle pot dibuixar centenars de formes amb molt poc codi. Mira aquest patró de quadrats:
Els colors van canviant gradualment perquè estem usant hsl() (Hue, Saturació, Lluminositat) i fem variar la Hue de 0 a 324 graus — tot l'arc de l'arc iris.
Amb dos bucles niats, pots fer una graella de formes:
Hem dibuixat un patró d'escaquer en 5 línies efectives de codi. Aquesta combinació «bucles + canvas» és la base de tot el que dibuixarem al capítol següent.
Errors típics
1. Oblidar beginPath() abans d'un cercle nou. Si dibuixes diversos arcs sense beginPath, totes les formes queden connectades i la pintura surt malament:
El segon cercle es dibuixa correctament, però el primer crida ara comparteix camí amb el segon i es repinta de manera estranya. Posa ctx.beginPath() abans de cada arc.
2. Posar el color després de dibuixar:
// ✗ INCORRECTE — surt en negre (el color encara no s'havia canviat) ctx.fillRect(10, 10, 50, 50); ctx.fillStyle = "red"; // ✓ CORRECTE — primer canvies el color, després dibuixes ctx.fillStyle = "red"; ctx.fillRect(10, 10, 50, 50);
3. Pensar que Y creix cap amunt — molts dibuixos surten al revés perquè confonem la convenció de les matemàtiques amb la de la pantalla. Recorda: Y gran = més avall.
Exercici
dibuixaQuadrat(ctx, x, y, mida, color) que dibuixi un quadrat ple de la mida i color donats a la posició (x, y).
La funció no ha d'imprimir res; només ha de canviar el fillStyle i cridar fillRect per dibuixar.
El simulador té un canvas i un codi que crida la teva funció diverses vegades per dibuixar un patró colorit. Si la teva funció és correcta, veuràs un patró bonic a la pàgina viva.
El test comprova tres coses: que poses el color correctament, que crides fillRect amb els arguments correctes (x, y, mida, mida), i que ho fas en l'ordre correcte (primer color, després dibuix).
Resum
<canvas width="W" height="H">és una tela on JavaScript pot dibuixar.ctx = canvas.getContext("2d")et dona l'API de dibuix.- Coordenades: (0,0) a dalt-esquerra, Y creix cap avall.
ctx.fillStyle+ctx.fillRect(x,y,w,h)— rectangle ple.ctx.strokeStyle+ctx.lineWidth+ctx.strokeRect(...)— rectangle buit.- Cercles:
beginPath()→arc(x,y,r,0,2*Math.PI)→fill(). ctx.clearRect(x,y,w,h)esborra una zona del canvas.- Colors com
"red","#ff6600",rgb(...),rgba(...)per a transparència,hsl(...)per a gradients de color. - Bucles + canvas = patrons amb molt poc codi.