Schnellstart: Manipulationsgesten (HTML)

[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation]

Sie können die Benutzerumgebung für die in der Windows-Sprache für Fingereingaben beschriebenen Manipulationsgesten anpassen (z. B. Ziehen, Streifen, Drehen, Zusammendrücken und Aufziehen). Dazu behandeln Sie Windows-Runtime-Gestenereignisse in Ihrer App mit JavaScript.

Die meisten Apps verarbeiten zwar Gesten (Drehen, Zoomen und Ziehen), die Rohzeigerdaten werden jedoch nicht genutzt, sondern nur zur Gestikerkennung weitergeleitet. In dem folgenden Beispiel werden Rohzeigerdaten verwendet, um die Behandlung und Verarbeitung von Manipulationsgesten zu unterstützen. So wird das Interaktionsmodell Ihrer App erweitert. Das Beispiel baut auf den grundlegenden Zeigerereignissen auf, die in Schnellstart: Zeiger beschrieben werden.

Updates für Windows 8.1: In Windows 8.1 wird eine Reihe von Updates und Verbesserungen für die Zeigereingabe-APIs eingeführt. Weitere Informationen dazu finden Sie unter API-Änderungen für Windows 8.1.

Wenn Sie noch keine Erfahrungen mit der Entwicklung von Apps mit JavaScript haben,: lesen Sie die Informationen in diesen Themen, um sich mit den hier erläuterten Technologien vertraut zu machen.

Erstellen Ihrer ersten App mit JavaScript

Roadmap für Apps mit JavaScript

Informieren Sie sich über Ereignisse unter Schnellstart: Hinzufügen von HTML-Steuerelementen und Behandeln von Ereignissen

App-Features von A bis Z:

In unserer Reihe App-Features von A bis Z können Sie sich genauer über diese Funktion informieren.

Benutzerinteraktion von A bis Z (HTML)

Anpassung der Benutzerinteraktion von A bis Z (HTML)

Richtlinien für die Benutzeroberfläche:

Die Plattform-Steuerelementbibliotheken (HTML und XAML) bieten umfassende Funktionalität für Benutzerinteraktionen, u. a. für Standardinteraktionen, animierte Bewegungseffekte und visuelles Feedback. Wenn Sie keine Unterstützung für angepasste Interaktionen benötigen, sollten Sie diese integrierten Steuerelemente verwenden.

Falls die Funktionalität der Plattformsteuerelemente nicht ausreicht, können Ihnen die folgenden Richtlinien für Benutzerinteraktionen dabei helfen, eine ansprechende, immersive und für alle Eingabemodi einheitliche Interaktionsumgebung bereitzustellen. Diese Richtlinien betreffen in erster Linie Fingereingaben, sie sind jedoch auch für Touchpad-, Maus-, Tastatur- und Stifteingaben relevant.

Beispiele: Sehen Sie sich unter Beispiele für Apps diese Funktionalität in Aktion an.

Anpassung der Benutzerinteraktion von A bis Z

Eingabe: Beispiel für die Behandlung von DOM-Zeigerereignissen

Eingabe: Beispiel für Manipulationen und Gesten (JavaScript)

Ziel: Hier erfahren Sie mehr über das Lauschen auf Manipulationsgesten über Eingaben durch Berührung, Maus, Zeichen-/Eingabestift und Windows-Runtime-Gestenereignisse sowie über deren Behandlung und Verarbeitung.

Voraussetzungen

schlagen Sie unter Schnellstart: Zeiger, Schnellstart: DOM-Gesten und -Manipulationen und Schnellstart: Statische Gesten nach.

In diesem Thema wird vorausgesetzt, dass Sie eine einfache App mit JavaScript erstellen können, die auf der Vorlage „Windows-Bibliothek für JavaScript“ basiert.

Für dieses Lernprogramm ist Folgendes erforderlich:

Was sind Gestikereignisse?

Eine Geste ist eine physische Bewegung, die mit dem Eingabegerät ausgeführt wird. Dazu gehört Folgendes: ein oder mehrere Finger auf einem Touchscreen, Zeichen-/Eingabestiftdigitalisierer, Maus usw. Diese natürlichen Interaktionen werden Vorgängen in Elementen sowohl im System als auch in Ihrer App zugewiesen. Weitere Informationen finden Sie unter Gesten, Manipulationen und Interaktionen.

In der folgenden Tabelle sind die in dieser Schnellstartanleitung behandelten Manipulationsgesten aufgeführt. Informationen zur Unterstützung statischer Gesten wie Tippen und Gedrückthalten finden Sie unter Schnellstart: Statische Gesten.

GesteBeschreibung
ZiehenZiehbewegung

Mindestens ein Kontakt, der über einen Distanzschwellenwert hinaus verschoben wird.

Wenn das Verschieben deaktiviert ist und der erste Kontakt im Bereich eines Elements liegt, wird durch Ziehen das Element bewegt.

