Interactie

In dit hoofdstuk ga je leren hoe je in p5.js sketches kan maken die reageren op input van de gebruiker.

Muispositie

p5.js heeft twee heel speciale variabelen, mouseX en mouseY, die de X en Y coordinaten van de muis cursor bevatten van het huidige frame. Als je bedenkt dat de code in draw() continu draait en heel snel: tot zestig keer per seconde. Een stukje code van p5.js dat deel uitmaakt van de library roept continu deze functie aan en iedere keer dat p5.js dat doet wordt de waarde van de mouseX en de mouseY variabelen geupdated met de huidige positie van de cursor op het scherm. De twee variabelen samen maken het heel makkelijk om je sketch te laten reageren op muisbewegingen van de gebruiker.

Hier een simpel voorbeeld dat een cirkel tekent op de positie van de muisaanwijzer:

Natuurlijk kan je mouseX en mouseY niet alleen gebruiken voor de positie van de vormen die je tekent, maar ook voor andere eigenschappen. Hier is een sketch die de mouseX waarde gebruikt voor de lijndikte en de mouseY waarde voor de grootte van de cirkel:

Een klassieke voorbeeld sketch van p5.js is om de background() functie in draw() weg te laten, terwijl je de muispositie variabelen gebruikt. Nu heb je eigenlijk de basis van een tekenprogramma:

We kunnen een wat onvoorspelbaarder tekenprogramma maken door wat veranderingen in tijd in te voeren en wat andere kleine aanpassingen:

Muisklik

p5.js heeft een speciale ingebouwde variabele genaamd mouseIsPressed waar de waarde true is als de gebruiker de muisknop ingedrukt houdt en false als dat niet zo is. Je kan dit gebruiken om je sketch verschillende dingen te laten doen afhankelijk van of de gebruiker de muisknop ingedrukt houdt of niet.

Muissnelheid

Naast mouseX en mouseY zijn er nog twee ingebouwde variabelen voor de muispositie, namelijk pmouseX en pmouseY. De waarde van de pmouseX en de pmouseY variabelen worden ook ieder frame geupdated, niet met de huidige muispositie maar met de vorige muispositie, dwz. de X en Y coördinaten van de muis in het voorlaatste frame. Nu kunnen we door de huidige muispositie te vergelijken met de vorige muispositie de snelheid meten waarmee de muis op dat moment over het scherm beweegt. Hiervoor gebruiken we deze code:

let speed = abs(mouseX - pmouseX) + abs(mouseY - pmouseY)

We trekken de vorige x- en y-positie van de muis af van de huidige x- en y-positie en nemen daarvan mbv. abs() de absolute waarde. Zo zorgen we dat de variabele speed altijd een positief getal is. Dit biedt weer nieuwe mogelijkheden voor je interactieve sketch. In het volgende voorbeeld tekenen we grotere of kleinere cirkels afhankelijk van de muissnelheid:

We kunnen deze sketch nog wat verder verfijnen door de beweging wat vloeiender te maken met behulp van lerp(). Deze functie berekent een getal tussen twee getallen afhankelijk van een stapwaarde tussen 0 en 1.

lerp(100, 200, 0.5) // 150
lerp(100, 200, 0.1) // 110
lerp(100, 200, 0.9) // 190

Door globale variabelen te gebruiken voor de x- en y-positie en deze te "lerpen" naar de muispositie krijgen we een meer vloeiendere animatie:

Ook hebben we hier de constrain() functie gebruikt. Deze functie zorgt dat een getal tussen een minimum en maximumwaarde blijft.

constrain(92, 10, 100); // 92
constrain(4, 10, 100); // 10
constrain(120, 10, 100); // 100

In bovenstaand voorbeeld kan de diameter van de cirkel dus nooit kleiner dan 10 pixels zijn en nooit groter dan 100 pixels.

Interactie en objecten

Laten we nu eens kijken hoe we meerdere vormen interactief kunnen maken. Het volgende voorbeeld gebruikt de ingebouwde functie dist() om de afstand tussen de objecten en de muis te meten - p5js.org/reference/#/p5/dist. De vulkleur is vervolgens afhankelijk gemaakt van de afstand. Hoe dichterbij hoe helderder de kleur van de cirkel:

In het volgende voorbeeld maken we de grootte van de cirkels afhankelijk van de afstand tot de muis:

En nog een wat ingewikkelder voorbeeld. Hier passen we de rotatie van de rechthoeken in een grid aan aan de muispositie. Daarvoor moeten we wel eerst de hoek ten opzichte van de muis berekenen mbv. atan2 - p5js.org/reference/#/p5/atan2. En omdat we gaan roteren gebruiken we translate(), push() en pop().