Démarrage rapide : manipulations et mouvements DOM (HTML)

[ Cet article est destiné aux développeurs de Windows 8.x et Windows Phone 8.x qui créent des applications Windows Runtime. Si vous développez une application pour Windows 10, voir la Documentation ]

Vous pouvez personnaliser l’expérience utilisateur relative à certains mouvements de base décrits dans le langage tactile de Windows (tels que le glissement, la rotation et le redimensionnement) via une gestion d’événements de mouvement DOM (Document Object Model) de base.

Mises à jour pour Windows 8.1: Dans Windows 8.1, les API d’entrée de pointeur ont fait l’objet de plusieurs mises à jour et améliorations. Pour plus d’informations, voir Modifications apportées aux API pour Windows 8.1.

Si vous débutez dans le développement d’applications en JavaScript: Examinez ces rubriques pour vous familiariser avec les technologies discutées ici.

Créer votre première application en JavaScript

Feuille de route pour les applications en JavaScript

Découvrir les événements avec Démarrage rapide : ajout de contrôles HTML et gestion des événements

Fonctionnalités d’application de A à Z:

Étudier cette fonctionnalité de façon plus approfondie dans le cadre de notre série Fonctionnalités d’application de A à Z

Interaction utilisateur de A à Z (HTML)

Personnalisation de l’interaction utilisateur de A à Z (HTML)

Recommandations en matière d’expérience utilisateur:

Les bibliothèques de contrôles de plateforme (HTML et XAML) fournissent une expérience d’interaction utilisateur complète, y compris les interactions standard, les effets physiques animés et le retour visuel. Utilisez ces contrôles intégrés si vous n’avez pas besoin d’une prise en charge d’interaction personnalisée.

Si les contrôles de plateforme ne suffisent pas, les présentes recommandations peuvent vous aider à fournir une expérience d’interaction utilisateur à la fois immersive et cohérente entre les divers modes d’entrée. Ces recommandations sont axées principalement sur l’entrée tactile, mais elles s’appliquent également à l’entrée de pavé tactile, de souris, de clavier et de stylet.

Exemples: Découvrez cette fonctionnalité en action dans nos exemples d’applications.

Exemple de personnalisation de l’interaction utilisateur de A à Z

Exemple de zoom, de panoramique et de défilement HTML

Entrée : exemple de gestion d’événement de pointeur DOM

Entrée : exemple de mouvements instanciables

Objectif: apprendre à écouter, gérer et traiter les mouvements de base pour la translation, la rotation et le redimensionnement à l’aide des entrées provenant d’interactions tactiles, avec la souris ou le stylo/stylet, ainsi que des événements de mouvement DOM.

Prérequis

Passez en revue Démarrage rapide : pointeurs.

Nous partons du principe que vous savez créer une application élémentaire en JavaScript qui utilise le modèle Bibliothèque Windows pour JavaScript.

Pour suivre ce didacticiel, vous devez :

Durée de réalisation: 30 minutes.

Qu’est-ce qu’un événement de mouvement ?

Un mouvement est l’acte physique ou le déplacement effectué sur ou par le périphérique d’entrée (un ou plusieurs doigts sur une surface tactile, un digitaliseur à stylo/stylet, une souris, etc.). Ces interactions naturelles sont mises en correspondance avec des éléments à la fois dans le système et dans votre application. Pour plus d’informations, voir Mouvements, manipulations et interactions.

Windows repose sur un ensemble de mouvements de base dans le cadre de l’interaction avec l’interface utilisateur et de la manipulation de cette dernière.

MouvementDescription
AppuyerAction d’appuyer

Un contact unique est détecté et relâché immédiatement.

Le fait d’appuyer sur un élément appelle l’action primaire associée.

Effectuer un appui prolongéAppui prolongé

Un contact unique persistant est détecté.

L’appui prolongé affiche des informations détaillées ou des éléments visuels didactiques (par exemple, une info-bulle ou un menu contextuel) ne requérant aucune action.

Faire glisserGlissement

Un ou plusieurs contacts sont détectés et se déplacent dans la même direction.

Le glissement est principalement utilisé pour les interactions de type panoramique mais peut également l’être pour le déplacement, le dessin ou l’écriture.

BalayerBalayage

Un ou plusieurs contacts sont détectés et se déplacent dans la même direction sur une courte distance.

