Краткое руководство: жесты управления (HTML)
[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. При разработке приложений для Windows 10 см. раздел последняя документация]
Вы можете изменить механизм взаимодействия пользователя для жестов управления, описанных в языке касаний Windows, таких как скольжение, прокрутка, вращение, сжатие и растяжение. Для этого в приложении вам необходимо обрабатывать события жестов среды выполнения Windows с использованием JavaScript.
Большинство приложений обрабатывают жесты касания (поворота, масштабирования и перетаскивания), а необработанные данные указателя просто передают средству обнаружения жестов, не используя их никаким иным образом. В этом примере мы используем необработанные данные указателя для поддержки обработки статического жеста. Это дополняет модель взаимодействия вашего приложения базовыми событиями указателя, о которых говорится в разделе Краткое руководство: указатели.
Обновления в Windows 8.1: В Windows 8.1 появилось множество обновлений и усовершенствований API ввода с помощью указателя. Подробнее: Изменения API для Windows 8.1.
Если у вас нет опыта в разработке приложений на JavaScript: Прочитайте эти разделы, чтобы ознакомиться с технологиями, обсуждаемыми в данной статье.
Создание первого приложения на JavaScript
Схема создания приложений на JavaScript
Информацию о событиях см. в разделе Краткое руководство: добавление элементов управления HTML и обработчиков событий
Компоненты приложения от начала до конца:
Дополнительные сведения об этой функциональности см. в нашей серии Компоненты приложения от начала до конца.
Взаимодействие с пользователем от А до Я (HTML)
Настройка взаимодействия с пользователем от А до Я (HTML)
Рекомендации по взаимодействию с пользователем:
Библиотеки элементов управления платформы (HTML и XAML) предоставляют все механизмы взаимодействия с пользователем, в том числе стандартные взаимодействия, анимированные физические эффекты и визуальную обратную связь. Если вы не планируете настраивать механизмы поддержки взаимодействий, используйте стандартные элементы управления.
Если элементов управления, предоставляемых платформой, недостаточно, то, чтобы обеспечить привлекательный и современный единый механизм взаимодействия для всех режимов ввода, вы можете воспользоваться следующими рекомендациями. В основном эти рекомендации описывают сенсорный ввод, но также применимы к вводу с сенсорной панели, мыши, клавиатуры и пера.
- Руководство по стандартным способам взаимодействия с пользователем
- Рекомендации по скольжению по диагонали
- Руководство по визуальному масштабированию и изменению размеров
- Руководство по функции сдвига
- Рекомендации по вращению
- Руководство по контекстному масштабированию
- Рекомендации по выделению текста и изображений
- Рекомендации по нацеливанию
- Руководство по визуальной обратной связи
Примеры: Примеры использования этой функциональности см. в коллекции примеров приложений.
Пример настройки взаимодействия с пользователем от А до Я
Ввод: пример обработки событий указателя DOM
Ввод: пример реализации манипуляций и жестов (JavaScript)
Цель: Описывается ожидание и обработка жестов управления на основе данных, вводимых с помощью касания, мыши, пера, и событий жестов среды выполнения Windows.
Необходимые условия
См. Краткое руководство: указатели, Краткое руководство: жесты и манипуляции модели DOM и Краткое руководство: статические жесты.
Предполагается, что вы умеете создавать простые приложения на JavaScript с использованием шаблона библиотеки Windows для JavaScript.
Для выполнения этого руководства вам необходимо:
- Установить Microsoft Visual Studio.
- Получить лицензию разработчика. Инструкции см. в разделе о разработке с помощью Visual Studio 2013.
- Создание первого приложения на JavaScript.
- Сведения об объектах и элементах управления WinJS см. в документе Краткое руководство: добавление элементов управления и стилей WinJS.
Что такое события жестов?
Жест — это физическое действие или движение, выполненное при помощи устройства ввода. Это понятие включает в себя один или несколько пальцев на поверхности касания, пера, дигитайзера, мыши и т. д. Такое естественное взаимодействие сопоставляется с операциями над элементами системы и вашего приложения. См. также раздел Жесты, манипуляции и взаимодействия.
В таблице ниже определяются жесты управления, рассмотренные в этом кратком руководстве. Чтобы получить информацию о поддержке статических жестов, таких как касание или нажатие и удерживание, см. раздел Краткое руководство: статические жесты.
Жест | Описание | |
---|---|---|
Скольжение |
Один или более контактов, перемещающихся за пределы порогового значения расстояния. Если функция сдвига не включена, а первоначальный контакт находится в границах элемента, жест скольжения приводит к перемещению элемента. Если функция сдвига включена, первоначальный контакт находится в границах элемента, а направление скольжения перпендикулярно оси сдвига, то жест скольжения также приводит к перемещению элемента. В противном случае инициируется функция сдвига.
| |
Прокрутка |
Один или несколько контактов, перемещающихся в пределах порогового значения расстояния (короткий скользящий жест). Прокрутка не является жестом, обработка которого определяется временем или скоростью. Если приложение не поддерживает функцию сдвига, а первоначальный контакт находится в границах элемента, жест прокрутки приводит к перемещению элемента. Если приложение поддерживает функцию сдвига, первоначальный контакт находится в границах элемента, а направление прокрутки перпендикулярно оси сдвига, то жест прокрутки приводит к выбору элемента. В противном случае жест прокрутки инициирует функцию сдвига.
| |
Сжатие и растяжение |
Два или более контактов, которые сходятся или расходятся для увеличения или уменьшения элемента соответственно. Обычно используется для изменения размеров объекта, его увеличения или уменьшения или для контекстного масштабирования.
| |
Вращение |
Вращение нескольких пальцев на экране приводит к повороту объекта. Чтобы повернуть весь экран, поверните само устройство. Два или более контактов, которые перемещаются по кругу вокруг центра (или точки) поворота. Обычно используется для поворота объекта.
| |
Подробнее об этих жестах и их отношении к языку касаний Windows 8 см. в разделе Взаимодействие с помощью сенсорного ввода. |
Важно Если вы реализуете собственную поддержку взаимодействий, помните: пользователи ожидают, что способ взаимодействия с элементами вашего приложения будет интуитивно понятным. Рекомендуется моделирование взаимодействий с пользователем на базе библиотек элементов управления платформы (HTML и XAML) для единообразия элементов и возможности их обнаруживать. Элементы управления в этих библиотеках предоставляют все механизмы взаимодействия с пользователем, в том числе стандартные взаимодействия, анимированные физические эффекты, визуальную обратную связь и специальные возможности. Создавайте пользовательские взаимодействия, только если они действительно необходимы и если ни один стандартный механизм взаимодействия не подходит для вашего сценария.
Создание пользовательского интерфейса
В следующем примере демонстрируется добавление в базовый элемент пользовательского интерфейса отдельного жеста — вращения для поворота. Квадрат (target
) действует как целевой объект для ввода и определения указателя. Эти данные указателя передаются объекту GestureRecognizer, который обрабатывает данные жеста вращения, чтобы создать вращающуюся операцию со стандартным инерционным поведением.
Приложение предоставляет следующие функциональные возможности взаимодействия с пользователем.
- Вращение: поворачивается объект, причем поворот не прекращается после прекращения контакта с указателем. Подобное поведение взаимодействия соответствует Рекомендациям по визуальной обратной связи и рекомендациям языка касаний Windows. Согласно этим рекомендациям жест поворота должен быть ограничен областью поворота элементов пользовательского интерфейса. Примечание Этот пример легко изменить для разработки поддержки перетаскивания и масштабирования. Далее мы рассмотрим это в данном кратком руководстве.
HTML-код для этого примера.
<html>
<head>
<meta charset="utf-8" />
<title>Manipulation Gestures</title>
<!-- WinJS references -->
<link rel="stylesheet" href="//Microsoft.WinJS.2.0/css/ui-light.css" />
<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
<script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
<!-- BasicGesture references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/InputProcessor.js"></script>
<script src="/js/ManipulationManager.js"></script>
<script src="/js/default.js"></script>
</head>
<body>
<div class="Container" id="Container">
<div id="targetTitle">Manipulation gestures (rotation)</div>
<div class="TargetContainer" id="targetContainer">
<div id="target" draggable="false"></div>
</div>
<div id="targetFooter"> </div>
</div>
</body>
</html>
Код каскадных таблиц стилей (CSS) для этого примера.
Примечание События указателя не генерируются в процессе взаимодействий сдвига или масштабирования. Сдвиг и масштабирование для области можно отключить при помощи таких свойств CSS, как msTouchAction, overflow и -ms-content-zooming.
html,body {
overflow: hidden;
position: relative;
height: 100%;
}
div #Container {
/*
This element permits no default touch behaviors.
A manipulation-blocking element is defined as an element that explicitly
blocks direct manipulation via declarative markup, and instead fires gesture
events such as MSGestureStart, MSGestureChange, and MSGestureEnd.
*/
touch-action: none;
display: -ms-grid;
-ms-grid-rows: 200px 1fr 50px;
-ms-grid-columns: 1fr;
overflow: hidden;
position: absolute;
padding: 0px;
margin: 0px;
border-width: 0px;
border-collapse: collapse;
}
div #targetTitle {
touch-action: none;
-ms-grid-row: 1;
-ms-grid-column: 1;
background-color: black;
color: white;
padding: 0px;
margin: 0px;
border-width: 0px;
border-collapse: collapse;
font-family: 'Segoe UI';
font-size: large;
}
div #targetContainer {
touch-action: none;
-ms-grid-row: 2;
-ms-grid-column: 1;
background-color: white;
padding: 0px;
margin: 0px;
border-width: 0px;
border-collapse: collapse;
}
div #targetFooter {
touch-action: none;
-ms-grid-row: 3;
-ms-grid-column: 1;
background-color: black;
color: white;
padding: 0px;
margin: 0px;
border-width: 0px;
border-collapse: collapse;
font-family: 'Segoe UI';
font-size: large;
}
div #target {
-ms-transform-origin: 0px 0px;
position: absolute;
width: 300px;
height: 300px;
background-color: black;
padding: 0px;
margin: 0px;
border-width: 0px;
border-collapse: collapse;
}
Инициализация приложения
Задайте целевой объект, его контейнер и обработку операций для целевого объекта при запуске приложения.
Здесь мы инициализируем целевой элемент (и другие объекты пользовательского интерфейса) в контейнере и настроим обработчик для операций.
/// <summary>
/// Initializes the target and manipulation handling.
/// </summary>
function initialize() {
var container = document.getElementById("targetContainer");
var target = document.getElementById("target");
var title = document.getElementById("targetTitle");
var footer = document.getElementById("targetFooter");
// Set the height of the target container for initial positioning of the target.
var containerHeight = window.innerHeight - title.clientHeight - footer.clientHeight;
container.style.height = containerHeight + "px";
// Set the initial position of the target.
target.style.msTransform = (new MSCSSMatrix()).
translate((container.clientWidth - parseInt(target.clientWidth)) / 2.0,
(containerHeight - parseInt(target.clientHeight)) / 2.0);
// Configure manipulation handling.
var manipulable = new Manipulator.ManipulationManager();
// The configuration function can support all manipulations.
// For this example, we limit manipulation support to rotation with inertia.
manipulable.configure(false,
true, // Rotation.
false,
true, // Inertia.
1,
0,
{
x: (container.clientWidth - parseInt(target.clientWidth)) / 2.0,
y: (containerHeight - parseInt(target.clientHeight)) / 2.0
});
manipulable.setElement(target);
manipulable.setParent(container);
// Handler for transforms related to the manipulation.
manipulable.registerMoveHandler({
x: (container.clientWidth / 2.0),
y: (containerHeight / 2.0)
}, Manipulator.ManipulationManager.FixPivot.MoveHandler);
}
Обработка ввода от указателя и настройка распознавателя жестов
Для этого примера мы используем базовый класс-оболочку (InputProcessor
) для определения обработчика событий указателя и объекта GestureRecognizer, который принимает ввод от указателя.
В большинстве случаев рекомендуется получать информацию об указателе через аргумент события обработчиков события указателя на выбранном языке платформы.
Если аргумент события не предоставляет данных указателя, необходимых для приложения, можно получить доступ к расширенным данным указателя через аргумент события с помощью методов getCurrentPoint и getIntermediatePoints или свойств currentPoint и intermediatePoints. Рекомендуется использовать методы getCurrentPoint и getIntermediatePoints, так как для них можно указать контекст указателя данных.
Совет В данном примере только один объект сопоставляется с распознавателем жестов. Если ваше приложение содержит большое количество объектов, которыми можно управлять (например, головоломка), рассмотрите возможность динамического создания распознавателя жестов только в моменты, когда на конечном объекте определяется ввод с помощью указателя. Распознаватель жестов может быть удален при завершении всех операций (см. пример жестов, который допускает создание экземпляров). Чтобы сократить временные затраты на создание и удаление распознавателей жестов, создайте небольшой пул распознавателей жестов при инициализации и динамически распределяйте их по мере необходимости.
Распознаватель жестов (_gestureRecognizer
) прослушивает и обрабатывает все события указателя и жестов.
/// <summary>
/// InputProcessor is a thin wrapper for pointer event handling and gesture detection.
/// Defines an InputProcessor class that takes all pointer event data and feeds it to
/// a GestureRecognizer for processing of the manipulation gestures
/// as configured in ManipulationManager.js.
/// </summary>
(function () {
"use strict";
WinJS.Namespace.define("Manipulator", {
InputProcessor: WinJS.Class.define(function () {
// Constructor.
this._gestureRecognizer = new Windows.UI.Input.GestureRecognizer();
this._downPoint = null;
this._lastState = null;
}, {
// Instance members.
element: {
/// <summary>
/// The manipulable element.
/// </summary>
get: function () {
if (!this._element) {
return null;
}
return this._element;
},
set: function (value) {
this._element = value;
this._setupElement();
}
},
parent: {
/// <summary>
/// The container that defines the coordinate space used
/// for transformations during manipulation of the target.
/// </summary>
get: function () {
if (!this._parent) {
return null;
}
return this._parent;
},
set: function (value) {
this._parent = value;
}
},
getRecognizer: function () {
/// <summary>
/// The gesture recognition object.
/// </summary>
return this._gestureRecognizer;
},
getDown: function () {
/// <summary>
/// The pointer data for the pointerdown event.
/// </summary>
return this._downPoint;
},
_setupElement: function () {
/// <summary>
/// Declare the event listeners for the pointer events on the target.
/// </summary>
var that = this;
this._element.addEventListener("pointerdown",
function (evt) { Manipulator.InputProcessor._handleDown(that, evt); },
false);
this._element.addEventListener("pointermove",
function (evt) { Manipulator.InputProcessor._handleMove(that, evt); },
false);
this._element.addEventListener("pointerup",
function (evt) { Manipulator.InputProcessor._handleUp(that, evt); },
false);
this._element.addEventListener("pointercancel",
function (evt) { Manipulator.InputProcessor._handleCancel(that, evt); },
false);
this._element.addEventListener("wheel",
function (evt) { Manipulator.InputProcessor._handleMouse(that, evt); },
false);
}
}, {
// Static members.
_handleDown: function (that, evt) {
/// <summary>
/// Handler for the pointerdown event.
/// </summary>
/// <param name="that" type="Object">
/// The InputProcessor object handling this event.
/// </param>
/// <param name="evt" type="Event">
/// The event object.
/// </param>
var pp = evt.getCurrentPoint(that._parent);
that._element.setPointerCapture(pp.pointerId);
that._gestureRecognizer.processDownEvent(pp);
// Prevent propagation of this event to additional event handlers.
evt.stopImmediatePropagation();
// Capture the pointer location for this event.
that._downPoint = { x: pp.position.x, y: pp.position.y };
},
_handleMove: function (that, evt) {
/// <summary>
/// Handler for the pointermove event.
/// </summary>
/// <param name="that" type="Object">
/// The InputProcessor object handling this event.
/// </param>
/// <param name="evt" type="Event">
/// The event object.
/// </param>
var pps = evt.getIntermediatePoints(that._parent);
that._gestureRecognizer.processMoveEvents(pps);
// Prevent propagation of this event to additional event handlers.
evt.stopImmediatePropagation();
},
_handleUp: function (that, evt) {
/// <summary>
/// Handler for the pointerup event.
/// </summary>
/// <param name="that" type="Object">
/// The InputProcessor object handling this event.
/// </param>
/// <param name="evt" type="Event">
/// The event object.
/// </param>
var pp = evt.getCurrentPoint(that._parent);
that._gestureRecognizer.processUpEvent(pp);
// Prevent propagation of this event to additional event handlers.
evt.stopImmediatePropagation();
},
_handleCancel: function (that, evt) {
/// <summary>
/// Handler for the pointercancel event.
/// </summary>
/// <param name="that" type="Object">
/// The InputProcessor object handling this event.
/// </param>
/// <param name="evt" type="Event">
/// The event object.
/// </param>
that._gestureRecognizer.completeGesture();
// Prevent propagation of this event to additional event handlers.
evt.stopImmediatePropagation();
},
_handleMouse: function (that, evt) {
/// <summary>
/// Handler for the mouse wheel event.
/// </summary>
/// <param name="that" type="Object">
/// The InputProcessor object handling this event.
/// </param>
/// <param name="evt" type="Event">
/// The event object.
/// </param>
var pp = evt.getCurrentPoint(that._parent);
that._gestureRecognizer.processMouseWheelEvent(pp, evt.shiftKey, evt.ctrlKey);
// Prevent propagation of this event to additional event handlers.
evt.stopImmediatePropagation();
evt.preventDefault();
}
})
});
})();
Обработка манипуляции
Здесь мы используем класс диспетчера манипуляций (ManipulationManager
) для определения поведения манипуляции и ограничений для объекта GestureRecognizer. Этот объект был определен в InputProcessor
(_inputProcessor
), описанном на предыдущем этапе.
/// <summary>
/// ManipulationManager is the manipulation processing engine for the
/// GestureRecognizer object defined in InputProcessor.js.
/// Different components and behaviors of manipulation (rotate, translate, zoom,
/// and inertia) can be enabled, disabled, and customized as required.
/// </summary>
(function () {
"use strict";
WinJS.Namespace.define("Manipulator", {
ManipulationManager: WinJS.Class.define(function () {
// Constructor.
// Create an input processor.
this._inputProcessor = new Manipulator.InputProcessor();
// Initialize the manipulation movement and end handlers.
this._endHandler = null;
this._moveHandler = null;
// Create the transform matrices used for manipulating
// and resetting the target.
this._currentTransform = new MSCSSMatrix();
this._initialTransform = new MSCSSMatrix();
// Initialize the transform matrices values.
this._initialTransformParams = {
translation: { x: 0, y: 0 },
rotation: 0,
scale: 1
};
this._currentTransformParams = {
translation: { x: 0, y: 0 },
rotation: 0,
scale: 1
};
}, {
// Instance members.
configure: function (scale, rotate, translate, inertia,
initialScale, initialRotate, initialTranslate) {
/// <summary>
/// Define the behaviors of the ManipulationManager object.
/// </summary>
/// <param name="scale" type="Boolean">
/// True if scaling is enabled.
/// </param>
/// <param name="rotate" type="Boolean">
/// True if rotation is enabled.
/// </param>
/// <param name="translate" type="Boolean">
/// True if translation is enabled.
/// </param>
/// <param name="inertia" type="Boolean">
/// True if inertia is enabled.
/// </param>
/// <param name="initialScale" type="Number">
/// The initial scale factor.
/// </param>
/// <param name="initialRotate" type="Number">
/// The initial rotation value.
/// </param>
/// <param name="initialTranslate" type="Object">
/// The initial translation values (x,y).
/// </param>
// Get the GestureRecognizer associated with this manipulation manager.
var gr = this._inputProcessor.getRecognizer();
// Set the manipulations supported by the GestureRecognizer if the
// interaction is not already being processed.
if (!gr.isActive) {
var settings = 0;
if (scale) {
settings |= Windows.UI.Input.GestureSettings.manipulationScale;
if (inertia) {
settings |= Windows.UI.Input.GestureSettings.manipulationScaleInertia;
}
}
if (rotate) {
settings |= Windows.UI.Input.GestureSettings.manipulationRotate;
if (inertia) {
settings |= Windows.UI.Input.GestureSettings.manipulationRotateInertia;
}
}
if (translate) {
settings |= Windows.UI.Input.GestureSettings.manipulationTranslateX |
Windows.UI.Input.GestureSettings.manipulationTranslateY;
if (inertia) {
settings |= Windows.UI.Input.GestureSettings.manipulationTranslateInertia;
}
}
// Cache a reference to the current object.
var that = this;
// If any manipulation is supported, declare the manipulation event listeners.
if (scale || rotate || translate) {
gr.addEventListener('manipulationstarted',
function (evt) { Manipulator.ManipulationManager._manipulationStarted(that, evt); },
false);
gr.addEventListener('manipulationupdated',
function (evt) { Manipulator.ManipulationManager._manipulationUpdated(that, evt); },
false);
gr.addEventListener('manipulationended',
function (evt) { Manipulator.ManipulationManager._manipulationEnded(that, evt); },
false);
}
gr.gestureSettings = settings;
// Initialize the transform matrices.
this._currentTransformParams.scale = initialScale;
this._currentTransformParams.rotation = initialRotate;
this._currentTransformParams.translation = initialTranslate;
this._initialTransformParams.scale = initialScale;
this._initialTransformParams.rotation = initialRotate;
this._initialTransformParams.translation = initialTranslate;
// Set the transformation values.
if (initialRotate) {
this._initialTransform = this._initialTransform.rotate(initialRotate);
}
else {
this._currentTransformParams.rotation = 0;
this._initialTransformParams.rotation = 0;
}
if (initialTranslate) {
this._initialTransform = this._initialTransform.translate(initialTranslate.x, initialTranslate.y);
}
else {
this._currentTransformParams.translation = { x: 0, y: 0 };
this._initialTransformParams.translation = { x: 0, y: 0 };
}
if (initialScale) {
this._initialTransform = this._initialTransform.scale(initialScale);
}
else {
this._currentTransformParams.scale = 1;
this._initialTransformParams.scale = 1;
}
this._currentTransform = this._initialTransform;
}
},
setElement: function (elm) {
/// <summary>
/// Set the manipulable object.
/// </summary>
/// <param name="elm" type="Object">
/// The object that supports manipulation.
/// </param>
this._inputProcessor.element = elm;
// Set the transform origin for rotation and scale manipulations.
this._inputProcessor.element.style.msTransformOrigin = "0 0";
},
setParent: function (elm) {
/// <summary>
/// Set the parent of the manipulable object.
/// </summary>
/// <param name="elm" type="Object">
/// The parent of the object that supports manipulation.
/// </param>
this._inputProcessor.parent = elm;
},
registerEndHandler: function (handler) {
/// <summary>
/// Register handler to be called after the manipulation is complete.
/// </summary>
/// <param name="handler" type="Function">
/// The manipulationended event handler.
/// </param>
this._endHandler = handler;
},
registerMoveHandler: function (arg, handler) {
/// <summary>
/// Register handler to be called when manipulation is under way.
/// </summary>
/// <param name="args">
/// Arguments passed to the move handler function.
/// </param>
/// <param name="handler" type="Function">
/// The manipulationupdated event handler.
/// </param>
this._moveHandlerArg = arg;
this._moveHandler = handler;
},
resetAllTransforms: function () {
/// <summary>
/// Reset the ManipulationManager object to its initial state.
/// </summary>
// Check that the element has been registered before before attempting to reset.
if (this._inputProcessor.element) {
// Reapply the initial transform
this._inputProcessor.element.style.transform = this._initialTransform.toString();
this._currentTransform = this._initialTransform;
// Reset the current transform parameters to their initial values.
this._currentTransformParams.translation = this._initialTransformParams.translation;
this._currentTransformParams.rotation = this._initialTransformParams.rotation;
this._currentTransformParams.scale = this._initialTransformParams.scale;
}
},
_applyMotion: function (pivot, translation, rotation, scaling) {
/// <summary>
/// Apply the manipulation transform to the target.
/// </summary>
/// <param name="pivot" type="Object">
/// The X,Y values for the rotation and scaling pivot point.
/// </param>
/// <param name="translation" type="Object">
/// The X,Y values for the translation delta.
/// </param>
/// <param name="rotation" type="Number">
/// The angle of rotation.
/// </param>
/// <param name="scaling" type="Number">
/// The scaling factor.
/// </param>
// Create the transform, apply parameters, and multiply by the current transform matrix.
var transform = new MSCSSMatrix().translate(pivot.x, pivot.y).
translate(translation.x, translation.y).
rotate(rotation).
scale(scaling).
translate(-pivot.x, -pivot.y).multiply(this._currentTransform);
this._inputProcessor.element.style.transform = transform.toString();
this._currentTransform = transform;
},
_updateTransformParams: function (delta) {
/// <summary>
/// Update the current transformation parameters based on the new delta.
/// </summary>
/// <param name="that" type="Object">
/// The change in rotation, scaling, and translation.
/// </param>
this._currentTransformParams.translation.x = this._currentTransformParams.translation.x + delta.translation.x;
this._currentTransformParams.translation.y = this._currentTransformParams.translation.y + delta.translation.y;
this._currentTransformParams.rotation = this._currentTransformParams.rotation + delta.rotation;
this._currentTransformParams.scale = this._currentTransformParams.scale * delta.scale;
}
}, {
// Static members.
_manipulationStarted: function (that, evt) {
/// <summary>
/// The manipulationstarted event handler.
/// </summary>
/// <param name="that" type="Object">
/// ManipulationManager object on which the event was performed.
/// </param>
/// <param name="evt" type="Event">
/// The event data.
/// </param>
Manipulator.ManipulationManager._manipulationHelper(that, evt);
},
_manipulationUpdated: function (that, evt) {
/// <summary>
/// The manipulationupdated event handler.
/// </summary>
/// <param name="that" type="Object">
/// ManipulationManager object on which the event was performed.
/// </param>
/// <param name="evt" type="Event">
/// The event data.
/// </param>
Manipulator.ManipulationManager._manipulationHelper(that, evt);
},
_manipulationEnded: function (that, evt) {
/// <summary>
/// The manipulationended event handler.
/// </summary>
/// <param name="that" type="Object">
/// ManipulationManager object on which the event was performed.
/// </param>
/// <param name="evt" type="Event">
/// The event data.
/// </param>
// Pass the event to the manipulation helper function.
Manipulator.ManipulationManager._manipulationHelper(that, evt);
// Call the manipulationended handler, if registered.
if (that._endHandler) {
that._endHandler();
}
},
_manipulationHelper: function (that, evt) {
/// <summary>
/// Helper function for calculating and applying the transformation parameter deltas.
/// </summary>
/// <param name="that" type="Object">
/// ManipulationManager object on which the event was performed.
/// </param>
/// <param name="evt" type="Event">
/// The event data.
/// </param>
if (evt.delta) {
// Rotation/scaling pivot point.
var pivot = { x: evt.position.x, y: evt.position.y };
// Translation values.
var translation = { x: evt.delta.translation.x, y: evt.delta.translation.y };
// Rotation angle.
var rotation = evt.delta.rotation;
// Scale factor.
var scale = evt.delta.scale;
// Group the transformation parameter deltas.
var delta = {
pivot: pivot,
translation: translation,
rotation: rotation,
scale: scale
};
// Apply the manipulation movement constraints.
if (that._moveHandler) {
delta = that._moveHandler(that._moveHandlerArg, delta, that._currentTransformParams, that._currentTransform);
}
// Update the transformation parameters with fresh deltas.
that._updateTransformParams(delta);
// Apply the transformation.
that._applyMotion(delta.pivot, delta.translation, delta.rotation, delta.scale);
}
},
FixPivot: WinJS.Class.define(function () {
/// <summary>
/// Constrain the center of manipulation (or pivot point) to a set of X,Y coordinates,
/// instead of the centroid of the pointers associated with the manipulation.
/// <param name="pivot" type="Object">
/// The pivot coordinates for the ManipulationManager object.
/// </param>
/// <param name="delta" type="Object">
/// The transformation parameter deltas (pivot, delta, rotation, scale).
/// </param>
/// </summary>
}, {
}, {
MoveHandler: function (pivot, delta) {
delta.pivot = pivot;
return delta;
}
}),
})
});
})();
См. ссылки на более сложные примеры в разделе "Связанные темы" в нижней части страницы.
Полный пример
См. раздел Полный код для жестов управления.
Краткая сводка и дальнейшие действия
Из данного краткого руководства вы узнали об обработке событий жестов манипуляций в приложениях Магазина Windows на JavaScript.
Жесты управления удобны для поддержки сложных взаимодействий, например скольжения для сдвига или перестановки/перемещения и поворота, и управления ими.
Более сложные примеры обработки жестов см. в разделе Ввод: образец пользовательских жестов.
Примечание Этот пример не соответствует рекомендациям языка касаний Windows в отношении пользовательского взаимодействия. Некоторые статические жесты переопределены в учебных целях.
Об управлении статическими взаимодействиями (такими как скольжение, прокрутка, вращение, сжатие и растяжение) см. в разделе Краткое руководство: статические жесты.
Подробнее о языке касания Windows 8 см. в разделе Взаимодействие с помощью сенсорного ввода.
Связанные разделы
Разработчикам
Реакция на взаимодействие с пользователем
Разработка приложений Магазина Windows (JavaScript и HTML)
Краткое руководство: указатели
Краткое руководство: жесты и манипуляции модели DOM
Краткое руководство: статические жесты
Проектировщикам