desigual

Recursos

Un poco de historia

Flash plugin

En 2006 fue adoptado por la W3C e incluido en la nueva especificacion HTML5

Soportado por navegadores modernos.

Compatibilidad navegador

Demos creativas

Implementacion web

Apple

Diesel

¿Qué es <canvas>?

  • Es el contenedor para nuestros gráficos

  • Permite dibujar en la página y actualizar lo que dibujamos dinamicamente

Características básicas

  • El area de dibujo es un conjunto de pixels

  • Responde a eventos JavaScript y a las acciones de los usuarios
  • Trabaja con pixels, lo que significa rasterizado (lo contrario a vector)
  • Buena performance
  • The sky is the limit

Pros

  • Complicado hacerlo accesible DOM

  • Responsive (reorganizar contenido basado en el viewport)

  • Retina

  • Debugar

Contras

API 2D de <canvas>

  • Objeto que nos permite dibujar y manipular imágenes y gráficos dentro de un elemento canvas

  • Tenemos que hacer una llamada a getContext();)

Método principal

  • canvas.getContext("");
  • Devuelve un objeto que proporciona todos los métodos y propiedades para dibujar en el canvas
  • El contexto de dibujo define si estamos pintando en 2D o 3D.

getContext()

Entendiendo el Lienzo

Coordenadas

  • Utilizadas para poder situar los elementos en el canvas

  • Funciona como un sistema de coordenadas cartesiano

  • El punto (0,0) comienza en la esquina superior izquierda

Primeros pasos

<head>
    <title>Con canvas y a lo loco</title>
    <script src="ejemplo.js"></script>
</head>
<body>
    <canvas id="canvasBilbo" width="500" height="300">
       <!-- medidas por defecto:
             width = 300px
             height = 150px -->
    </canvas>
</body>
  • Colocar la etiqueta <canvas> en el cuerpo de la página
  • Indicamos el valor de los 2 atributos principales o por defecto será de width 300px y height 150px
  • Dibujar en el <canvas> utilizando un script en Javascript
  • Asignaremos un nombre único
  • Para referirnos a este canvas a través de JS

Identificador #id

Setup básico

var canvas = document.getElementById("canvasBilbo");
var ctx = canvas.getContext("2d");
<canvas id="canvasBilbo" width="500" height="300"></canvas>

HTML

JavaScript

Soporta varias formas primitivas

Rectangulos

fillRect (x, y, w, h)

Dibuja un rectángulo relleno

strokeRect (x,y,w,h)

Dibuja el contorno de un rectángulo

clearRect (x,y,w,h)

Borra un área rectangular especificada

var canvas = document.getElementById("canvasBilbo");
var ctx = canvas.getContext("2d");

ctx.fillRect(25,25,100,100);
ctx.clearRect(45,45,60,60);
ctx.strokeRect(50,50,50,50);
<canvas id="canvasBilbo" width="500" height="300"></canvas>

HTML

JavaScript

Líneas

lineTo (x, y)

Dibuja una linea desde la posición actual a la especificada

*El punto final de un trazo es el inicial para el siguiente

moveTo (x,y,w,h)

Permita que cambiemos el punto de inicio del trazo

lineCap = type

Podemos determinar como acaba cada punto

lineJoin = type

Como se conectan dos segmentos

var canvas = document.getElementById("canvasBilbo");
var ctx = canvas.getContext("2d");

ctx.moveTo(0,0); //configurar punto de salida
ctx.lineTo(200,100); //configurar path al punto final
ctx.stroke(); //dibujar una linea de 1px width
<canvas id="canvasBilbo" width="500" height="300"></canvas>

HTML

JavaScript

Paths

Podemos dibujar formas geométricas uniendo varias lineas en un trazado 

beginPath ()

Crea un nuevo trazado

closePath ()

Cierra el trazado

stroke ()

Dibuja la linea del contorno

fill ()

Rellena el trazado

var canvas = document.getElementById("canvasBilbo");
var ctx = canvas.getContext("2d");

ctx.beginPath();
// X pos, Y pos, Radius, start point, end point
ctx.arc(95, 50, 40, 0, 2 * Math.PI); 
ctx.stroke();

JavaScript

<canvas id="canvasBilbo" width="500" height="300"></canvas>

HTML

Texto

fillText (x, y)

Crea un texto (relleno) en la posición dada (x,y)

strokeText (x,y)

Crea un texto (trazo) en la posición dada (x,y)

  • Los nombres de propiedades son parecidos a los de CSS

  • Puedes elegir el style, size y font family
var canvas = document.getElementById("canvasBilbo");
var ctx = canvas.getContext("2d");

ctx.font = "30px Arial";
ctx.fillStyle = 'orange';
ctx.fillText("Hola Bilbao!",10,50);
<canvas id="canvasBilbo" width="500" height="300"></canvas>

HTML

JavaScript

Degradados

var canvas = document.getElementById("canvasBilbo");
var ctx = canvas.getContext("2d");

// Creando degradado
var degra = ctx.createLinearGradient(0,0,200,0);
degra.addColorStop(0,"orange");
degra.addColorStop(1,"white");

// Relleno
ctx.fillStyle = degra;
ctx.fillRect(10,10,150,80);

JavaScript

<canvas id="canvasBilbo" width="500" height="300"></canvas>

