Guia de início rápido: capturando dados a tinta (HTML)

[ Este artigo destina-se aos desenvolvedores do Windows 8.x e do Windows Phone 8.x que escrevem aplicativos do Windows Runtime. Se você estiver desenvolvendo para o Windows 10, consulte documentação mais recente]

Este guia de início rápido fornece informações passo a passo sobre a captura de dados a tinta de um digitalizador de entrada.

Observação  O código usado neste tópico foi tirado do projeto funcional totalmente JavaScript no  Microsoft Visual Studio 2013. Enquanto o projeto não estiver disponível para download, os arquivos completos das Folhas de Estilo em Cascata (CSS), HTML e JavaScript podem ser encontrados no Capturando código completo de dados de tinta.

 

Atualizações para Windows 8.1: O Windows 8.1 introduz uma série de atualizações e melhorias para as APIs de entrada de ponteiro. Para saber mais, veja Alterações de API para Windows 8.1.

Objetivo: Ao concluir este guia de início rápido, você entenderá como usar a plataforma de tinta para detectar e capturar entradas de um dispositivo de ponteiro (mouse, caneta ou toque) em um aplicativo da Windows Store com JavaScript.

Pré-requisitos

Nós supomos que você possa criar um aplicativo básico da Windows Store em JavaScript que use o modelo da Biblioteca do Windows para JavaScript.

Para completar este tutorial, você precisa:

Instruções

1. Crie um novo projeto "Aplicativo em branco" no Visual Studio e adicione arquivos HTML, CSS e JavaScript.

Para esse exemplo, nós temos um arquivo HTML ("InkPage.html"), um arquivo CSS ("InkPage.css") e um arquivo JavaScript ("InkPage.js").

Os arquivos completos de CSS, HTML e JavaScript podem ser encontrados em Capturando código completo de dados de tinta.

2. Configure uma superfície de desenho na sua interface do usuário

Este exemplo usa um elemento Canvas como o desenho com tinta e a superfície de renderização.

Um canvas é um elemento do HTML5 que atua como uma superfície para desenho dinâmico, renderização e manipulação de elementos gráficos em um aplicativo da Windows Store com JavaScript.

Observação  Um objeto SVG (Elementos Gráficos Vetoriais Escaláveis) também pode ser usado.

 

No arquivo HTML, declare um elemento canvas e dê a ele um id do "inkCanvas". Use esta id para referenciar o elemento no arquivo JavaScript.

<body>
<div id="applicationTitle">Ink sample</div>
<div>
    <canvas id="inkCanvas"></canvas>
    <div>
        <button id="load">Load</button>
        <button id="save">Save</button>
        <button id="draw">Draw</button>
        <button id="select">Select</button>
        <button id="selectall">Select all</button>
        <button id="erase">Erase</button>
        <button id="eraseAll">Erase all</button>
        <button id="recognize" value="selected">Handwriting recognition</button>
    </div>
</div>
<div id="modeMessage"></div>
<div id="deviceMessage"></div>
<div id="statusMessage"></div>
</body>

3. Crie um gerenciador de tinta

Um objeto InkManager processa e manipula os dados relacionados à tinta obtidos da entrada do ponteiro.

No arquivo JavaScript, crie o InkManager. Para esse exemplo, o objeto InkManager é global.

        // Create an ink manager.
        // InkManager is documented at https://go.microsoft.com/fwlink/?LinkID=260648.
        var inkManager = new Windows.UI.Input.Inking.InkManager();

4. Conecte o seu aplicativo à superfície de desenho

Para trabalhar com o canvas e seus elementos filhos, é necessário que você defina duas variáveis.

A primeira variável (inkCanvas) recebe uma referência ao elemento canvas, "inkCanvas", usando getElementById. A segunda variável (inkContext) recebe um contexto de desenho do elemento canvas (uma superfície 2D, neste caso), usando o método getContext.

// Obtain reference to the specified element.
function get(elementId)
{
    return document.getElementById(elementId);
}
inkCanvas = get("inkCanvas");
inkContext = inkCanvas.getContext("2d");

5. Definir as funções de manipulação de eventos

