Elementen tegelijkertijd animeren
Voor sommige toepassingen is het handig om een bepaalde figuur steeds over het scherm te laten gaan. Een voorbeeld daarvan is de tram hier rechts. In het voorbeeld gaat die tram van links naar rechts over het scherm, of omgekeerd. In het voorbeeld is het scherm in drie kolommen verdeeld. In elk van deze kolommen rijdt de tram heen en weer.
Als je het document lokaal opent (dus vanaf je PC) in een browser loopt het goed. Dus: het voorbeeld downloaden en lokaal uitproberen. Daarna testen met de server van je hosting provider!
Op deze pagina wordt uitgelegd hoe je zoiets maakt. De code kun je downloaden om zelf te gebruiken, inclusief het plaatje.
Dit is een bewerking van code die ik vond in Webdesigner Magazine 98 (september 2017), pag. 70 en 71.
Dit blad wordt sinds eind november 2017 niet meer gemaakt.
Voor deze site is de opmaak van het voorbeeld aangepast. Een kleine onvolkomenheid in de code is gerepareerd.
- 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 en JavaScript (in het document) en CSS (in de file styles.css).
- HTML
- De <body> bevat een enkele <div>-tag met de klasse content, gevolgd door het noodzakelijke JavaScript. Verder bevat de <body> geen content.
- In het voorbeeld bevat content drie <div>-tags met de klasse container. Die worden gebruikt om het scherm in drie delen te verdelen. De breedte van elk deel is 33%, zodat er een smal randje aan de redhterkant overblijft.
- Elk van de containers bevat een <div>-tag met de klasse tram. Daar zit het plaatje in. De CSS
zorgt er voor, in combinatie met JavaScript, dat de trams bewegen.
- CSS
- De CSS begint met een eenvoudige reset van de body. De body bedekt het hele window en de binnen- en buitenmarges worden op nul gezet. De achtergrond bedekt het hele window en de achtergrondkleur wordt ingesteld.
- Het blok met id="content" bedekt de hele body.
- De blokken met klasse container zijn relatief gepositioneerd t.o.v. content. Ze hebben elk de breedte van
33%. Door deze breedte liggen ze naast elkaar. Er blijft aan de rechterkant een klein randje over.
De blokken content zijn elk even hoog als de container. Ze hebben aan de rechterkant een dunne, grijze rand. - De achtergrond van de klasse tram is een figuur die is gemaakt met SVG. Daardoor is de figuur eenvoudig schaalbaar. In de SVG-code zijn de afmetingen opgegeven als 1127.5 breed en 391.7 hoog. De CSS stelt de hoogte in op 200px. Daardoor is de breedte van de tram op het scherm 576px; dit komt overeen met 100%.
- De tram heeft een bovenmarge van 200px. Die wordt door JavaScript bij elke keer dat de tram gaat bewegen aangepast.
- De tram wordt op 700px links van het scherm geplaatst en is daardoor niet zichtbaar.
- De achtergrondfiguur mag niet verder worden geschaald. Daarom staat is background-size: 100% 100%; opgegeven.
- De klassen left en right, die door JavaScript aan tram kunnen worden toegevoegd, definiéren alleen de animatie, die lineair verloopt en 3 seconden duurt.
- Bij de animatie van left beweegt de linker bovenhoek van de tram van +700px (dus 700px rechts van de linker rand van container; omdat de tram 576px breed is, is dat net buiten beeld) naar -700px (dus 700px links van de linker rand van container;omdat de tram 576px breed is, is dat net buiten beeld).
- Bij de animatie van right beweegt de linker bovenhoek van de tram van -700px (dus 700px links van de linker rand
van container) naar +700px (dus 700px rechts van de linker rand van container; omdat de tram 576px breed is,
is dat net buiten beeld).
- JavaScript
- De beweging van de trams wordt geregeld met CSS. Het JavaScript zorgt er voor dat er willekeurig een richting wordt gekozen.
- De plaats van het JavaScript in de <body> is belangrijk. Het moet na de HTML staan.
- Zodra het Javascript is geladen begint het met de uitvoering. Als eerste wort er een referentie gemaakt naar het element
met klasse content. Dat gebeurt met getElementById().
Het is in deze code niet mogelijk om er daar meer dan één van te hebben. Tevens wordt de variabele timer aangemaakt. Die wordt verderop in het script gebruikt. - Daarna wordt de function makeChange() gedefinieerd. Die maakt als eerste een lijst aan van alle elementen die de klasse tram hebben. Dat gebeurt querySelectorAll(). In het voorbeeld zijn dat er drie.
- Binnen makeChange() wordt de function change() gedefinieerd. Die doet het eigenlijke werk.
- Direct na de definitie van change() wordt deze aangeroepen. change() roept ook zichzelf aan met een vertraging. Dat gaat via setTimeout().
- De vertraging (berekend in milliseconden) is 97% van de duur van de animatie. In het voorbeeld is dat dus 0.97 × 3000
= 2910 ms.
De reden voor deze vertraging is dat het er allemaal net even wat mooier uitziet.
- change() verwijdert eerst de klassen left en right van de elementen met de klasse tram. Dat gebeurt door classList.remove(). Het verwijderen van een klasse van een element dat die klasse niet heeft, hindert niet; classList.remove() kan daar tegen.
- Vervolgens wordt een variabele random aangemaakt, waarin een willekeurig getal (0 ≤ random ≤ 0.9999…) wordt opgeslagen.
- random wordt gebruikt om de bovenmarge van het plaatje van de tram in te stellen. Door random met 400 te vermenigvuldigen wordt de marge een waarde tussen 0px en 400px.
- random wordt ook gebruikt om de rijrichting van de tram te bepalen. Door random met 2 te vermenigvuldigen en naar boven af te ronden ontstaat de waarde 2 of 1. Op basis van die getallen krijgt de klasse tram er de klasse left of right bij.
- Als een tram de klasse left krijgt, beweegt de tram van rechts naar links. Als een tram de klasse right krijgt,
beweegt de tram van links naar rechts.
- Direct na de definitie van makeChange() wordt deze gestart.
- Toepassen in je eigen site
- Download de .zip-file en pak hem uit. Hernoem de file html584a.htm naar index.html of iets dergelijks. Je hebt nu een werkend voorbeeld.
- Pas de kleuren aan naar je eigen smaak. Vervang de afbeelding tram.svg door je eigen plaatje. Je kunt hier elk grafisch formaat voor gebruiken dat door een browser wordt begrepen. Een plaatje met één kleur en transparante achtergrond (.gif, .png) zou bij mij de voorkeur hebben, maar echt nodig is het niet.
- Als je alleen de kleur van de tram wilt veranderen, open je de file tram.svg met een editor voor platte tekst. Windows
kladblok is daarvoor heel geschikt.
Verander de kleurcode #d00 in het blok:
<style>
.st0{ fill:#d00; }
</style>
In het voorbeeld is de tram rood. Dat is om goed aan te geven waar het over gaat. Het beste kies jee en neutrale, lichte tint die weinig contrast heeft met de achtergrond. - De bewegingssnelheid van de tram kun je veranderen door de animaties te veranderen. Dan moet je ook de tijd in de aanroep van setTimeout() aanpassen zoals hierboven is genoemd.
- Als je het aantal kolommen wilt wijzigen dan voeg je een of meerdere containers toe binnen het blok content, of je verwijdert ze juist. In beide gevallen moet je in de CSS de breedte van de klasse container wijzigen. Het aantal containers maal de breedte moet net een beetje minder zijn dan 100%. Dan staan de containers naast elkaar.
- Als de (netto) breedte van de figuur verandert moet je ook de waarde van de getallen 700px (met of zonder min-teken) aanpassen.
- Tenslotte
- Als het voorbeeld wordt getoond op een scherm dat breder is dan ongeveer 2000px, zal het gebeuren dat de tram te vroeg. verdwijnt. Als dat gebeurt moet je de waarden -700px en 700px verhogen in de background-position en in beide@keyframe-sets.
- De warde 700px zijn gebaseerd op de netto-breedte van de tram-figuur. Als je een bredere figuur laat bewegen, moet je die waarde verhogen. Als je een smallere figuur wilt laten bewegen kun je de waarden van 700px verlagen.
- Als je de waarden van 700px aanpast moet je ook de waarde in setTimeout() in het JavaScript veranderen, zoals hiervoor is beschreven.
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>).
<link rel="stylesheet" href="styles.css">
(Zet dit in de <BODY>).
div id="content">
<div class="container">
<div class="tram"></div>
</div>
<div class="container">
<div class="tram"></div>
</div>
<div class="container">
<div class="tram"></div>
</div>
</div>
(Zet dit in de <BODY>, na de HTML).
<script>
var content = document.getElementById('content');
var timer;
function makeChange() {
var trams = content.querySelectorAll('.tram');
function change() {
for (var i = 0; trams.length > i; i++) {
trams[i].classList.remove('left');
trams[i].classList.remove('right');
var random = Math.random();
var ht = Math.ceil(random * 400);
trams[i].style.marginTop = ht + "px";
if (Math.ceil(2 * random) === 2) {
trams[i].classList.add('left');
} else {
trams[i].classList.add('right');
}
}
timer = setTimeout(change, 2910);
}
change();
}
makeChange();
</script>
Downloaden:
Druk op de knop:
File: voorb584.zip, 2384 bytes.