HTML

Transformaciones

translate (x, y)

Mueve el canvas y su origen

rotate (x, y)

Rota el canvas en el sentido del reloj

scale (x, y)

Escala el dibujo

Animando

  • Limpiar el canvas

  • Dibujar la nueva escena

Pasos fundamentales

setTimeout(); (function, delay)

No recomendable

  • Esta función ha servido desde hace muchos años para toda clase de acciones como temporizador

  • No fue contemplada para animaciones

  • Requiere múltiples llamadas por segundo, consumiendo muchos recursos de CPU

requestAnimationFrame()

  • Informa al navegador que quieres realizar una animación

  • Solicita que el navegador programe el repintado de la ventana para el próximo ciclo de animación

  • Método nativo disponible en el objeto window de JS

  • Genera las acciones para que se llamen constantemente, realiza la interpolación por ti (animaciones más suaves)

var canvas = document.getElementById("canvasBilbo");
var ctx = canvas.getContext("2d");
var x = 0;

setInterval(function() {
    ctx.fillStyle= "orange";
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillRect(x, 50, 50, 50); 
    x += 1;
}, 30);

JavaScript

<canvas id="canvasBilbo" width="500" height="300"></canvas>

HTML

Imágenes

Puede trabajar con imágenes en los formatos más comunes (gif, jpg, png)

Para dibujar una imagen en el lienzo se utiliza el Método drawImage()

<canvas> vs <svg>

canvas

  • Orientado al pixel (elemento de imagen con un API de dibujo)

  • Elemento HTML individual, similar en su comportamiento a la etiqueta <img>

  • La representación visual se crea y modifica "on the fly" via scripting

  • El modelo de evento/interacción con el usuario es rudimentario y las interacciones se deben programar manualmente a partir de las coordenadas del ratón

  • No DOM
  • La API no soporta la accesibilidad

svg

  • Múltiples elementos gráficos con su propio (DOM)

  • La representación visual se genera a partir del markup y se modifica mediante CSS scripting JS

  • El modelo de evento/interacción con el usuario

  • Soporta accesibilidad de forma nativa

El API no soporta la accesibilidad

Manos a la obra

var Class = function(){return function(){this.initialize.apply(this,arguments)}}
var Stage = Class();
Stage.prototype = {
    initialize: function(canvasId, bgColor, rate) {
        this.rate = Math.round( 1000 / rate );
        this.canvas = document.getElementById("canvasBilbo");
        this.context = this.canvas.getContext("2d");
        this.bgColor = bgColor;
        this.rect = this.canvas.getBoundingClientRect();
        this.mouseX = 0;
        this.mouseY = 0;
        this.children = [];
        var self = this;
        this.canvas.onmousemove = function(e) {
            self.mouseX = e.clientX - self.rect.left;
            self.mouseY = e.clientY - self.rect.top;
        };
    },
//...

    refresh:function(){
        this.context.fillStyle = this.bgColor;
        this.context.fillRect(0, 0, this.canvas.width ,     this.canvas.height );
    },
    addChild:function(obj){
        this.refresh();
        this.children.push( obj );
        obj.stage = this;
        obj.draw();
    },
    update:function(){
        this.refresh();
        for( var i = 0; i < this.children.length; i++ ) {
            this.children[i].draw();
        }
    },
    rendering:function(func){
        var self = this;
        setInterval( function(){
            func();
            self.update();
        }, this.rate );
    }
};

var Circle = Class();
Circle.prototype = {
    initialize: function(radius, color) {
        this.radius = radius;
        this.color = color;
        this.stage = null;
        this.x = 0;
        this.y = 0;
    },
    draw: function(){
        if( this.stage == null ) return;
        
        var ctx = this.stage.context;
        ctx.fillStyle = this.color;
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true);
        ctx.closePath();
        ctx.fill();
    }
};

window.addEventListener("load", function(){
    var stage = new Stage("canvas", "black", 50);
    var circle = new Circle(10 , "orange");
    stage.addChild(circle);
    stage.rendering(function(){
        circle.x += (stage.mouseX - circle.x) * 0.1;
        circle.y += (stage.mouseY - circle.y) * 0.1;
    });
});

JavaScript

Librerías

Creative coding

Pintar con matemáticas

Processing.js

P5.js

  • Creative Coding Accesible  para todos
  • Nivel alto de abstracción

Setup básico

<head>
 <script src="p5.min.js"></script>
 <script src="sketch.js"></script>
</head>

HTML

function setup() { 
  createCanvas(400, 400);
} 

function draw() { 
  background('orange');
}

JavaScript

Funciones esenciales

Setup function

  • Código relativo a la inicialización de nuestra app

  • Crear un canvas 
  • Todo lo escrito dentro de esta función será ejecutado una vez arranque la página

  • Aquí es donde irá nuestro código relativo a las funcionalidades de dibujo

  • Esta función se ejecuta después de la función Setup, y se irá ejecutando continuamente (alrededor de 60 frames por segundo)

Draw function

p5.js Demos

WebGL

Tecnología nativa contexto 3D

Pros

  • Interacción y efectos
  • Hardware-accelerated
  • VR

Contras

  • Complicado lidiar con la escena
  • Comunidad pequeña (pero creciendo)
  • "Please visit desktop version"

Three.js

Demo

Gracias