Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This topic provides the complete code sample used in Quickstart: Manipulation gestures.
This topic contains these sections:
- Technologies
- Requirements
- View the code ()
Download ___location
This sample is not available for download.
Technologies
Programming languages | C++ |
Programming models | Windows Runtime |
Requirements
Minimum supported client | Windows 8 |
Minimum supported server | Windows Server 2012 |
Minimum required SDK | Microsoft Visual Studio Express 2012 for Windows 8 |
View the code ()
default.css
body {
/*
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.
*/
overflow: hidden;
position: absolute;
font-family: 'Segoe UI';
font-size: small;
touch-action: none;
background-color: black;
}
div #targetContainer {
position: relative;
height: fill-available;
width: fill-available;
}
div #inputBox {
position: relative;
width: 640px;
height: 640px;
color: black;
overflow: hidden;
background-color: darkgrey;
margin: 0px;
padding: 0px;
border-width: 1px;
border-color: white;
border-style: solid;
}
div #instructions {
position: relative;
width: 100%;
height: fit-content;
color: black;
background-color: white;
visibility: visible;
}
div #questions {
position: relative;
width: 100%;
height: fit-content;
color: white;
background-color: black;
visibility: visible;
}
div #answers {
position: relative;
width: 100%;
height: fit-content;
color: white;
background-color: black;
visibility: visible;
}
div #clues {
position: relative;
width: 100%;
height: 100%;
background-color: DimGray;
}
div #timerBox {
background-color: red;
color: black;
position: absolute;
width: 100%;
bottom: 0px;
height: 20px;
text-align: center;
}
div #answerFloater {
position: absolute;
visibility: hidden;
top: 0px;
left: 0px;
background-color: blue;
}
div #eventLog {
font-size: xx-small;
position: absolute;
left: 0px;
top: 0px;
width: 640px;
height: 50px;
overflow: auto;
overflow-style: auto;
}
default.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>
default.js
(function () {
"use strict";
/// <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);
}
document.addEventListener("DOMContentLoaded", initialize, false);
})();
InputProcessor.js
/// <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.js
/// <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;
}
}),
})
});
})();