Guida introduttiva: Gesti e manipolazioni DOM (HTML)

[ Questo articolo è rivolto agli sviluppatori per Windows 8.x e Windows Phone 8.x che realizzano app di Windows Runtime. Gli sviluppatori che usano Windows 10 possono vedere Documentazione aggiornata ]

Puoi personalizzare l'esperienza utente per alcuni gesti di base descritti nel linguaggio per il tocco di Windows, ad esempio scorrimento, rotazione e ridimensionamento, tramite la gestione degli eventi tocco DOM (Document Object Model) di base.

Aggiornamenti per Windows 8.1: In Windows 8.1 vengono introdotti diversi aggiornamenti e miglioramenti alle API di input tramite puntatore. Per altre informazioni, vedi Modifiche delle API per Windows 8.1.

Se non hai familiarità con lo sviluppo di app mediante JavaScript,: Leggi questi argomenti per imparare a conoscere le tecnologie qui descritte.

Creare la prima app con JavaScript

Roadmap per app in JavaScript

Scopri di più sugli eventi in Guida introduttiva: Aggiunta di controlli HTML e gestione di eventi

Funzionalità delle app dall'inizio alla fine:

Per conoscere meglio questa funzionalità, vedi gli argomenti della serie Funzionalità dell'app dall'inizio alla fine

Interazioni con l'utente, dall'inizio alla fine (HTML)

Personalizzazione delle interazioni con l'utente, dall'inizio alla fine (HTML)

Linee guida per l'esperienza utente:

Le raccolte di controlli della piattaforma (HTML e XAML) forniscono un'esperienza di interazione utente completa, che include interazioni standard, effetti fisici animati e feedback visivo. Se non hai l'esigenza di supportare interazioni personalizzate, usa questi controlli predefiniti.

Se i controlli della piattaforma non sono sufficienti, queste linee guida ti aiuteranno a offrire un'esperienza di interazione coinvolgente e Immersive coerente tra le diverse modalità di input. Queste linee guida sono incentrate principalmente sull'input tocco, ma sono rilevanti anche per input di tipo tocco, mouse, tastiera e stilo.

Esempi: Per esaminare questa funzionalità in azione, vedi gli esempi di app.

Personalizzazione delle interazioni con l'utente, dall'inizio alla fine

Esempio di controlli HTML di scorrimento, panoramica e zoom

Input: Esempio di gestione degli eventi relativi al puntatore DOM

Input: Esempio di gesti istanziabili

Obiettivo: Viene illustrato come rilevare, gestire ed elaborare gesti di base per la traslazione, la rotazione e l'adattamento basate su interazioni tramite tocco, mouse, penna/stilo ed eventi relativi ai gesti DOM.

Prerequisiti

Vedi Guida introduttiva: Puntatori.

In questa guida introduttiva si suppone che tu sia in grado di creare con Javascript un'app di base che usi il modello Libreria Windows per JavaScript.

Per completare questa esercitazione, devi:

Tempo per il completamento: 30 minuti.

Che cosa sono gli eventi relativi ai gesti?

Un gesto è un atto fisico o un movimento eseguito su o tramite il dispositivo di input (un dito o più dita su una superficie di tocco, un digitalizzatori di penna/stilo, il mouse e così via). Queste interazioni naturali vengono mappate a operazioni su elementi nel sistema e nell'app. Per altre informazioni, vedi Gesti, manipolazioni e interazioni.

Windows usa un set di gesti di base per interagire con l'interfaccia utente e manipolarla.

GestoDescrizione
ToccareGesto tocco

Viene rilevato un singolo contatto che viene immediatamente sollevato.

Toccare un elemento ne richiama la relativa azione principale.

Tenere premutoGesto pressione prolungata

Viene rilevato un singolo contatto che si prolunga.

La pressione prolungata genera la visualizzazione di informazioni dettagliate o elementi visivi a scopo didattico, ad esempio una descrizione comando o un menu contestuale, senza dover eseguire un'azione specifica.