Nesta seção, nós definimos os vários manipuladores de eventos obrigatórios para a entrada do ponteiro. Eles serão associados aos ouvintes de eventos que você adicionar na próxima etapa.

  • pointerdown é o evento usado para iniciar a captura de tinta.

    Neste exemplo, os métodos beginPath e moveTo são usados para definir o local, em coordenadas da tela, no qual iniciar a exibição dos dados a tinta. (Capturar tinta e exibi-la são duas ações separadas). O evento pointerdown é, então, processado pelo inkManager passando os dados do ponteiro (currentPoint) do evento para ProcessPointerDown.

    A variável global penID é usada para armazenar o pointerId do ponteiro de entrada associado a esse evento. Discutiremos a necessidade disso mais adiante.

    Observação  Este exemplo filtra a entrada do ponteiro (usando a propriedade pointerType) de maneira que a captura de tinta seja realizada para a entrada com caneta e para a entrada com mouse apenas quando o botão esquerdo está pressionado. A entrada por toque é reservada para manipulação da interface do usuário do aplicativo.

     

        function getPointerDeviceType(pId)
        {
            var pointerDeviceType;
            var pointerPoint = Windows.UI.Input.PointerPoint.getCurrentPoint(pId);
            switch (pointerPoint.pointerDevice.pointerDeviceType)
            {
                case Windows.Devices.Input.PointerDeviceType.touch:
                    pointerDeviceType = "Touch";
                    break;
    
                case Windows.Devices.Input.PointerDeviceType.pen:
                    pointerDeviceType = "Pen";
                    break;
    
                case Windows.Devices.Input.PointerDeviceType.mouse:
                    pointerDeviceType = "Mouse";
                    break;
                default:
                    pointerDeviceType = "Undefined";
            }
            deviceMessage.innerText = pointerDeviceType;
            return pointerDeviceType;
        }
    
        // Occurs when the pointer (touch, pen, mouse) is detected by the canvas.
        // Each stroke begins with onPointerDown.
        function onPointerDown(evt)
        {
            // Get the device type for the pointer input.
            pointerDeviceType = getPointerDeviceType(evt.pointerId);
    
            // Process pen and mouse (with left button) only. Reserve touch for manipulations.
            if ((pointerDeviceType === "Pen") || ((pointerDeviceType === "Mouse") && (evt.button === 0)))
            {
                statusMessage.innerText = pointerDeviceType + " pointer down: Start stroke. "
    
                // Process one pointer at a time.
                if (pointerId === -1)
                {
                    var current = evt.currentPoint;
    
                    // Start drawing the stroke.
                    inkContext.beginPath();
                    inkContext.lineWidth = strokeWidth;
                    inkContext.strokeStyle = strokeColor;
    
                    inkContext.moveTo(current.position.x, current.position.y);
    
                    // Add current pointer to the ink manager (begin stroke).
                    inkManager.processPointerDown(current);
    
                    // The pointer id is used to restrict input processing to the current stroke.
                    pointerId = evt.pointerId;
                }
            }
            else
            {
                // Process touch input.
            }
        }
    
  • Dados a tinta são capturados quando ocorre um evento pointermove.

    No exemplo a seguir, a variável global, penId, é usada para assegurar que o pointerId para este evento seja idêntico ao do evento pointerdown associado. Caso contrário, a entrada é ignorada e não há captura de dados a tinta. Isso é útil, por exemplo, para filtrar a entrada de um mouse movido acidentalmente enquanto um traço é riscado com a caneta.

    Os métodos lineTo (que usam o RawPosition do ponteiro conforme relatado pelo digitalizador) e stroke são chamados para desenhar e exibir os dados da tinta imediatamente como segmentos de linha discretos. (Capturar tinta e exibi-la são duas ações separadas). O evento pointermove é, então, processado pelo inkManager passando os dados do ponteiro (currentPoint) do evento para ProcessPointerUpdate.

        // Mouse: Occurs when the pointer moves.
        // Pen/Touch: Occurs at a steady rate (approx. 100 messages/second) whether the pointer moves or not.
        function onPointerMove(evt)
        {
            // Process pen and mouse (with left button) only. Reserve touch for manipulations.
            if ((pointerDeviceType === "Pen") || ((pointerDeviceType === "Mouse") && (evt.button === -1)))
            {
                statusMessage.innerText = pointerDeviceType + " pointer move: Draw stroke as lines. "
                // The pointer Id is used to restrict input processing to the current stroke.
                // pointerId is updated in onPointerDown().
                if (evt.pointerId === pointerId)
                {
                    var current = evt.currentPoint;
    
                    // Draw stroke in real time.
                    inkContext.lineTo(current.rawPosition.x, current.rawPosition.y);
                    inkContext.stroke();
    
                    // Add current pointer to the ink manager (update stroke).
                    inkManager.processPointerUpdate(current);
                }
            }
            else
            {
                // Process touch input.
            }
        }
    
  • A captura de dados a tinta é concluída quando ocorre um evento pointerup.

    Como no exemplo anterior, esta função usa a variável global, penId, para assegurar que o pointerId para este evento seja idêntico aos eventos associados pointerdown e pointermove. Caso contrário, a entrada é ignorada e não há captura de dados a tinta.

    Os métodos lineTo, stroke e closePath são chamados para completar e fechar o caminho criado na função handlePointerDown. O evento pointerup é, então, processado pelo inkManager passando os dados do ponteiro (currentPoint) do evento para ProcessPointerUp.

    A função renderAllStrokes neste exemplo é opcional e é chamada para processar os dados de tinta e processar os segmentos de traços brutos no elemento canvas como curvas suaves (Veja Como para processar dados de tinta).

    // Occurs when the pointer (touch, pen, mouse) is lifted from the canvas.
    // Each stroke ends with onPointerUp.
    function onPointerUp(evt)
    {
        // Process pen and mouse (with left button) only. Reserve touch for manipulations.
        if ((pointerDeviceType === "Pen") || ((pointerDeviceType === "Mouse") && (evt.button === 0)))
        {
            statusMessage.innerText = pointerDeviceType + " pointer up: Finish stroke. "
            if (evt.pointerId === pointerId) {
                // Add current pointer to the ink manager (end stroke).
                inkManager.processPointerUp(evt.currentPoint);
    
                // End live drawing.
                inkContext.closePath();
    
                // Render strokes using bezier curves.
                renderAllStrokes();
    
                // Reset pointer Id.
                pointerId = -1;
            }
        }
        else
        {
            // Process touch input.
        }
    }
    

