App para desenho usando Canvas HTML5

Este aplicativo de exemplo em HTML5 utiliza o Canvas para desenhos livres usando toque, um mouse ou o acelerômetro dos dispositivos. Este App pode ser executado em navegadores compatíveis com o HTML5, ou pode ser empacotado como um aplicativo híbrido usando o PhoneGap* ou o Intel XDK e ser executado em dispositivos Apple iOS* e Android*, entre outros.

SketchPad App screenshot

Esta app utiliza o framework jQuery Mobile para implementar os elementos da UI de forma que escalem consistentemente em diferentes dispositivos, sistemas operacionais e navegadores. Este post descreve como uma linha é desenhada utilizando o canvas HTML5 e então explica como os handlers de eventos de mouse e toque do jQuery são usados para implementar o desenho livre utilizando toque e mouse. Ele também utiliza as APIs de acelerômetro do Cordova para implementar o desenho com base na inclinação do dispositivo. A App utiliza manipulação básica de CSS, usando o jQuery para implementar outros elementos da UI como a paleta de seleção de cores.

O código fonte completo deste app está disponível no github. Este github possui ainda códigos fonte de exemplos para criar aplicações de desenho baseado em toque com:

  • somente JavaScript
  • jQuery
  • jQuery + jQuery Mobile para a UI
  • desenho com canvas usando o aceletrômetro dos dispositivos com as APIs do Cordova

 

DEMO


 

Desenhando uma linha usando o Canvas

O trecho de código em Javascript abaixo mostra a forma mais simples para se desenhar uma linha usando o canvas.

function drawLine()
{
    var ctx=document.getElementById("canvas").getContext("2d");
    ctx.beginPath(); 
    ctx.moveTo(10,10);
    ctx.lineTo(50,50);
    ctx.lineWidth = 5;
    ctx.strokeStyle = "#00F"; 
    ctx.stroke(); 
}

Este código básico é usado com eventos de toque e mouse para possibilitar o desenho livre com toques ou utilizando um mouse. Os métodos moveTo() e lineTo() de getContext("2d") são utilizados para definir os pontos inicial e final das linhas. As propriedades lineWidth e strokeStyle de getContext("2d") são usados para configurar a largura da linha e a seleção de cores na App.O método stroke() é usado para desenhar a linha baseado no evento de toque ou mouse.


 

Desenhando com eventos de toque

O trecho de código em Javascript abaixo mostra a implementação de eventos de toque para desenhar linhas no canvas. O evento "touchstart" do jQuery é usado para setar o ponto inicial da linha usando o método moveTo() e o evento "touchmove" é usado para setar o ponto final da linha usando o método lineTo(), seguido pelo método stroke() para finalmente desenhar a linha no canvas.

$.fn.drawTouch = function() {
    var start = function(e) {
        var touchEvent = e.originalEvent.changedTouches[0];
        ctx.beginPath();  
        ctx.moveTo(touchEvent.pageX, touchEvent.pageY);
    };
    var move = function(e) {
        var touchEvent = e.originalEvent.changedTouches[0];
        e.preventDefault();
        ctx.lineTo(touchEvent.pageX, touchEvent.pageY);
        ctx.stroke();
    };
    $(this).touchstart(start);
    $(this).touchmove(move);
};

 

Desenhando com eventos MSPointer (para o Microsoft* IE)

O trecho de código em Javascript abaixo mostra a implementação dos eventos mspointer para desenhar linhas no canvas. Os eventos "MSPointer" são requeridos para funcionar no Internet Explorer, e nos dispositivos Windows Phone e Windows Surface. O evento "mspointerdown" do jQuery é usado para setar o ponto inicial da linha usando o método moveTo() e o evento "mspintermove" é utilizado para setar o ponto final da linha usando o método lineTo(), seguido pelo método stroke(), que finalmente desenha a linha no canvas.