ScorrereGesto scorrimento

Vengono rilevati uno o più contatti che si spostano nella stessa direzione.

Lo scorrimento viene usato principalmente per interazioni di tipo panoramica, ma può essere usato anche per operazioni di spostamento, disegno o scrittura.

Scorrere rapidamenteGesto scorrimento rapido

Vengono rilevati uno o più contatti che si spostano nella stessa direzione per una breve distanza.

Lo scorrimento rapido viene usato eseguire selezioni, comandi e spostamenti.

RuotareGesto rotazione

Vengono rilevati due o più contatti che si muovono in senso orario o antiorario.

La rotazione viene usata per ruotare gli oggetti.

Avvicinare le ditaMovimento di avvicinamento delle dita

Vengono rilevati due o più contatti che si avvicinano tra di loro.

L'avvicinamento delle dita viene usato per eseguire lo zoom indietro.

Allontanare le ditaMovimento di allontanamento delle dita

Vengono rilevati due o più contatti che si allontanano tra di loro.

L'allontanamento delle dita viene usato per eseguire lo zoom avanti.

Per altre informazioni su questi gesti e sulla correlazione con il linguaggio per il tocco di Windows, vedi Progettazione delle interazioni tramite tocco.

 

Il rilevamento dei gesti ti permette di estendere il modello di interazione della tua app basandoti sugli eventi puntatore di base descritti in Guida introduttiva: Gestione dell'input del puntatore. Infatti, con tutta probabilità la tua app userà gli eventi relativi ai gesti per la gestione dei tocchi, la panoramica o lo spostamento tramite scorrimento e lo zoom con avvicinamento o allontanamento delle dita e i dati del puntatore non elaborati per supportare il rilevamento e l'elaborazione dei gesti.

L'app può elaborare più gesti contemporaneamente, ad esempio zoom e rotazione, raggruppare i contatti del puntatore per definire un elemento di destinazione specifico, ad esempio associare tutti i contatti alla destinazione del contatto iniziale o principale, e identificare gli elementi specifici selezionati mediante un gesto o un contatto del puntatore specifico.

Importante  Se implementi un supporto personalizzato per le interazioni, tieni presente che gli utenti si aspettano un'esperienza intuitiva che include l'interazione diretta con gli elementi dell'interfaccia utente della tua app. Ti consigliamo di modellare le tue interazioni personalizzate sulle raccolte di controlli della piattaforma (HTML e XAML) per garantire la coerenza e l'intuitività. I controlli inclusi in queste librerie forniscono un'esperienza di interazione utente completa che include le interazioni standard, gli effetti fisici animati, il feedback visivo e l'accessibilità. Crea interazioni personalizzate solo in presenza di un requisito chiaro e ben definito e qualora le interazioni di base non siano in grado di supportare il tuo scenario.

 

Creare l'interfaccia utente

In questo esempio verrà usato un rettangolo (target) come oggetto di destinazione per l'input del puntatore.

Il rettangolo funge da miscelatore di colori di base. Il colore della destinazione cambia in base alla selezione del colore RGB (rosso, verde o blu) e all'angolo di rotazione della destinazione come indicato tramite il gesto di rotazione. Calcoliamo il valore di rosso, verde o blu dall'angolo di rotazione.

Visualizziamo i dettagli per ogni evento relativo al puntatore e ai gesti, insieme alla matrice di trasformazione corrente applicata alla destinazione, all'interno dell'oggetto di destinazione.

HTML per questo esempio.

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

CSS (Cascading Style Sheets) per questo esempio.

Nota  Gli eventi puntatore non vengono generati durante un'interazione di tipo panoramica o zoom. Puoi disabilitare la panoramica e lo zoom in un'area tramite le proprietà CSS msTouchAction, overflow e -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);
}

Ascoltare gli eventi relativi ai gesti e al puntatore

In questo codice vengono impostati il miscelatore di colori e i selettori di colori e vengono dichiarati i vari listener di eventi.