Le balayage est utilisé pour sélectionner, commander et déplacer un élément.

TournerRotation

Au moins deux contacts sont détectés et pivotent en arc de cercle de haut en bas ou de bas en haut.

La rotation est utilisée pour faire pivoter un élément.

PincerPincement

Au moins deux contacts sont détectés et se rapprochent.

Le pincement est utilisé pour effectuer un zoom arrière.

ÉtirerÉtirement

Au moins deux contacts sont détectés et s’éloignent l’un de l’autre.

L’étirement est utilisé pour effectuer un zoom avant.

Pour plus d’informations sur ces mouvements et leur association au langage tactile de Windows, voir Conception de l’interaction tactile.

 

Vous pouvez utiliser la détection des mouvements pour étendre le modèle d’interaction de votre application et pour vous appuyer sur les événements de pointeur de base décrits dans la rubrique Démarrage rapide : gestion des entrées de pointeur. En fait, il est fort probable que votre application utilise des événements de mouvement (tels que la gestion des actions d’appui, des glissements de panoramique ou de déplacement et du zoom par pincement ou étirement) et des données de pointeur brutes pour prendre en charge la détection et le traitement des mouvements.

Votre application peut traiter plusieurs mouvements simultanément (par exemple, le zoom et la rotation), grouper les contacts de pointeur de façon à cibler un élément spécifique (par exemple, associer tous les contacts à la cible du contact initial ou principal) et identifier les éléments spécifiques ciblés par un mouvement ou un contact de pointeur précis.

Important  Si vous implémentez votre propre prise en charge d’interaction, gardez à l’esprit que les utilisateurs s’attendent à disposer d’une expérience intuitive impliquant une interaction directe avec les éléments d’interface utilisateur de votre application. Nous vous recommandons de modeler vos interactions personnalisées sur les bibliothèques de contrôles de plateforme (HTML et XAML) pour des raisons de cohérence et de simplicité de détection. Les contrôles de ces bibliothèques fournissent une expérience d’interaction utilisateur complète, notamment pour les interactions standard, les effets physiques animés, le retour visuel et l’accessibilité. Ne créez des interactions personnalisées que pour répondre à des exigences claires et bien définies, notamment en l’absence d’interactions de base prenant en charge votre scénario.

 

Création de l’interface utilisateur

Dans le cadre de cet exemple, nous utilisons un rectangle (target) comme objet cible de l’entrée du pointeur et de la détection et du traitement des mouvements.

Le rectangle agit comme un mélangeur de couleurs élémentaire. La couleur de la cible change en fonction de la sélection d’une couleur RVB (rouge, vert ou bleu) et de l’angle de rotation de la cible signalé par le mouvement de rotation. (La valeur rouge, vert ou bleu est calculée à partir de l’angle de rotation.)

Nous affichons les détails de chaque pointeur et événement de mouvement, ainsi que la matrice de transformation appliquée à la cible, au sein de l’objet cible.

Voici le code HTML correspondant à cet exemple.

<html>
<head>
    <meta charset="utf-8" />
    <title>PointerInput</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    <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/default.js"></script>
</head>
<body>
    <div class="TargetContainer" id="targetContainer">
        <div id="colorMixer">
            <input type="radio" name="color" value="R" title="Red" id="red" class="Red" /><label for="red" id="labelRed">Red</label>
            <input type="radio" name="color" value="G" title="Green" id="green" class="Green" /><label for="green" id="labelGreen">Green</label>
            <input type="radio" name="color" value="B" title="Blue" id="blue" class="Blue" /><label for="blue" id="labelBlue">Blue</label>
            <div id="targetLog"></div>
            <div id="eventLog"></div>
        </div>
    </div>
</body>
</html>

Voici le code CSS (feuilles de style en cascade) correspondant à cet exemple.

Remarque  Les événements de pointeur ne se déclenchent pas au cours d’une interaction de panoramique ou de zoom. Vous pouvez désactiver les mouvements de panoramique et de zoom au niveau d’une région via les propriétés CSS msTouchAction, overflow et -ms-content-zooming.

 

body {
    overflow: hidden;
    position: relative;
}