$.fn.drawPointer = function() {
        var start = function(e) {
        e = e.originalEvent;
                ctx.beginPath();
                x = e.pageX;
                y = e.pageY-44;
                ctx.moveTo(x,y);
        };
        var move = function(e) {
                e.preventDefault();
        e = e.originalEvent;
                x = e.pageX;
                y = e.pageY-44;
                ctx.lineTo(x,y);
                ctx.stroke();
    };
        $(this).on("MSPointerDown", start);
        $(this).on("MSPointerMove", move);
};

Desenhando com eventos de mouse

O trecho de código em Javascript abaixo mostra a implementação de eventos de mouse para desenhar linhas no canvas. O evento "mousedown" do jQuery é usado para setar o ponto inicial da linha usando o método moveTo(), e o evento "mousemove" é usado para setar o ponto final da linha através do método lineTo(), seguido do método stroke() que finalmente desenha a linha no canvas. O evento "mouseup" é usado para garantir que seja possível apenas desenhar quando o botão do mouse estiver clicado e se movendo, e não quando o mouse estiver apenas se movendo pelo canvas.

$.fn.drawMouse = function() {
    var clicked = 0;
    var start = function(e) {
        clicked = 1;
        ctx.beginPath();
        ctx.moveTo(e.pageX, e.pageY);
    };
    var move = function(e) {
        if(clicked){
            ctx.lineTo(e.pageX, e.pageY);
            ctx.stroke();
        }
    };
    var stop = function(e) {
        clicked = 0;
    };
    $(this).mousedown(start);
    $(this).mousemove(move);
    $(this).mouseup(stop);
};

Desenhando com o acelerômetro

Esta app também implementa o acelerômetro para desenhar linhas, baseado em como o dispositivo é inclinado. O trecho de código em Javascript abaixo mostra como o acelerômetro é usado para implementar isso. Os valores de x e y retornados pelo acelerômetro são usados para desenhar a linha para a direita/esquerda ou para cima/para baixo. O valor também é usado para determinar o comprimento do desenho da linha, que aparece para o usuário como a velocidade em que a linha é desenhada, e é proporcional ao valores de x/y do acelerômetro. A linha é desenhada mais rápido se o dispositivo estiver mais inclinado.

// Inicia o monitoramento do acelerometro
function startWatch() {
    // Atualiza a aceleracao uma vez por segundo
    var options = { frequency: 100 };
    watchID = navigator.accelerometer.watchAcceleration(onSuccess, onError, options);
}

// Para de monitorar o acelerometro
function stopWatch() {
    if (watchID) {
        navigator.accelerometer.clearWatch(watchID);
        watchID = null;
    }
}

// onSuccess: desenha a linha com base na quantidade e direcao da inclinacao
function onSuccess(acceleration) {
    // desenha com base nas posicoes do acelerometro
    if(acceleration.x > 2 && Math.abs(acceleration.y) < 2 ){
        if (x < 3){ x = 3; } // stop drawing at edge of canvas
        x = x-Math.abs(acceleration.x); // length of line drawn is made proportional to tilt
        ctx.lineTo(x, y);
        ctx.stroke();
    } else if(acceleration.x < -2 && Math.abs(acceleration.y) < 2){
        if (x > $(window).width() - 3){ x = $(window).width() - 3;}
            x = x+Math.abs(acceleration.x);
            ctx.lineTo(x, y);
            ctx.stroke();
    } else if(acceleration.y > 2 && Math.abs(acceleration.x) < 2){
            if (y > $(window).height() - 93) { y = $(window).height() - 93;}
            y = y+Math.abs(acceleration.y);
            ctx.lineTo(x, y);
            ctx.stroke();
    } else if(acceleration.y < -2 && Math.abs(acceleration.x) < 2){
            if(y < 3) { y = 3;}
            y = y-Math.abs(acceleration.y);
            ctx.lineTo(x, y);
            ctx.stroke();
    }	
}

SketchPad App screenshot

A app também implementa a função de vibração para alertar o usuário quando o cursor alcançar o final do canvas, quando ele estiver usando o modo acelerômetro para desenhar. Isto é implementado usando a chamada navigator.notification.vibrate().

Para obter informações mais completas sobre otimizações do compilador, consulte nosso aviso de otimização.