Поделиться через


Краткое руководство. Захват рукописного ввода (HTML)

[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. При разработке приложений для Windows 10 см. раздел последняя документация]

В этом кратком руководстве содержатся инструкции по захвату данных рукописного ввода, получаемых от дигитайзера ввода.

Примечание  В этом разделе используется код из полностью функционального проекта Microsoft Visual Studio 2013 на JavaScript. Хотя проект недоступен для скачивания, полностью файлы каскадных таблиц стилей (CSS), HTML и JavaScript можно найти в разделе Полный код захвата рукописного ввода.

 

Обновления в Windows 8.1: В Windows 8.1 появилось множество обновлений и усовершенствований API ввода с помощью указателя. Дополнительные сведения см. в разделе Изменения API для Windows 8.1.

Цель: Изучив это краткое руководство, вы поймете, как использовать платформу рукописного ввода для обнаружения и захвата ввода с указывающего устройства (мышь, перо, сенсорный экран) в приложении Магазина Windows на JavaScript.

Необходимые условия

Предполагается, что вы умеете создавать простые приложения Магазина Windows на JavaScript с помощью шаблона библиотеки Windows для JavaScript.

Для выполнения этого руководства вам необходимо:

Инструкции

1. Создайте новый проект "Пустое приложение" в Visual Studio и добавьте файлы HTML, CSS и JavaScript.

В данном примере используются один HTML-файл ("InkPage.html"), один CSS-файл ("InkPage.css") и один файл JavaScript ("InkPage.js").

Полностью файлы CSS, HTML и JavaScript можно найти в разделе Полный код захвата рукописного ввода.

2. Настройте поверхность конструктора в вашем пользовательском интерфейсе

Данный пример использует элемент Canvas для отрисовки и обработки рукописного ввода.

canvas — это элемент HTML5, выполняющий роль поверхности для графических элементов, которые динамически отрисовываются, обрабатываются и изменяются в приложении Магазина Windows на JavaScript.

Примечание  Также можно использовать объект масштабируемой векторной графики.

 

В HTML-файле объявите элемент canvas и присвойте ему идентификатор (id) "inkCanvas". Используйте этот идентификатор (id) для ссылки на элемент из файла 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. Создайте диспетчер рукописного ввода

Объект InkManager обрабатывает и изменяет данные рукописного ввода, полученные через ввод указателем.

В файле JavaScript создайте диспетчер рукописного ввода. В данном примере объект InkManager является глобальным.

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

4. Подключите ваше приложение к поверхности конструктора

Для работы с объектом canvas и его дочерними элементами необходимо определить две переменные.

Первой переменной (inkCanvas) присваивается ссылка на элемент canvas, "inkCanvas", при помощи метода getElementById. Второй переменной (inkContext) присваивается контекст прорисовки элемента canvas (двухмерная поверхность в данном случае) при помощи метода getContext.

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

5. Определите функции обработчика событий

В этом разделе мы определим различные обработчики событий для ввода указателем. Они будут связаны с прослушивателями событий, которые вы добавите на следующем шаге.

  • pointerdown — событие, которое используется для начала записи рукописного ввода.

    В этом примере методы beginPath и moveTo используются для задания экранных координат места, где необходимо начать отображение данных рукописного ввода. (Запись и отображение рукописного ввода — это два отдельных действия.) Затем событие pointerdown обрабатывается с помощью inkManager, передавая данные указателя (currentPoint) события на ProcessPointerDown.

    Глобальная переменная penIDиспользуется для хранения pointerId указателя ввода, связанного с этим событием. О необходимости использования такой переменной мы расскажем позже.

    Примечание  Этот пример фильтрует ввод указателя (с помощью свойства pointerType) так, что сбор рукописного ввода осуществляется только для ввода пера и мыши, если нажата левая кнопка мыши. Сенсорный ввод зарезервирован для изменения пользовательского интерфейса вашего приложения.

     

        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.
            }
        }
    
  • Данные рукописного ввода записываются при возникновении события pointermove.

    В следующем примере глобальная переменная penId позволяет убедиться, что свойство pointerId для этого события идентично свойству, связанному с событием pointerdown. Если это не так, ввод игнорируется и рукописный ввод не записывается. Такая проверка полезна, например, для отфильтровывания ввода с помощью мыши, которая случайно переместилась во время движения пера.

    Метод lineTo (с использованием параметра RawPosition указателя согласно сообщению дигитайзера) и методы stroke вызываются для немедленной прорисовки и отображения данных рукописного ввода в виде отдельных сегментов линии. (Запись и отображение рукописного ввода — это два отдельных действия.) Затем событие pointermove обрабатывается с помощью inkManager, передавая данные указателя (currentPoint) события на 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.
            }
        }
    
  • Запись данных рукописного ввода завершается при возникновении события pointerup.

    Как и в предыдущем примере, эта функция использует глобальную переменную penId, чтобы проверить, идентично ли свойство pointerId для этого события свойству, связанному с событиями pointerdown и pointermove. Если это не так, ввод игнорируется и рукописные данные не записываются.

    Методы lineTo, stroke и closePath вызываются, чтобы завершить и закрыть контур, созданный в функции handlePointerDown. Затем событие pointerup обрабатывается с помощью inkManager, передавая данные указателя (currentPoint) события на ProcessPointerUp.

    В этом примере вызывается дополнительная функция renderAllStrokes для обработки данных рукописного ввода и преобразования необработанных сегментов росчерка в элемент canvas в виде плавных кривых (см. раздел Обработка данных рукописного ввода).

    // 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.
        }
    }
    

См. ссылки на более сложные примеры в разделе "Связанные темы" в нижней части страницы.

6. Подключите прослушиватели событий ввода к поверхности конструктора

Используя ссылку на элемент canvas, подключите прослушиватели PointerEvent и свяжите их с обработчиками событий указателя, определенными на предыдущем шаге.

  • Событие pointerdown возникает, когда пользователь нажимает пером или пальцем на поверхность дигитайзера либо щелкает левой кнопкой мыши.
  • Событие pointermove возникает, когда указатель, связанный с событием pointerdown, перемещается по canvas.
  • Событие pointerup возникает, когда пользователь убирает перо или палец с поверхности дигитайзера или отпускает левую кнопку мыши.
// Set up the handlers for input processing.
inkCanvas.addEventListener("pointerdown", onPointerDown, false);
inkCanvas.addEventListener("pointermove", onPointerMove, false);
inkCanvas.addEventListener("pointerup", onPointerUp, false);

Сводка

Теперь вы имеете представление о том, как захватывать данные рукописного ввода с помощью своего приложения Магазина Windows.

Чтобы понаблюдать за действием этого кода, выполните сборку и запустите образцы рукописного ввода, представленные на домашней странице образцов приложений Магазина Windows:

Связанные разделы

Понятия

Реакция на ввод с помощью пера

Справочные материалы

Windows.Devices.Input

Windows.UI.Core

Windows.UI.Input

Windows.UI.Input.Inking

Примеры (DOM)

Ввод: пример обработки событий указателя DOM

Примеры (API приложения Магазина Windows)

Ввод: пример возможностей устройства

Ввод: пример рукописного ввода

Ввод: пример упрощенного рукописного ввода