<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<title>Cara amb Canvas, Scale i Rotate</title>
<!-- Incloem la biblioteca p5.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
</head>
<body>
<!-- Botó per canviar la cara, escala i rotació -->
<button id="changeButton" style="font-size:16px; margin: 20px;" onclick="changeFace()">Canvia la cara</button>
<!-- Div per allotjar el canvas. El canvas es crearà dins d'aquest div -->
<div id="canvas-container"></div>
<script>
// Variables globals per a dimensions, posicions, escala i rotació
let faceWidth = 300;
let faceHeight = 400;
let skinColor;
let rotationAngle = 0; // Angle de rotació inicial (0 radians)
let scaleFactor = 1; // Factor d'escala inicial (1 = 100%)
// Variables per calcular el centre del canvas
let centerX, centerY;
// Funció setup() de p5.js: s'executa una sola vegada al començar
function setup() {
// Creem el canvas de 800x800 píxels
let canvas = createCanvas(800, 800);
// Enganxem el canvas dins del div amb id "canvas-container"
canvas.parent("canvas-container");
centerX = width / 2;
centerY = height / 2;
skinColor = color(245, 207, 160); // Color inicial de la pell
noLoop(); // Impedeix que draw() s'executi en bucle
}
// Funció draw() de p5.js: s'executa cada cop que es crida redraw()
function draw() {
background(220); // Fons gris clar
// Utilitzem push() per salvar l'estat de la transformació
push();
// Traslladem l'origen al centre del canvas
translate(centerX, centerY);
// Apliquem la rotació amb l'angle indicat
rotate(rotationAngle);
// Apliquem l'escala (tant horitzontal com vertical)
scale(scaleFactor);
// Dibuixem la cara centrada a (0,0) després de la transformació
drawFace(0, 0, faceWidth, faceHeight);
drawEyes(0, 0, faceWidth * 0.2, faceWidth * 0.4);
drawNose(0, faceHeight * 0.1, faceWidth * 0.15);
drawMouth(0, faceHeight * 0.3, faceWidth * 0.4);
// Restaurem l'estat anterior de la transformació
pop();
}
// Funció per canviar la cara, escala i rotació al prémer el botó
function changeFace() {
// Canvia el color de pell a un valor aleatori dins d'un rang de tons suaus
skinColor = color(random(220, 255), random(190, 230), random(170, 210));
// Actualitza l'angle de rotació (aleatori entre -PI/8 i PI/8)
rotationAngle = random(-PI/8, PI/8);
// Actualitza el factor d'escala (aleatori entre 0.8 i 1.2)
scaleFactor = random(0.8, 1.2);
// Força el redibuix del canvas per mostrar els canvis realitzats
redraw();
}
// Funció per dibuixar el rostre
function drawFace(x, y, w, h) {
fill(skinColor);
noStroke();
// Dibuixa la forma principal del rostre com una el·lipse
ellipse(x, y, w, h);
// Dibuixa les orelles en posicions relatives a la mida del rostre
drawEar(x - w/2 * 0.9, y, w * 0.25, h * 0.4);
drawEar(x + w/2 * 0.9, y, w * 0.25, h * 0.4);
}
// Funció per dibuixar una orella
function drawEar(x, y, w, h) {
fill(skinColor);
ellipse(x, y, w, h);
fill(255, 200, 200);
ellipse(x, y, w * 0.6, h * 0.6);
}
// Funció per dibuixar els ulls
function drawEyes(x, y, eyeSize, eyeSpacing) {
// La posició vertical dels ulls és una mica superior al centre
let eyeY = y - faceHeight * 0.1;
// Dibuixa l'ull esquerre
drawEye(x - eyeSpacing/2, eyeY, eyeSize);
// Dibuixa l'ull dret
drawEye(x + eyeSpacing/2, eyeY, eyeSize);
}
// Funció per dibuixar un únic ull
function drawEye(x, y, size) {
fill(255); // Blanc de l'ull
ellipse(x, y, size, size * 0.8);
fill(random(50, 200), random(50, 200), random(50, 200)); // Iris aleatori
ellipse(x, y, size * 0.6, size * 0.6);
fill(0); // Pupil·la negra
ellipse(x, y, size * 0.3, size * 0.3);
fill(255, 200); // Reflex ocular
ellipse(x - size * 0.15, y - size * 0.1, size * 0.2);
}
// Funció per dibuixar el nas
function drawNose(x, y, size) {
stroke(0);
strokeWeight(2);
noFill();
triangle(
x, y - size,
x - size/2, y + size,
x + size/2, y + size
);
noStroke();
fill(255, 200, 200);
ellipse(x, y + size * 1.1, size * 0.4);
}
// Funció per dibuixar la boca
function drawMouth(x, y, mouthWidth) {
noStroke();
fill(150, 50, 50);
arc(x, y, mouthWidth, 80, PI, 0, CHORD);
fill(255);
rect(x - mouthWidth/2, y, mouthWidth, 5);
fill(200, 100, 100);
arc(x, y + 5, mouthWidth * 0.8, 40, 0, PI, CHORD);
}
</script>
</body>
</html>