Nella maggior parte dei casi è consigliabile ottenere informazioni sul puntatore mediante l'argomento dell'evento del gestore eventi del puntatore nel framework del linguaggio che hai scelto.

Se l'argomento dell'evento non espone i dettagli del puntatore richiesti dall'app, puoi ottenere l'accesso a dati del puntatore estesi dall'argomento dell'evento tramite i metodi getCurrentPoint e getIntermediatePoints o le proprietà currentPoint e intermediatePoints. Ti consigliamo di usare i metodi getCurrentPoint e getIntermediatePoints perché puoi specificare il contesto dei dati del puntatore.

Per prima cosa, dichiariamo le variabili globali, definiamo un oggetto dati (colorInfo) per tracciare lo stato della destinazione e inizializziamo sia il miscelatore di colori (target) che i selettori di colori RGB.

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

Impostiamo quindi il miscelatore di colori, associamo un riconoscitore dei gesti (msGesture) all'oggetto e dichiariamo i vari listener di eventi.

Suggerimento  Per questo esempio, solo un oggetto è associato a un riconoscitore di gesti. Se l'app contiene un numero elevato di oggetti manipolabili, ad esempio un puzzle, prova a creare dinamicamente un riconoscitore di gesti solo quando viene rilevato l'input del puntatore su un oggetto di destinazione. Il riconoscitore di gesti può essere eliminato al termine della manipolazione. Per un esempio, vedi Input: Esempio di gesti istanziabili. Per evitare il sovraccarico delle attività di creazione ed eliminazione, crea un piccolo pool di riconoscitori di gesti in fase di inizializzazione e assegnali dinamicamente in base alle necessità.

 

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

Infine, inizializziamo i selettori di colori RGB (con i listener di eventi) e l'oggetto 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;
}

Gestire l'evento relativo al puntatore giù

Quando si verifica un evento relativo al puntatore giù, otteniamo il colore RGB selezionato e associamo il puntatore al riconoscitore dei gesti chiamando il metodo addPointer. Tracciamo la sequenza e l'oggetto pointerType per riassociare il puntatore al riconoscitore dei gesti, se necessario.

Se non è selezionato alcun colore, ignoriamo l'evento puntatore.

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

Gestire gli eventi relativi ai gesti

Nel codice seguente elaboreremo i gesti relativi a traslazione (avvicinamento o allontanamento delle dita), rotazione, e ridimensionamento.

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

Gestire altri eventi, in base alle esigenze

In questo esempio vengono descritti solo gli altri eventi gestiti in questa sezione. Un'app più potente può fornire funzionalità aggiuntive.

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

Per i link a esempi più complessi, vedi gli Argomenti correlati alla fine della pagina.

Esempio completo

Vedi il codice completo per i gesti e le manipolazioni DOM.

Riepilogo e passaggi successivi

In questa Guida introduttiva hai imparato i concetti relativi alla gestione degli eventi relativi ai gesti di base nelle app di Windows Store in JavaScript.

Il riconoscimento dei gesti di base, unitamente agli eventi del puntatore, è utile per la gestione di semplici interazioni quali traslazione (scorrimento o scorrimento rapido), rotazione e ridimensionamento (avvicinamento o allontanamento delle dita).

Per informazioni su come gestire interazioni più elaborate e offrire un'esperienza di interazione completamente personalizzata, vedi Guida introduttiva: Gesti statici e Guida introduttiva: Gesti di manipolazione.

Per altre informazioni sul linguaggio per il tocco di Windows 8, vedi Progettazione delle interazioni tramite tocco.

Argomenti correlati

Sviluppatori

Risposta alle interazioni degli utenti

Sviluppo di app di Windows Store (JavaScript e HTML)

Guida introduttiva: Puntatori

Guida introduttiva: Gesti statici

Guida introduttiva: Gesti di manipolazione

Designer

Progettazione delle interazioni tramite tocco