Programmeren voor aanraakschermen:
Afbeelding
in een viewport
Hieronder zie je een deel van een foto. Op een aanraakscherm kun je over de foto swipen, zodat je de rest ook kunt bekijken.
Het bijzondere is dat de foto pas gaat bewegen als het scherm wordt losgelaten (lees:de swipe is afgelopen).
Op deze pagina wordt beschreven hoe je zoiets maakt. De code van het voorbeeld kun je downloaden, echter zonder de foto.
Daar moet je zelf voor zorgen.
N.B.: Het voorbeeld werkt alleen met een aanraakscherm. Slepen met de muis kan dus niet. Zie ook het item
Programmeren voor aanraakschermen.
- Er worden twee items besproken:
- De werking van het script.
- Toepassen in je eigen site.
- De werking van het script
- De code bestaat uit HTML, CSS en JavaScript (in de files swipedetect2.js en script.js).
- De JavaScript-code is een vereenvoudigde uitvoering van de code die wordt besproken in het item Programmeren voor aanraakschermen: Veegbewegingen.
- HTML
- De HTML van het voorbeeld bestaat uit een enkele <;div> met class="containerBox", met daarbinnen een <img>-tag met id="draggableElement".
- Voor de melding die ontstaat als er geen aanraakscherm is, is een vereenvoudigde versie gebruikt van de techniek die wordt
beschreven in het item Aanraakscherm detecteren.
- CSS
- De CSS van het voorbeeld bestaat uit twee blokken: .ContainerBox en #draggableElement.
- .ContainerBox definieert de viewport voor de foto: afmetingen
en positionering in het document.
De positionering is relative. Dat betekent dat de HTML op de plaats in het document moet staan waar de viewport moet verschijnen.
Het deel van de foto dat buiten de viewport valt is onzichtbaar gemaakt metoverflow:hidden. - #draggableElement verzorgt de positionering van de foto in de viewport (top en left) bij het laden van de pagina. Die worden door JavaScript veranderd als er over de foto wordt geswiped.
- De positionering is absoluut binnen containerBox, want anders kan de foto niet worden verplaatst.
- De afmetingen van de foto zijn alleen nodig in het JavaScript, daarom staan ze niet in de CSS.
- Om de bewegingen vloeiend te laten verlopen is een transition
toegevoegd.
- JavaScript
- Het JavaScript voor deze toepassing bestaat uit drie delen:
1. De melding die ontstaat als er geen aanraakscherm aanwezig is. Zie onder het kopje HTML. Dit wordt hier niet opnieuw besproken.
2. De (algemeen toepasbare) function swipedetect() voor het onderscheppen en analyseren van aanrakingen van het scherm. Deze staat in de file swipedetect.js.
3. De code die specifiek is voor de toepassing in het voorbeeld, in de file script.js.
- De function swipedetect2()
- Zoals hierboven al is gemeld is deze function algemeen toepasbaar. De function staat in de file swipedetect2.js.
- swipedetect2() declareert als eerste een set variabelen, te weten: touchsurface, touchobj, startX,
startY, vectorStr en handleswipe. Deze variabelen worden in het volgende besproken.
- De function swipedetect2() heeft twee parameters, die allebei verplicht zijn: el en callback.
• el bevat een verwijzing naar het HTML-element dat moet reageren op een swipe. Dit haal je op met document.getElementById(). De waarde van el wordt bewaard in touchsurface.
• callback is de naam van de function die moet worden uitgevoerd als swipedetect() zijn werk heeft gedaan. Als callback niet bestaat wordt een (anonieme) function gebruikt die niets doet. - swipedetect2() retourneert de string vectorStr. Deze bevat de swipe beweging als vector met componenten in X- en Y-richting gescheiden door een puntkomma, samengevoegd in een string.
- swipedetect2() maakt drie event-listeners aan, voor achtereenvolgens touchstart, touchmove en touchend.
- De event-listener voor touchstart bereidt het verplaatsen van de plaatjes voor.
• Als eerste wordt de lijst met de laatste wijziging van het touchEvent-object opgehaald en bewaard:touchobj = e.changedTouches[0];
.
• De coördinaten van de aanraking worden bewaard in startX en startY.
• Tenslotte wordt de default-actie voor dit event uitgeschakeld. - De event-listener voor touchmove schakelt alleen de default-actie voor dit event uit. Daardoor wordt onbedoeld scrollen voorkomen.
- De event-listener voor touchend berekent de vector van de beweging.
• Als eerste wordt de lijst met de laatste wijziging van het touchEvent-object opgehaald en bewaard in touchobj.
• De lengte van de swipe wordt berekend door startX resp. startY af te trekken van de huidige coördinaten in X- en Y-richting. De resultaten worden opgeslagen in vectorStr. De coördinaten worden achter elkaar gezet, gescheiden door een puntkomma.
• Tenslotte wordt de default-actie voor dit event uitgeschakeld.
- De event-listener voor touchstart bereidt het verplaatsen van de plaatjes voor.
- De drie event-listeners hebben een extra parameter, met de waarde false. Deze derde parameter is optioneel en heeft false als default-waarde. Om deze reden wordt deze parameter vrijwel altijd weggelaten. Als hier true wordt gebruikt, mag het event niet omhoog bubbelen in de object-boom. Zie het item Over Event-bubbling voor meer informatie.
- Merk op dat swipedetect2() maar één keer wordt aangeroepen, door de event-listener voor "load",
zie hieronder.
- De code die specifiek is voor de toepassing
- De voor het voorbeeld specifieke JavaScript-code bestaat uit een enkele listener die reageert op het event "load". Deze staat in de file script.js.
- Als er een aanraakscherm beschikbaar is worden functions en instellingen gemaakt zodat de pagina op swipes kan reageren. Anders stopt de uitvoering van de listener.
- Als eerste wordt een set variabelen gedeclareerd en geïnitialiseerd, te weten:
• De afmetingen van de foto: imgSizeX (hier: 868) en imgSizeY (hier: 1023).
• De afmetingen van de viewport: viewSizeX (hier: 400) en viewSizeY (hier: 250).
• De positie van de foto ten opzichte van de linker bovenhoek van de viewport: posXold (hier: -100) en posYold (hier: -350). Deze waarden moeten gelijk zijn aan de waarden voor top resp. left in het CSS-blok #draggableElement.
• Een verwijzing naar het id draggableElement, deze wordt opgeslagen in draggable.
• Het resultaat van swipedetect2() wordt als string opgeslagen in vectorStr.
• Tenslotte zijn er nog de hulp-variabelen vector, posX en posY. Deze drie kijgen pas een waarde bij het verwerken van de gemaakte swipe. - Bovenstaande variabelen moeten worden opgegeven in pixels.
- Vervolgens wordt de callback van swipedetect2() gedefinieerd. Deze splitst vectorStr op in de X- en Y-compontent van de swipe-vector en slaat deze op in de array vector. Let wel: beide componenten zijn nog opgeslagen als string.
- De nieuwe positie van de linker bovenhoek van de foto wordt berekend door de vector op te tellen bij de 'huidige' positie,
die in posXold en posYold zijn opgeslagen. Hierbij worden de componenten van vector worden omgezet van
string naar getal.
De nieuwe coördinaten worden bewaard in posX en posY. - Nu wordt gekeken of de linker bovenhoek van de foto niet binnen de grenzen van de viewport komt. Dat gebeurt als posX en/of posY groter wordt dan nul. Als dat gebeurt wordt de waarde op nul gezet.
- Tegelijk wordt gekeken of de rechter onderhoek niet binnen de viewport komt. Dat gebeurt als posX kleiner wordt dan
-imgSizeX + viewSizeX. Als dat gebeurt wordt posX gelijk gemaakt aan die waarde.
Dezelfde conditie wordt gebruikt in Y-richting. - Nu wordt de nieuwe positie van de foto daadwerkelijk doorgevoerd in het document. De CSS-transition zorgt voor het vloeiende verloop van de beweging.
- Tenslotte worden de waarden van posX en posY gekopieerd naar posXold en posYold, zodat de
plaats van de foto is ingesteld voor de volgende swipe.
- Toepassen in je eigen site
- Regel een scherpe afbeelding van behoorlijke afmetingen. Alle soorten waar HTML mee overweg kan zijn mogelijk. Bepaal de grootte van de viewport waar je de foto in wilt zetten. Bepaal ook de positie van de afbeelding in de viewport.
- Download de .zip-file en pak hem uit. Bouw de code op zoals hieronder is aangegeven.
- Zet de bestandsnaam van de afbeelding in de HTML.
- Wijzig de CSS: zet de afmetingen van de viewport in.ContainerBox (width en height). Pas ook de positie van de afbeelding in de viewport aan (top enleft in #draggableElement).
- Wijzig het JavaScript in de file script.js: zet de afmetingen van de afbeelding in imgSizeX en imgSizeY.
zet de afmetingen van de viewport in viewSizeX en viewSizeY. Zet de coördinaten van de linker bovenhoek in
posXold en posYold.
- Je kunt de tekst en de opmaak van de melding over het aanraakscherm naar je eigen inzicht aanpassen. Je kunt de melding natuurlijk ook gewoon weglaten.
Gebruik:
- De code staat gedeeltelijk in de <HEAD> en gedeeltelijk in de <BODY>.
De code van het voorbeeld ziet er als volgt uit:
(Zet dit in de <HEAD>).
<style>
.containerBox {
position:relative;
margin:0 auto;
border:1px solid black;
width:400px;
height:250px;
overflow:hidden;
}
#draggableElement {
position:absolute;
top:-350px;
left:-100px;
transition: all 0.5s ease;
}
</style>
<script src="swipedetect2.js"></script>
<script src="script.js"></script>
(Zet dit in de <BODY> op de plaats waar de melding moet verschijnen).
<p id="Melding" style="text-align:center"><script>
if ("ontouchstart" in document.documentElement == false) {
document.getElementById('Melding').innerHTML =
"<b style=\"color:maroon; font-weight:bold\">Om het voorbeeld te
kunnen bekijken is een aanraakscherm nodig. Op dit scherm werkt
het dus niet.</b>";
}
</script></p>
(Zet dit in de <BODY> op de plaats waar de viewport voor de foto moet staan).
<div class="containerBox">
<img id="draggableElement" src="foto.jpg">
</div>
Downloaden:
Druk op de knop:
File: voorb294.zip, 1788 bytes.
Opmerking:
Het item Figuur in een Viewport (Draggable Content) bevat een vergelijkbare
techniek, maar dan met de muis.