Wenn das Verschieben aktiviert ist, der erste Kontakt im Bereich eines Elements liegt und die Ziehbewegung im rechten Winkel zur Achse für die Verschiebung ausgeführt wird, wird durch Ziehen das Element bewegt. Andernfalls wird das Verschieben initiiert.

  • Anfangszustand: Mindestens ein Kontakte festgestellt.
  • Bewegung: Das Verschieben/Ziehen überschreitet den Distanzschwellenwert.
  • Beendigungszustand: Letzter Kontakt aufgehoben bzw. beendet.
StreifenStreifbewegung

Mindesten ein Kontakt, der innerhalb eines Distanzschwellenwerts bewegt wird (eine kurze Ziehbewegung). Eine Streifbewegung basiert nicht auf Geschwindigkeit oder Zeit.

Wenn die App das Verschieben nicht ermöglicht und der erste Kontakt im Bereich eines Elements liegt, wird das Element durch Streifen bewegt.

Wenn die App das Verschieben ermöglicht, der erste Kontakt im Bereich eines Elements liegt und die Streifbewegung im rechten Winkel zur Achse für die Verschiebung ausgeführt wird, wird durch Streifen das Element bewegt. Andernfalls wird durch Streifen das Verschieben initiiert.

  • Anfangszustand: Mindestens ein Kontakte festgestellt.
  • Bewegung: Das Verschieben/Ziehen überschreitet nicht den Distanzschwellenwert.
  • Beendigungszustand: Letzter Kontakt aufgehoben bzw. beendet.
Zusammendrücken und AufziehenZusammendrück- und Aufziehbewegung

Mindestens zwei Kontakte, die konvergieren bzw. divergieren, um die Ansicht zu vergrößern bzw. zu verkleinern.

Wird üblicherweise zur Größenänderung eines Objekts, zum Vergrößern oder Verkleinern einer Ansicht oder für den semantischen Zoom verwendet.

  • Anfangszustand: Mindestens zwei Kontakte innerhalb des umgebenden Rechtecks eines Objekts festgestellt.
  • Bewegung: Das Verschieben/Ziehen konvergierender oder divergierender Kontakte.
  • Beendigungszustand: Nur ein bzw. kein Kontakt festgestellt.
DrehenDrehbewegung

Durch das Drehen mit mindestens zwei Fingern wird ein Objekt gedreht. Drehen Sie das Gerät selbst, um den ganzen Bildschirm zu drehen.

Mindestens zwei Kontakte, die sich in kreisförmiger Bewegung um ein Rotationszentrum bzw. einen Rotationspunkt bewegen.

Wird üblicherweise zum Drehen eines Objekts verwendet.

  • Anfangszustand: Mindestens zwei Kontakte innerhalb des umgebenden Rechtecks eines Objekts festgestellt.
  • Bewegung: Verschieben/Ziehen von mindestens zwei Kontakten in einer Kreisbewegung
  • Beendigungszustand: Nur ein bzw. kein Kontakt festgestellt.

Weitere Informationen zu diesen Gesten und ihrer Beziehung zur Windows 8-Sprache für die Fingereingabe finden Sie unter Design für Interaktion per Fingereingabe.

 

Wichtig  Wenn Sie eine eigene Interaktionsunterstützung implementieren, sollten Sie daran denken, dass die Benutzer eine intuitive Umgebung erwarten, die die direkte Interaktion mit den UI-Elementen der App beinhaltet. Es empfiehlt sich, die benutzerdefinierten Interaktionen basierend auf den Plattform-Steuerelementbibliotheken (HTML und XAML) zu modellieren, um auf diese Weise für eine konsistente und intuitive Benutzerumgebung zu sorgen. Die Steuerelemente in diesen Bibliotheken bieten umfassende Funktionen für Benutzerinteraktionen wie Standardinteraktionen, animierte Bewegungseffekte, visuelles Feedback und Barrierefreiheit. Erstellen Sie benutzerdefinierte Interaktionen nur dann, wenn ein eindeutiger, klar umrissener Bedarf besteht und es keine Basisinteraktion gibt, die das gewünschte Szenario unterstützt.

 

Erstellen der Benutzeroberfläche

Dieses Beispiel zeigt, wie eine einzelne Manipulationsgeste (Drehen zu Rotieren) für ein einfaches UI-Element aktiviert wird. Ein Quadrat (target) dient als Zielobjekt für Zeigereingaben und Erkennung. Diese Zeigerdaten werden an ein GestureRecognizer-Objekt übergeben, das die Daten einer Drehbewegung verarbeitet, um eine Rotation mit dem normalen Trägheitsverhalten zu erstellen.

Die App bietet die folgenden Funktionen für Benutzerinteraktionen:

  • Drehen: Dreht das Objekt; mit Trägheit, wenn die Zeigerkontakte beendet sind. Dieses Interaktionsverhalten richtet sich nach den Richtlinien für visuelles Feedback und den Empfehlungen der Windows-Sprache für die Fingereingabe. Diese Empfehlungen besagen, dass Drehbewegungen auf die Rotation von UI-Elementen zu beschränken sind. Hinweis  Dieses Beispiel muss nur leicht abgeändert werden, um Ziehen und Zoomen zu unterstützen. Dieses Thema werden wird später in dieser Schnellstartanleitung behandeln.  