Confira os Tópicos relacionados no final desta página para acessar links para exemplos mais complexos.

6. Anexe ouvintes de eventos de entrada à superfície de desenho

Usando a referência ao elemento canvas, anexe os ouvintes PointerEvent e associe-os com os manipuladores de eventos de ponteiro definidos na etapa anterior.

  • pointerdown dispara quando um usuário pressiona a superfície do digitalizador com uma caneta ou dedo ou se clica no botão esquerdo de um mouse.
  • pointermove dispara quando o ponteiro associado ao evento pointerdown se move ao longo de canvas.
  • pointerup é disparado quando o usuário levanta a caneta ou o dedo da superfície digitalizadora ou quando ele solta o botão esquerdo do mouse.
// Set up the handlers for input processing.
inkCanvas.addEventListener("pointerdown", onPointerDown, false);
inkCanvas.addEventListener("pointermove", onPointerMove, false);
inkCanvas.addEventListener("pointerup", onPointerUp, false);

Resumo

Agora você tem uma ideia básica de como capturar dados a tinta com o seu aplicativo da Windows Store.

Para ver este código em ação, construa e execute os exemplos de tinta a seguir na Página inicial de exemplo de aplicativo da Windows Store:

Tópicos relacionados

Conceitual

Respondendo à entrada de caneta

Referência

Windows.Devices.Input

Windows.UI.Core

Windows.UI.Input

Windows.UI.Input.Inking

Amostras (DOM)

Entrada: amostra de manipulação de eventos de ponteiros DOM

Amostras (APIs de aplicativos da Windows Store )

Entrada: amostra de recursos de dispositivo

Entrada: amostra de tinta

Entrada: amostra de tinta simplificada