13.4 Gester
I detta exempel illustreras några vanliga gester och det visas hur man kan känna av dem i programmet. En del utförs med en pekare och de fungerar då både med mus och på en pekskärm. Ett par kräver två pekare och kan då endast utföras på en pekskärm. Följande gester tas upp:
- Klick och dubbelklick med pointerdown.
- Drag för att flytta element.
- Drag för att panorera i en bild.
- Svep (swipe) åt vänster eller höger.
- Nyp och dra ihop (pinch och spread) med två fingrar.
Gesterna och deras exempel visas i varsin del i exemplet och tas här även upp i varsin film.
a. Klick och dubbelklick — 10 min.
b. Drag för flyttning — 2 min.
c. Drag för panorering — 13 min.
d. Svep — 9 min.
e. Nyp och dra isär — 11 min.
Sammanfattning
Här följer en kort sammanfattning av de olika gesterna och delarna i exemplet.
a. Klick och dubbelklick
Har vi ett element som vi endast ska klicka eller dubbelklicka på kan vi använda händelserna click
och dblclick
, vilket då fungerar både med mus och på en pekskärm. Men ska vi även kunna utföra andra pekaroperationer, som att dra elementet, lägger vi på CSS-koden touch-action:none
och händelselyssnare för touchstart
, där vi utför preventDefault()
, för att förhindra standardoperationer på en pekskärm. Då fungerar inte längre click
och dblclick
, utan vi får istället använda pointerdown
eller pointerup
. Det är den situationen som visas i exemplet och det är framför alt för att kunna känna av dubbelklick som det behövs lite extra kod. I exempelt visas hur man kan lösa det med en CSS-klass och en timer.
b. Dra för att flytta
Detta har ju visats ingående i de två föregående exemplen, men här ges en kort repetition.
c. Drag för panorering
I exemplet kan man panorera en bild inom en ruta. Rutan skapas genom ett div
-element som omger img
-taggen för bilden. I CSS-koden ges div
-elementet en mindre storlek än bilden och det som hamnar utanför rutan döljs med overflow:hidden
. För att panorera förskjuts bilden i x- och y-led med hjälp av CSS-egenskapen translate
. Programkoden är i övrigt uppbyggd på samma sätt som vid drag-and-drop.
d. Svep åt vänster eller höger
Svep är också en dragrörelse, men här drar man endast en liten bit och släpper sedan upp pekaren. Därefter kan operationen utföras, t.ex. att fortsätta skjuta elementet till ett målelement, bläddra i ett bildspel (kommer i ett senare exempel) eller något annat. Även här är koden uppbyggd på samma sätt som vid drag-and-drop, men förflyttning av det element som dras sker med translateX()
.
e. Nyp och dra isär
Med två fingrar (ofta tummen och pekfingret) kan man dra ihop eller isär fingrarna och därmed utföra gesterna "pinch" och "spread". Detta kan t.ex. användas för att förminska/förstora ett element eller zomma i en bild. Båda dessa operationerna tas upp i kommande exempel. I detta exempel koncentrerar vi oss på interaktionen och hur vi kan känna av de båda gesterna. Båda pekarna generar varsina händelser och event
-objekt, så pointermove
genereras för var och en av dem och vi kommer in i pointerStart
för båda pekarna. För att skilja på dem används egenskapen pointerId
i event
-objektet. Dessa id sparas tillsammans med event
-objekten i ett Map
-objekt, där vi sedan kan ta ut de båda pekarna och beräkna avståndet mellan dem. I pointerMove
kollar man om avståndet ökat eller minskat, för att avgöra vilken gest det är.
Egna övningar
Denna övning tar upp den första gesten med dubbelklick. Övriga gester kommer sedan exemplifieras mer i kommande exempel. Öppna som vanligt test.html med Live Server och skriv kod i test.js. I filen finns kod för att kunna dra runt rutorna med bilder (det är exakt samma program som i del b). Du ska nu lägga till kod, så att man kan markera en ruta, genom att dubbelklicka på den.
- Kopiera funktionerna
clickBox
ochclickOutSideBox
från script-a.js och lägg dem sist i test.js. - I
clickBox
tar du bortelse
-delen. Innehållet iif
-satsen byter du till följande tre rader:- Inför en lokal variabel kallad
markedElem
och spara elementet med klassenmarked
, som du söker fram medquerySelector
.- Resultatet blir alltså antingen
null
eller en referens till ett element.
- Resultatet blir alltså antingen
- Kontrollera i en
if
-sats ommarkedElem
har ett element —if (markedElem)
. I så fall tar du bort klassenmarked
ur elementet. - Lägg in ytterligare en
if
-sats, där du kontrollerar ommarkedElem
ochthis
är olika. I så fall lägger du in klassenmarked
ithis
.
- Inför en lokal variabel kallad
- I
init
-funktionen lägger du på en händelselyssnare förpointerdown
som anroparclickBox
på alla element idragElems
.- Testa nu att dubbelkilcka på boxarna. Man kan både markera och avmarkera en box genom att dubbelklicka på den. Det ska också endast vara en box som kan vara markerad.
- I
init
-funktionen lägger du nu också på en händelselyssnare pådocument
för händelsenpointerdown
och anrop av funktionenclickOutsideBox
. - I
clcikOutsideBox
byter du ut de två sista raderna mot två rader som är exakt desamma som de två första raderna du la in iif
-satsen iclickBox
.- Testa nu att du också kan avmarkera en box, genom att klicka utanför boxarna. I detta fall är det ett enkelklick.