6 - Juegos y Multimedia HTML5 - Fuentes personalizadas con @font-face, classList y animaciones CSS3

Ya tenemos construidos nuestros fuegos artificiales y ¡de múltiples colores! Para poner la guinda al pastel, vamos a utilizar la regla CSS @font-face que nos va a permitir cargar fuentes personalizadas en diferentes formatos. Con la fuente cargada dibujaremos un bonito título al que, también utilizando CSS, vamos a añadirle unos efectos llamativos (un reflejo en el suelo y movimiento al pasar el ratón por encima de él).
Aunque no nos va a servir mucho para este ejemplo, voy a presentaros el objeto classList del cual ya he escrito un artículo que contiene información detallada para el que prefiera leer a ver el vídeo ;)



Así es como se encontraba el archivo fireworks.html al terminar el videotutorial. Lo podéis ver funcionando aquí.
<!DOCTYPE html>
<html>
  <head>
    <title>Canvas</title>
    <meta charset="UTF-8">
    <meta name="author" content="http://programmingheroes.blogspot.com.es">
    <style>
        @font-face {
            font-family: "PlaneCrash";
            src: url("fonts/PlaneCrash.woff") format("woff"),
                url("fonts/PlaneCrash.ttf") format("truetype");
        }
        body {
            background-color: #000;
            overflow: hidden;
            margin: 0;
        }
        div {
            -moz-user-select: none;
            -webkit-user-select: none;
        }
        canvas {
            background-color: #000;
            position: absolute;
        }
        #title {
            -webkit-transform: rotateZ(-5deg);
            -webkit-transition: -webkit-transform 2s;
            -webkit-box-reflect: below -40px
                -webkit-gradient(linear, left top, left bottom, 
                   from(transparent), to(rgba(255, 255, 255, 0.6)));
            -webkit-transform-origin: 0% 100%;
            font-family: "PlaneCrash";
            position: relative;
            text-align: center;
            top: 30px;
            font-size: 6em;
            color: red;
            text-shadow: 0px 0px 20px white;
        }
        #title:hover {
            -webkit-transform: rotateZ(5deg);
        }
    </style>
    <script>
        window.addEventListener("resize", resizeCanvas, false);
        window.addEventListener("DOMContentLoaded", onLoad, false);
        
        window.requestAnimationFrame = 
            window.requestAnimationFrame       || 
            window.webkitRequestAnimationFrame || 
            window.mozRequestAnimationFrame    || 
            window.oRequestAnimationFrame      || 
            window.msRequestAnimationFrame     || 
            function (callback) {
                window.setTimeout(callback, 1000/60);
            };
        
        var canvas, ctx, w, h, particles = [], probability = 0.04,
            xPoint, yPoint;
        
        
        var img = new Image();
        img.src = "img/fire.png";
        
        
        function onLoad() {
            canvas = document.getElementById("canvas");
            canvas.addEventListener("mousedown", mouseDown, false);
            canvas.addEventListener("mousewheel", mouseWheel, false);
            ctx = canvas.getContext("2d");
            resizeCanvas();
            
            window.requestAnimationFrame(updateWorld);
        } // fin de onLoad();
        
        function mouseDown() {
            createFirework();
        } // fin de moveDown(e);
        
        function mouseWheel(e) {
            e = e || window.event;
            if (e.wheelDelta > 0) {
                probability += 0.01;
            } else {
                probability -= 0.01;
                probability = probability<0? 0: probability;
            }
        } // fin dw mouseWheel();
        
        function resizeCanvas() {
            if (!!canvas) {
                w = canvas.width = window.innerWidth;
                h = canvas.height = window.innerHeight;
            }
        } // fin de resizeCanvas();
        
        function updateWorld() {
            update();
            paint();
            window.requestAnimationFrame(updateWorld);
        } // fin de update();
        
        function update() {
            if (particles.length < 500 && Math.random() < probability) {
                createFirework();
            }
            var alive = [];
            for (var i=0; i<particles.length; i++) {
                if (particles[i].move()) {
                    alive.push(particles[i]);
                }
            }
            particles = alive;
        } // fin de update();
        
        function paint() {
            ctx.globalCompositeOperation = 'source-over';
            ctx.fillStyle = "rgba(0,0,0,0.2)";
            ctx.fillRect(0, 0, w, h);
            ctx.globalCompositeOperation = 'lighter';
            for (var i=0; i<particles.length; i++) {
                particles[i].draw(ctx);
            }
        } // fin de paint();
        
        function createFirework() {
            xPoint = Math.random()*(w-200)+100;
            yPoint = Math.random()*(h-200)+100;
            var nFire = Math.random()*50+100;
            var c = "rgb("+(~~(Math.random()*200+55))+","
                 +(~~(Math.random()*200+55))+","+(~~(Math.random()*200+55))+")";
            for (var i=0; i<nFire; i++) {
                var particle = new Particle();
                particle.color = c;
                var vy = Math.sqrt(25-particle.vx*particle.vx);
                if (Math.abs(particle.vy) > vy) {
                    particle.vy = particle.vy>0 ? vy: -vy;
                }
                particles.push(particle);
            }
        } // fin de createParticles();
        
        function Particle() {
            this.w = this.h = Math.random()*6+1;
            // Position
            this.x = xPoint-this.w/2;
            this.y = yPoint-this.h/2;
            // Velocidades x e y entre -5 y +5
            this.vx = (Math.random()-0.5)*10;
            this.vy = (Math.random()-0.5)*10;
            // Tiempo de vida
            this.alpha = Math.random()*.5+.5;
            // color
            this.color;
        } // fin de Particle();
        
        Particle.prototype = {
            gravity: 0.05,
            move: function () {
                this.x += this.vx;
                this.vy += this.gravity;
                this.y += this.vy;
                this.alpha -= 0.01;
                if (this.x <= -this.w || this.x >= screen.width ||
                    this.y >= screen.height ||
                    this.alpha <= 0) {
                        return false;
                }
                return true;
            },
            draw: function (c) {
                c.save();
                c.beginPath();
                
                c.translate(this.x+this.w/2, this.y+this.h/2);
                c.arc(0, 0, this.w, 0, Math.PI*2);
                c.fillStyle = this.color;
                c.globalAlpha = this.alpha;
                
                c.closePath();
                c.fill();
                c.restore();
            }
        } // fin de Particle.prototype;
    </script>
  </head>
  <body>
      <noscript>
        No tiene habilitado JavaScript. Debería habilitarlo para poder
        disfrutar al completo de los contenidos de esta página.
      </noscript>
      <div>
          <canvas id="canvas">
              Tu navegador no soporta el elemento <code>canvas</code> de HTML5.
          </canvas>
      </div>
      <div id="title">
          fireworks!
      </div>
  </body>
</html>


Aquí el enlace a la presentación sobre efectos CSS3.


Para descargar la fuente te dejo la página el autor. Si la página deja de funcionar en algún momento intentaré subir la fuente que tengo en mi equipo.

Índice del curso

1 comentario :

  1. tengo un problema con los fuegos artificales, qusiera implementar la parte de cambiar la variable probability con la rueda del mouse en Firefox, peroo la funcion e.wheelDelta que usas, no es soportada, intente con DomMouseScroll y tiene barios problemas:
    1 sale "invertido" en donde esa variable debe crecer disminuye y viceversa, esto realmente no seria algo tan grave "invertir el codigo y compensar la variable invertida, lo cual genera la ilusion de normalidad", pero solo carga la primera funcion

    lo que en tu demo equivale a:
    function mouseWheel(e) {
    e = e || window.event;
    if (e.wheelDelta > 0) {
    probability += 0.01;
    }

    dime que alternativa puedo usar para Firefox, o si es mejor manipular desde teclado

    ResponderEliminar