div #targetContainer {
/*
Set the width and height properties of the target container to fill the viewport. 
You can set these properties to 100%, but we use 100vw (viewport width) and 100vh (viewport height).
See https://go.microsoft.com/fwlink/?LinkID=301480 for more detail on CSS units supported by Internet Explorer.
*/
    height: 100vw;
    width: 100vh;
    overflow: hidden;
    position: absolute;
}

div #colorMixer {
/*
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;
    -ms-transform-origin: 0px 0px;
    position: absolute;
    background-color: black;
    border-color: white;
    border-width: thick;
    border-style: solid;
}

div #colorSelector {
    position: relative;
}

div #eventLog {
    -ms-overflow-style:scrollbar;
}

input.Red {
    background-color: rgb(255,0,0);
}

input.Green {
    background-color: rgb(0,255,0);
}

input.Blue {
    background-color: rgb(0,0,255);
}

Écoute des événements de pointeur et de mouvement

Le code ci-dessous comporte la définition du mélangeur de couleurs et des sélecteurs de couleurs, ainsi que la déclaration des divers détecteurs d’événements.

Dans la plupart des cas, nous vous conseillons d’obtenir les informations sur le pointeur via l’argument d’événement des gestionnaires d’événements de pointeur dans l’infrastructure de langage choisie.

Si l’argument d’événement n’expose pas les détails du pointeur nécessaires à votre application, vous pouvez obtenir l’accès aux données étendues du pointeur à partir de l’argument d’événement via les méthodes getCurrentPoint et getIntermediatePoints ou les propriétés currentPoint et intermediatePoints. Nous vous recommandons d’utiliser les méthodes getCurrentPoint et getIntermediatePoints car vous pouvez spécifier le contexte des données du pointeur.

Il commence par la déclaration des variables globales, la définition d’un objet de données (colorInfo) permettant de suivre l’état de la cible et l’initialisation à la fois du mélangeur de couleurs (target) et des sélecteurs de couleurs RVB.

var _width = 640;
var _height = 640;

var _pointerInfo;
var _targetLog;

var _selectedColor;
var _colorRed, _colorGreen, _colorBlue;

// Color-specific data object.
//   value: The color value (r, g, or b)
//   rotation: The rotation value used to calculate color value.
//   matrix: The transform matrix of the target.
function colorInfo(value, rotation, matrix) {
    this.value = value;
    this.rotation = rotation;
    this.matrix = matrix;
}

function initialize() {
    // Configure the target.
    setTarget();

    // Initialize color tracking.
    setColors();
}

Viennent ensuite la configuration du mélangeur de couleurs, l’association d’une reconnaissance de mouvement (msGesture) à l’objet et la déclaration des divers détecteurs d’événements.

Astuce  Pour cet exemple, un seul objet est associé à une reconnaissance de mouvement. Si votre application contient un grand nombre d’objets qui peuvent être manipulés (tels que des puzzles), envisagez de créer dynamiquement la reconnaissance de mouvement uniquement lorsque l’entrée du pointeur est détectée sur un objet cible. La reconnaissance de mouvement peut être détruite lorsque la manipulation est terminée (voir Entrée : exemple de mouvements instanciables). Pour éviter la surcharge de création et de destruction de reconnaissances de mouvement, créez un petit pool de reconnaissances de mouvement lors de l’initialisation et assignez-les dynamiquement au fil des besoins.

 

// Configure the interaction target.
function setTarget() {
    //  Set up the target position, size, and transform.
    colorMixer.style.width = _width + "px";
    colorMixer.style.height = _height + "px";
    colorMixer.style.msTransform = (new MSCSSMatrix()).
        translate((window.innerWidth - parseInt(colorMixer.style.width)) / 2.0,
        (window.innerHeight - parseInt(colorMixer.style.height)) / 2.0);

    // Create gesture recognizer.
    var msGesture = new MSGesture();
    msGesture.target = colorMixer;
    colorMixer.gesture = msGesture;
    // Expando property for handling multiple pointer devices.
    colorMixer.gesture.pointerType = null;

    // Expando property to track pointers.
    colorMixer.pointers = [];

    // Declare event handlers.
    colorMixer.addEventListener("pointerdown", onPointerDown, false);
    colorMixer.addEventListener("pointerup", onPointerUp, false);
    colorMixer.addEventListener("pointercancel", onPointerCancel, false);
    colorMixer.addEventListener("lostpointercapture", onLostPointerCapture, false);
    colorMixer.addEventListener("MSGestureChange", onMSGestureChange, false);
    colorMixer.addEventListener("MSGestureTap", onMSGestureTap, false);
    colorMixer.addEventListener("MSGestureEnd", onMSGestureEnd, false);
    colorMixer.addEventListener("MSGestureHold", onMSGestureHold, false);
}

Et, pour finir, l’initialisation des sélecteurs de couleurs RVB (avec les détecteurs d’événements) et de l’objet colorInfo.

// Initialize values and event listeners for color tracking.
function setColors() {
    var m = new MSCSSMatrix(colorMixer.style.msTransform);
    _colorRed = new colorInfo(0, 0, m);
    _colorGreen = new colorInfo(0, 0, m);
    _colorBlue = new colorInfo(0, 0, m);

    document.getElementById("red").addEventListener("click", onColorChange, false);
    document.getElementById("green").addEventListener("click", onColorChange, false);
    document.getElementById("blue").addEventListener("click", onColorChange, false);
}

// Re-draw target based on transform matrix associated with color selection.
function onColorChange(e) {
    switch (e.target.id) {
        case "red":
            colorMixer.style.msTransform = _colorRed.matrix;
            break;
        case "green":
            colorMixer.style.msTransform = _colorGreen.matrix;
            break;
        case "blue":
            colorMixer.style.msTransform = _colorBlue.matrix;
            break;
    }
    _selectedColor = e.target.id;

    eventLog.innerText = "Color change";
    targetLog.innerText = colorMixer.style.msTransform;
}

Gestion de l’événement de pointeur appuyé

Lors d’un événement de pointeur appuyé, nous obtenons la couleur RVB sélectionnée et associons le pointeur à la reconnaissance de mouvement en appelant la méthode addPointer. Nous effectuons le suivi de la séquence et de pointerType pour associer à nouveau le pointeur et la reconnaissance de mouvement, si nécessaire.

Si aucune couleur n’est sélectionnée, nous ignorons l’événement de pointeur.

// Pointer down handler: Attach the pointer to a gesture object.
function onPointerDown(e) {
    // Do not attach pointer if no color selected.
    if (_selectedColor === undefined)
        return;
    _selectedColor = getSelectedColor();

    // Process pointer.
    if (e.target === this) {
        this.style.borderStyle = "double";
        //  Attach first contact and track device.
        if (this.gesture.pointerType === null) {
            this.gesture.addPointer(e.pointerId);
            this.gesture.pointerType = e.pointerType;
        }
            // Attach subsequent contacts from same device.
        else if (e.pointerType === this.gesture.pointerType) {
            this.gesture.addPointer(e.pointerId);
        }
            // New gesture recognizer for new pointer type.
        else {
            var msGesture = new MSGesture();
            msGesture.target = e.target;
            e.target.gesture = msGesture;
            e.target.gesture.pointerType = e.pointerType;
            e.target.gesture.addPointer(e.pointerId);
        }
    }
    eventLog.innerText = "Pointer down";
}

// Get the current color.
function getSelectedColor() {
    var colorSelection = document.getElementsByName("color");
    for (var i = 0; i < colorSelection.length; i++) {
        if (colorSelection[i].checked)
            return colorSelection[i].id;
    }
}

Gestion de l’événement de mouvement

Ce code traite les mouvements de translation (glissement et balayage), rotation et mise à l’échelle (pincement ou étirement).

// Gesture change handler: Process gestures for translation, rotation, and scaling.
// For this example, we don't track pointer movements.
function onMSGestureChange(e) {
    // Get the target associated with the gesture event.
    var elt = e.gestureObject.target;
    // Get the matrix transform for the target.
    var matrix = new MSCSSMatrix(elt.style.msTransform);

    // Process gestures for translation, rotation, and scaling.
    e.target.style.msTransform = matrix.
        translate(e.offsetX, e.offsetY).
        translate(e.translationX, e.translationY).
        rotate(e.rotation * 180 / Math.PI).
        scale(e.scale).
        translate(-e.offsetX, -e.offsetY);

    // Mix the colors based on rotation value.
    switch (_selectedColor) {
        case "red":
            _colorRed.rotation += ((e.rotation * 180 / Math.PI));
            _colorRed.rotation = _colorRed.rotation % 360;
            targetLog.innerText = _colorRed.rotation.toString();
            if (_colorRed.rotation >= 0)
                _colorRed.value = parseInt(Math.abs(_colorRed.rotation) * (256 / 360));
            else
                _colorRed.value = parseInt((360 - Math.abs(_colorRed.rotation)) * (256 / 360));
            document.getElementById("labelRed").innerText = _colorRed.value.toString();
            _colorRed.matrix = matrix;
            break;
        case "green":
            _colorGreen.rotation += ((e.rotation * 180 / Math.PI));
            _colorGreen.rotation = _colorGreen.rotation % 360;
            targetLog.innerText = _colorGreen.rotation.toString();
            if (_colorGreen.rotation >= 0)
                _colorGreen.value = parseInt(Math.abs(_colorGreen.rotation) * (256 / 360));
            else
                _colorGreen.value = parseInt((360 - Math.abs(_colorGreen.rotation)) * (256 / 360));
            document.getElementById("labelGreen").innerText = _colorGreen.value.toString();
            _colorGreen.matrix = matrix;
            break;
        case "blue":
            _colorBlue.rotation += ((e.rotation * 180 / Math.PI));
            _colorBlue.rotation = _colorBlue.rotation % 360;
            if (_colorBlue.rotation >= 0)
                _colorBlue.value = parseInt(Math.abs(_colorBlue.rotation) * (256 / 360));
            else
                _colorBlue.value = parseInt((360 - Math.abs(_colorBlue.rotation)) * (256 / 360));
            document.getElementById("labelBlue").innerText = _colorBlue.value.toString();
            _colorBlue.matrix = matrix;
            break;
    }
    e.target.style.backgroundColor = "rgb(" + _colorRed.value + ", " + _colorGreen.value + ", " + _colorBlue.value + ")";
    targetLog.innerText = e.target.style.msTransform;
    eventLog.innerText = "Gesture change";
}

Gestion des autres événements (le cas échéant)

Dans cet exemple, nous rapportons simplement les autres événements gérés ici. Une application plus robuste fournirait des fonctionnalités supplémentaires.

// Tap gesture handler: Display event.
// The touch language described in Touch interaction design (https://go.microsoft.com/fwlink/?LinkID=268162),
// specifies that the tap gesture should invoke an elements primary action (such as launching an application 
// or executing a command). 
// The primary action in this sample (color mixing) is performed through the rotation gesture.
function onMSGestureTap(e) {
    eventLog.innerText = "Gesture tap";
}

// Gesture end handler: Display event.
function onMSGestureEnd(e) {
    if (e.target === this) {
        this.style.borderStyle = "solid";
    }
    eventLog.innerText = "Gesture end";
}

// Hold gesture handler: Display event.
function onMSGestureHold(e) {
    eventLog.innerText = "Gesture hold";
}

// Pointer up handler: Display event.
function onPointerUp(e) {
    eventLog.innerText = "Pointer up";
}

// Pointer cancel handler: Display event.
function onPointerCancel(e) {
    eventLog.innerText = "Pointer canceled";
}

// Pointer capture lost handler: Display event.
function onLostPointerCapture(e) {
    eventLog.innerText = "Pointer capture lost";
}

Des liens vers des exemples plus complexes sont proposés à la section Rubriques associées, en bas de cette page.

Exemple complet

Voir Code complet des manipulations et mouvements DOM.

Récapitulatif et étapes suivantes

Cette rubrique de démarrage rapide vous a appris à gérer les événements de mouvement de base dans les applications du Windows Store en JavaScript.

La reconnaissance des mouvements de base, associée aux événements de pointeur, est utile dans le cadre de la gestion des interactions simples, telles qu’une translation (glissement ou balayage), une rotation ou un redimensionnement (pincement ou étirement).

Pour gérer des interactions plus élaborées et fournir une expérience d’interaction utilisateur entièrement personnalisée, voir Démarrage rapide : actions statiques et Démarrage rapide : actions de manipulation.

Pour plus d’informations sur le langage tactile de Windows 8, voir Conception de l’interaction tactile.

Rubriques associées

Développeurs

Réponse à l’interaction utilisateur

Développement d’applications du Windows Store (JavaScript et HTML)

Démarrage rapide : pointeurs

Démarrage rapide : actions statiques

Démarrage rapide : actions de manipulation

Concepteurs

Conception de l’interaction tactile