Come creare un animazione in JavaScript (3)
Migliorando l'animazione precedente, Come creare un animazione in JavaScript (2), si può affinare il codice creando degli oggetti che rappresentano le forme (sprite) gestite:
Definisco un oggetto che identifica le forme:
poi i singoli sprite e un oggetto arena che rappresenta lo spazio dell'animazione:
ridefinisco i metodi updatePosition e draw:
e aggiungo gli sprites con i nuovi metodi:
Il risultato è l'animazione a inizio pagina.
Se non vedi l'animazione clicca sul canvas o ricarica la pagina
Definisco un oggetto che identifica le forme:
JavaScript
//tipi di sprite gestiti
const SpriteType = {
BACKGROUND: 'background',
CIRCLE: 'circle',
RECTANGLE: 'rectangle',
TEXT: 'text',
};
JavaScript
//definisco un oggetto che rappresenta l'area da disegnare
function Arena(w, h) {
this.w = w;
this.h = h;
this.sprites = []; //sposto l'array 'sprites'
}
//creo l'arena
const arena = new Arena(canvas.width, canvas.height);
//aggiungo un metodo per 'aggiungere' gli sprites
Arena.prototype.addSprite = function (sprite) {
this.sprites.push(sprite);
}
//definisco i tipi di oggetti da disegnare
function SpriteBackground(x, y, w, h, fillColor) {
this.type = SpriteType.BACKGROUND;
this.x = x; // x e y sempre riferiti all'angolo in alto a sinistra
this.y = y;
this.w = w;
this.h = h;
this.fillColor = fillColor == null ? null : fillColor;
this.animationOn = false;
this.alpha = 1;
}
function SpriteCircle(x, y, radius, color, fillColor, deltaX, deltaY) {
this.type = SpriteType.CIRCLE;
this.x = x;
this.y = y;
this.radius = radius;
this.color = color == null ? null : color;
this.fillColor = fillColor == null ? null : fillColor;
this.deltaX = deltaX == null ? 0 : deltaX;
this.deltaY = deltaY == null ? 0 : deltaY;
this.animationOn = this.deltaX !== 0 || this.deltaY !== 0;
this.startAngle = 0;
this.endAngle = Math.PI * 2;
this.alpha = 1;
}
function SpriteRect(x, y, w, h, color, fillColor, deltaX, deltaY) {
this.type = SpriteType.RECTANGLE;
this.x = x; // x e y sempre riferiti al centro dell'oggetto
this.y = y;
this.w = w;
this.h = h;
this.color = color == null ? null : color;
this.fillColor = fillColor == null ? null : fillColor;
this.deltaX = deltaX == null ? 0 : deltaX;
this.deltaY = deltaY == null ? 0 : deltaY;
this.animationOn = this.deltaX !== 0 || this.deltaY !== 0;
this.alpha = 1;
}
function SpriteText(x, y, text, font, color, fillColor, textAlign, baseline, deltaX, deltaY) {
this.type = SpriteType.TEXT;
this.x = x;
this.y = y;
this.text = text;
this.font = font == null ? '14px Arial' : font;
this.color = color == null ? null : color;
this.fillColor = fillColor == null ? null : fillColor;
this.textAlign = textAlign == null ? 'left' : textAlign;
this.baseline = baseline == null ? 'bottom' : baseline;
this.deltaX = deltaX == null ? 0 : deltaX;
this.deltaY = deltaY == null ? 0 : deltaY;
this.animationOn = this.deltaX !== 0 || this.deltaY !== 0;
this.alpha = 1;
}
JavaScript
function updatePosition() {
arena.sprites.forEach(sprite => {
if (sprite.animationOn === true) {
// per ogni oggetto calcolo la nuova posizione
sprite.x += sprite.deltaX;
sprite.y += sprite.deltaY;
}
});
}
function draw() {
//avendo gestito i type 'rectangle'
//non devo più cancellare lo sfondo in modo esplicito
arena.sprites.forEach(sprite => {
ctx.globalAlpha = sprite.alpha;
switch (sprite.type) {
case SpriteType.BACKGROUND:
ctx.beginPath();
ctx.rect(sprite.x, sprite.y, sprite.w, sprite.h);
ctx.fillStyle = sprite.fillColor; //colore di riempimento
ctx.fill();
break;
case SpriteType.RECTANGLE:
ctx.beginPath();
const x = sprite.x - sprite.w / 2;
const y = sprite.y - sprite.h / 2;
ctx.rect(x, y, sprite.w, sprite.h);
if (sprite.fillColor !== null) {
ctx.fillStyle = sprite.fillColor; //colore di riempimento
ctx.fill();
}
if (sprite.color !== null) {
ctx.strokeStyle = sprite.color; // colore del bordo
ctx.stroke();
}
break;
case SpriteType.CIRCLE:
ctx.beginPath();
ctx.arc(sprite.x, sprite.y, sprite.radius, 0, 2 * Math.PI);
if (sprite.fillColor !== null) {
ctx.fillStyle = sprite.fillColor; //colore di riempimento
ctx.fill();
}
if (sprite.color !== null) {
ctx.strokeStyle = sprite.color; // colore del bordo
ctx.stroke();
}
break;
case SpriteType.TEXT:
ctx.font = sprite.font;
ctx.textAlign = sprite.textAlign;
ctx.textBaseline = sprite.baseline;
if (sprite.fillColor !== null) {
ctx.fillStyle = sprite.fillColor; //colore di riempimento
ctx.fillText(sprite.text, sprite.x, sprite.y);
}
if (sprite.color !== null) {
ctx.strokeStyle = sprite.color; // colore del bordo
ctx.strokeText(sprite.text, sprite.x, sprite.y);
}
break;
}
});
}
JavaScript
function createSprites() {
arena.sprites.length=0;
const cx = canvas.width / 2;
const cy = canvas.height / 2;
//aggiungo lo sfondo
arena.addSprite(new SpriteBackground(0, 0, canvas.width, canvas.height, '#444'));
//aggiungo un testo
const text1 = new SpriteText(cx, cy, 'Sgart.it', '150px Arial', '#ccc',null, 'center', 'middle');
text1.alpha = .5;
arena.addSprite(text1);
//aggiungo gli altri oggetti da animare
arena.addSprite(new SpriteCircle(50, canvas.height - 50, 35, '#ccc', 'red', 3, -2));
// creo un testo sotto al rettangolo
arena.addSprite(new SpriteText(100, 400, 'Testo di sfondo sotto al rettangolo giallo', '25px Arial', '#00f'));
//definisco un oggetto trasparente
arena.addSprite(new SpriteRect(50, 50, 40, 45, '#fff', 'yellow', 1, 2));
//aggiungo un testo
const text2 = new SpriteText(200, 150, 'testo in primo piano', '70px Arial', null, '#f0f');
text1.alpha = .5;
arena.addSprite(text2);
//l'ultimo sprite definito è quello più in alto, sopra a tutti
}
- Come creare un animazione in JavaScript
- Come creare un animazione in JavaScript (2)
- Come creare un animazione in JavaScript (3)
- Come creare un animazione in JavaScript (4) - collisioni
- Come creare un animazione in JavaScript (5) - tastiera
- Come creare un animazione in JavaScript (6) - mouse
- Come creare un animazione in JavaScript (7) - immagini