Schijngestalte van de Maan II: Tekening met JavaScript
Weerberichten zijn heel populair op internet. Dat is op zich niet vreemd, want westerlingen praten heel veel over het weer. Websites waarop weerberichten staan worden vaak "aangekleed" met andere zaken die met weer te maken hebben, zoals een plaatje van de stand van de maan. Deze website is daarop geen uitzondering. Hieronder zie je een voorbeeld van hoe dat er uit zou kunnen zien.
Het bijzondere van dit plaatje is dat het helemaal is getekend met behulp van JavaScript.
Het oorspronkelijke idee voor deze aanpak is van James Thiele, die daarvoor een script op zijn website heeft gezet. Ik heb
de kleuren aangepast (was zwart en wit) en het rekengedeelte vervangen door een (nauwkeuriger) script van Tim Poulsen. Daarbij
heb ik het gemakkelijker gemaakt om het script in te bouwen in een website. Ook heb ik er wat eigen ontwikkelingen aan toegevoegd.
De sites van Thiele en Poulsen zijn helaas verdwenen.
In 2020 heb ik het JavaScript aangepast, de HTML herschreven en CSS toegevoegd, om het te laten werken in de moderne browsers.
Hier wordt beschreven hoe je dit kunt aanpakken.
De code staat onderaan de pagina. Je kunt hem ook downloaden om zelf te gebruiken.
Elders op deze site wordt een vergelijkbaar script geschreven dat werkt met "echte" plaatjes. Zie het item "Schijngestalte van de Maan".
- Er worden twee items besproken:
- Inbouwen op je eigen website
- Globale werking van het script
- De HTML en de CSS staan in het document. Het JavaScript code staat in de file maanstand.js. Deze hoef je niet te
veranderen om hem te kunnen gebruiken.
- De HTML van het voorbeeld bestaat uit een <table> met de klasse wrapper. Deze bevat één
rij, met twee cellen die de klasse Opmerk-g hebben. De eerste cel bevat de meldingen; de tweede cel bevat het plaatje.
De klasse Opmerk-g hoort bij deze site en dient alleen om de letters wat kleiner te maken.
De wrapper dient dus alleen voor de opmaak van het voorbeeld. Hoewel het in de moderne visie op Webdesign "not done" is om een website op te maken met tabellen, is het voor deze toepassing veruit het handigst.
- De CSS bevat naast wrapper ook twee andere klassen, te weten moonClass en moonCell. Deze worden door JavaScript in het document gezet. In de HTML komen ze niet voor.
- Het plaatje wordt opgebouwd in een table met de klasse moonClass. Deze table een aantal rijen dat gelijk is aan tweemaal de diameter van de maan, uitgedrukt in pixels. Elke rij bevat één cel met klasse moonCell.
- Om te zorgen dat er een mooie cirkel ontstaat, heeft moonCell de instelling text-align: center;. Verder zijn de eigenschappen padding, font-size en line-height op nul gezet, zodat de hoogte van de cel niet meer is dan één pixel.
- Ook is het nodig om de witruimte die door de randen van de cellen en de tabelrijen op nul te zetten. Dan komen de plaatjes waarmee de maansikkel wordt gemaakt netjes tegen elkaar aan te liggen. Dit is gemaakt met border-collapse: collapse;. in de klasse moonClass.Verder wordt deze table rechts in het document gezet met wat padding zodat de maan niet helemaal pal tegen de rechter marge staat.
- Om het plaatje van de maan te laten zien roep de function showMoon(size) aan. De code van deze function moet ongewijzigd blijven.
- De parameter van showMoon() heeft de volgende betekenis:
Parameter Betekenis size Dit is de straal van de cirkel (dus de halve diameter van de maan), in pixels. Hier: 35.
Om het een beetje zichtbaar te houden wordt aanbevolen om size niet kleiner te kiezen dan 10. De bovengrens van size wordt bepaald door de breedte van het document op het scherm. Voor deze website is 200 zo'n beetje het maximum.
Bij de aanroep van showMoon moet de waarde van size tussen enkele of dubbele aanhalingstekens staan. Deze parameter is verplicht en mag dus niet worden weggelaten.
Toelichting: Het plaatje wordt op het scherm pixelrij voor pixelrij opgebouwd met twee gif-plaatjes die elk 1px × 1px groot zijn (op deze pagina: blauw en geel). Voor elke rij wordt de breedte van beide plaatjes berekend.
Het plaatje van de maan wordt in een table gezet. De table heeft voor elke pixelrij een regel (<tr>) met daarin één cel. Elke cel bevat een blauw en een geel plaatje.
- De meldingen over de maanstand verschijnen als je showMessages(param) aanroept.
- Met de parameter param bepaal je welke meldingen er verschijnen.
De aanpak die hier wordt gebezigd staat bekend als "bitwise AND". Het werkt als volgt:
- Elke melding heeft een uniek volgnummer, dat een macht van twee is: 20, 21, 22, 23, 24, enzovoort. In gewone getallen: 1, 2, 4, 8, 16, ...
- Met deze getallen geef je aan welke van de meldingen je wilt laten zien:
Alleen de eerste melding laten zien: param = 1 ( = 20) Alleen de tweede melding laten zien: param = 2 ( = 21) Alleen de derde melding laten zien: param = 4 ( = 22) Alleen de vierde melding laten zien: param = 8 ( = 23) Alleen de vijfde melding laten zien: param = 16 ( = 24)
Enzovoort.
- Als je meer dan één melding wilt laten zien tel je de getallen bij elkaar op, bijvoorbeeld:
De eerste en de tweede melding laten zien: param = 1+2 = 3 De eerste en de derde melding laten zien: param = 1+4 = 5 De tweede en de derde melding laten zien: param = 2+4 = 6 De eerste, de tweede en de derde melding laten zien: param = 1+2+4 = 7
Enzovoort.
- De melding die het hoogste nummer heeft, wordt als eerste getoond. Dit volgt direct uit de programmering van dit algoritme. In het bijzondere geval dat je de volgorde van de meldingen wilt veranderen moet je de volgorde van de meldingen in showMessages() aanpassen, maar precies in omgekeerde volgorde!
- De function showMessages() kan zes meldingen geven. Je kunt dus combinaties maken met de getallen 20, 21, 22, 23, 24 en 25, Ofwel 1, 2, 4, 8, 16 en 32. Als je alle meldingen wilt laten zien gebruik je dus 1+2+4+8+16+32 = 63.
- Als je aan ShowMessages() een waarde van param meegeeft die ≤ 0 of die ≥ 64 is, wordt param = 63 gebruikt. Dat gebeurt ook als je param weglaat.
- Het script werkt in grote lijnen als volgt:
- Een maancyclus loopt van Nieuwe Maan tot Nieuwe Maan.
- Het script bevat een datum in het verleden waarop het Nieuwe Maan is (de begindatum).
Deze website gebruikt 29 juli 2003 om 06:53:00 uur. - Het aantal etmalen dat is verstreken tussen 'nu' en de begindatum wordt berekend.
Dit wordt verminderd met het aantal verstreken volledige maancycli sinds de begindatum. - Hieruit volgt het percentage van de huidige maancyclus. Aan dit percentage wordt de naam van de schijngestalte ontleend:
- bij 0% tot 2,5% en 97,5% tot 100%: Nieuwe Maan
- bij 22,5% tot 27,5%: Eerste Kwartier
- bij 47,5% tot 52,5%: Volle Maan
- bij 72,5% tot 77,5%: Laatste Kwartier
- Als het percentage <50% is: Wassende maan
- Als het percentage > 50% is: Afnemende maan.
- Het percentage van de maan dat verlicht is volgt uit het percentage van de maancyclus dat is doorlopen.
- Het plaatje van de maan wordt opgebouwd uit twee .GIF-plaatjes, die elk één bij één pixel
groot zijn. Het ene plaatje heeft de donkere (schaduw-)kleur van de maan en heet singleblack.gif.
Het andere plaatje heeft de lichte kleur en heet singlewhite.gif. - Met deze twee plaatjes wordt de schijngestalte van de maan getekend, in "regels" van één pixel hoog. Bij elke regel is de lengte van de horizontale koorde anders. Bij de berekening van die lengte spelen de straal, de parameter size (zie hierboven) en de Stelling van Pythagoras een rol. De breedte van singleblack.gif en singlewhite.gif wordt uiteindelijk ingesteld door het width-attribuut te veranderen en wordt verder nog bepaald door het percentage van de maancyclus dat is voltooid.
- De kleuren van het plaatje kun je eenvoudig veranderen door met een tekenprogramma de kleuren van singleblack.gif en singlewhite.gif aan te passen (met MS-paint gaat het al heel goed).
- Het is mogelijk om in singleblack.gif een transparante achtergrond in te stellen. Dat kan een heel mooi effect
geven op je webpagina, maar rond nieuwe maan is er dan weinig te zien. Even uitproberen dus.
Opmerking:
De maan-cyclus is 29,530589 dagen. Deze is echter niet constant maar varieert een beetje. Daardoor ontstaan onnauwkeurigheden
in de resultaten van dit script, die worden versterkt door de noodzaak om in de berekening getallen af te ronden. De afwijkingen
worden groter als de systeemklok van je PC niet helemaal op tijd loopt.
Een en ander zorgt er voor dat de meldingen over -bijvoorbeeld- het percentage van de maan dat verlicht is kunnen afwijken
van de werkelijkheid. Ook kan de figuur net even iets anders weergeven dan je op grond van de meldingen zou veronderstellen.
De afwijking kan oplopen tot maximaal één etmaal. Als de afwijking structureel fout gaat moet je de variabele
baseDate in regel 18 van maanstand.js veranderen naar een recentere datum en tijd.
Gebruik:
- De code staat gedeeltelijk in de <HEAD> en gedeeltelijk in de <BODY>.
De code ziet er als volgt uit:
(Zet dit in de <HEAD>).
<style>
.moonClass {
float: right;
margin-left: 20px;
padding: 10px;
border-collapse: collapse;
}
.moonCell {
text-align :center;
padding: 0;
font-size: 0;
line-height: 0;
}
.wrapper {
padding: 10px;
border: 1px solid navy;
width: 100%;
}
</style>
<script src="maanstand.js"></script>
(Zet in in de BODY op de plaats waar je het nodig hebt)
<table class="wrapper"><tr>
<td class="Opmerk-g" style="width:70%"><script>showMessages()</script></td>
<td style="width:30%"><script>showMoon('35')</script></td>
</tr></table>
Downloaden:
Druk op de knop:
File: voorb173.zip, 2339 bytes.