Im Folgenden ist der HTML-Code für dieses Beispiel aufgeführt.

<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">&nbsp;</div>
    </div>
</body>
</html>

Im Folgenden ist das Cascading Stylesheet (CSS) für dieses Beispiel aufgeführt.

Hinweis  Zeigerereignisse werden bei Verschiebungs- oder Zoominteraktionen nicht ausgelöst. Sie können Verschiebungen und Zoomaktionen für einen Bereich über die CSS-Eigenschaften msTouchAction, overflow und -ms-content-zooming deaktivieren.

 

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;
}

Initialisieren der App

Richten Sie das Ziel, den Zielcontainer und die Behandlung von Manipulationen für das Ziel beim Starten der App fest.

Hier initialisieren wir das Zielelement (und andere UI-Objekte) innerhalb des Containers und konfigurieren einen Handler für Manipulationen.

/// <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);
}

Behandeln von Zeigereingaben und Konfigurieren der Gestikerkennung

In diesem Beispiel verwenden wir eine einfache Wrapper-Klasse (InputProcessor), um die Zeigerereignishandler zusammen mit dem GestureRecognizer-Objekt zu definieren, das die Zeigereingaben verwendet.

Für die meisten Fälle wird empfohlen, Zeigerinformationen über das Ereignisargument der Zeigerereignishandler im ausgewählten Programmiersprachenframework abzurufen.

Sollte das Ereignisargument die für die App erforderlichen Zeigerdetails nicht liefern, können Sie über die Methoden getCurrentPoint und getIntermediatePoints oder die Eigenschaften currentPoint und intermediatePoints auf erweiterte Zeigerdaten des Ereignisarguments zugreifen. Wir empfehlen die Verwendung der Methoden getCurrentPoint und getIntermediatePoints, weil sie die Möglichkeit bieten, den Kontext der Zeigerdaten anzugeben.

Tipp  In diesem Beispiel ist einer Gestikerkennung nur ein Objekt zugeordnet. Falls Ihre App viele Objekte enthält, die manipuliert werden können (z. B. ein Puzzle), erwägen Sie die dynamische Erstellung einer Gestikerkennung nur, wenn die Zeigereingabe für ein Zielobjekt ermittelt wird. Die Gestikerkennung kann zerstört werden, wenn die Manipulation abgeschlossen ist. (Ein Beispiel hierfür finden Sie unter Eingabe: Beispiel für instanziierbare Gesten.) Um den Aufwand für das Erstellen und Zerstören von Gestikerkennungen zu vermeiden, erstellen Sie bei der Initialisierung einen kleinen Pool mit Gestikerkennungen, und weisen Sie sie nach Bedarf dynamisch zu.

 

Hier lauscht die Gestikerkennung (_gestureRecognizer) auf Zeiger- und Gestikereignisse und verarbeitet diese.

/// <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();
            }
        })
    });
})();

Verarbeiten der Manipulation

Wir verwenden hier eine Manipulationsverwaltungsklasse (ManipulationManager), um das Manipulationsverhalten und Beschränkungen für das GestureRecognizer-Objekt zu definieren. Dieses Objekt wurde im InputProcessor (_inputProcessor) definiert, der im vorherigen Schritt beschrieben wurde.

/// <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;
                }
            }),
        })
    });
})();

Links zu komplexeren Beispielen finden Sie weiter unten unter "Verwandte Themen".

Vollständiges Beispiel

Informationen hierzu finden Sie unter Manipulationsgesten (vollständiger Code).

Zusammenfassung und nächste Schritte

In dieser Schnellstartanleitung haben Sie gelernt, wie Manipulationsgestikereignisse in Windows Store-Apps mit JavaScript behandelt werden.

Manipulationsgesten sind hilfreich, um komplexe Interaktionen (z. B. Ziehen zum Verschieben oder Neuanordnen/Verschieben, Zoomen und Drehen) zu unterstützen und zu verwalten.

Ein komplexeres Beispiel für die Behandlung von Gesten finden Sie unter Eingabe: Beispiel für instanziierbare Gesten.

Hinweis  Dieses Beispiel entspricht nicht den Richtlinien der Windows-Sprache für die Fingereingabe bei benutzerdefinierten Interaktionen. Einige statische Gesten wurden zu Vorführungszwecken neu definiert.

 

Informationen zum Verwalten statischer Interaktionen (z. B. Ziehen, Streifen, Drehen, Zusammendrücken und Aufziehen) finden Sie unter Schnellstart: Statische Gesten.

Weitere Informationen zur Windows 8-Sprache für die Fingereingabe finden Sie unter Design für Interaktion per Fingereingabe.

Verwandte Themen

Entwickler

Reaktion auf Benutzerinteraktionen

Entwickeln von Windows Store-Apps (JavaScript und HTML)

Schnellstart: Zeiger

Schnellstart: DOM-Gesten und -Manipulationen

Schnellstart: Statische Gesten

Designer

Entwicklung von Fingereingabeinteraktionen