Easing-functies zijn wiskundige transformaties die lineaire invoerwaarden omzetten in niet-lineaire uitvoerwaarden, en daarmee fundamenteel veranderen hoe waarden zich ontwikkelen van een begin- naar een eindtoestand. Hoewel ze vaak worden geassocieerd met animatietiming, zijn deze functies essentiële tools in generatieve kunst om elke parameter te sturen die over een domein verandert—of dat domein nu tijd, ruimte of een andere continue variabele is.
Lineaire vs. niet-lineaire interpolatie
Lineaire interpolatie (lerp) levert een constante veranderingssnelheid op. Gegeven een genormaliseerde invoer t tussen 0 en 1, geeft lineaire interpolatie simpelweg t terug. De output verloopt in een gelijkmatig tempo en creëert mechanische, voorspelbare beweging die voor menselijke waarneming vaak onnatuurlijk aanvoelt.
Niet-lineaire easing-functies veranderen deze relatie door wiskundige curves toe te passen op de invoerwaarde. Een easing-functie neemt een genormaliseerde tijdwaarde t (meestal 0 tot 1) en geeft een aangepaste voortgangswaarde terug, eveneens doorgaans in het bereik 0 tot 1. Deze transformatie creëert versnelling, vertraging of complexere bewegingspatronen die natuurlijke fysica benaderen en organischer aanvoelen.
Veelvoorkomende soorten easing
Easing-functies worden meestal ingedeeld op basis van hun versnellingskarakteristieken, die bepalen hoe de veranderingssnelheid zich ontwikkelt over het invoerdomein.
Ease-in
Ease-in-functies beginnen langzaam en versnellen naar het einde toe. De afgeleide van de functie neemt toe naarmate t 1 nadert. Deze functies creëren een gevoel van opbouwende momentum, bruikbaar voor objecten die vanuit stilstand starten of waarden die uit een basisniveau tevoorschijn komen.
Ease-out
Ease-out-functies beginnen snel en vertragen naar het einde toe. De afgeleide neemt af naarmate t 1 nadert. Ze creëren een uitdempend effect, alsof een object tot rust komt of een waarde haar eindtoestand nadert met afnemende energie.
Ease-in-out
Ease-in-out-functies combineren beide gedragingen: ze versnellen in de eerste helft en vertragen in de tweede helft. Ze zorgen voor vloeiende, symmetrische overgangen die gebalanceerd en natuurlijk aanvoelen, en zijn bijzonder effectief voor cyclische of omkeerbare bewegingen.
Wiskundige formuleringen
Verschillende wiskundige functies leveren uiteenlopende easing-curves op, elk met karakteristieke acceleratieprofielen en esthetische kwaliteiten.
Polynomiale easing
Polynomiale functies verheffen de input tot een macht en creëren zo vloeiende curves met beheersbare steilheid. Kwadratisch (t²), kubisch (t³), quartisch (t⁴) en kwintisch (t⁵) zijn gangbare keuzes. Hogere machten zorgen voor dramatischere acceleratiecurves, met langere periodes van trage verandering gevolgd door snelle overgangen.
// Quadratic ease-in
const easeInQuad = t => t * t;
// Cubic ease-in
const easeInCubic = t => t * t * t;
// Quartic ease-in
const easeInQuart = t => t * t * t * t;
// Generic polynomial ease-in
const easeInPower = (t, power) => Math.pow(t, power);Sine-gebaseerde easing
Goniometrische functies leveren vloeiende, golfachtige easing-curves op. Sine-gebaseerde easing creëert een zachte acceleratie en vertraging die bijzonder organisch aanvoelt. Deze functies zijn afgeleid van delen van de sinusgolf, meestal in het bereik van -π/2 tot π/2 of 0 tot π.
// Sine ease-in
const easeInSine = t => 1 - Math.cos((t * Math.PI) / 2);
// Sine ease-out
const easeOutSine = t => Math.sin((t * Math.PI) / 2);
// Sine ease-in-out
const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;Exponentiële easing
Exponentiële functies creëren dramatische acceleratiecurves met zeer trage starts of eindes. Ze zijn gebaseerd op machten van 2 en produceren de meest extreme easing-effecten, nuttig wanneer je een sterk contrast nodig hebt tussen langzame en snelle fasen van verandering.
// Exponential ease-in
const easeInExpo = t => t === 0 ? 0 : Math.pow(2, 10 * (t - 1));
// Exponential ease-out
const easeOutExpo = t => t === 1 ? 1 : 1 - Math.pow(2, -10 * t);
// Exponential ease-in-out
const easeInOutExpo = t => {
if (t === 0) return 0;
if (t === 1) return 1;
if (t < 0.5) return Math.pow(2, 20 * t - 10) / 2;
return (2 - Math.pow(2, -20 * t + 10)) / 2;
};Circulaire easing
Circulaire easing is afgeleid van de vergelijking van een cirkel (x² + y² = 1) en creëert vloeiende curves met een matige acceleratie. Deze functies leveren easing op die qua intensiteit tussen polynomiaal en exponentieel in ligt.
// Circular ease-in
const easeInCirc = t => 1 - Math.sqrt(1 - t * t);
// Circular ease-out
const easeOutCirc = t => Math.sqrt(1 - Math.pow(t - 1, 2));
// Circular ease-in-out
const easeInOutCirc = t => {
if (t < 0.5) return (1 - Math.sqrt(1 - 4 * t * t)) / 2;
return (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2;
};Toepassingen buiten animatie
Hoewel easing-functies hun oorsprong hebben in animatiecontexten, zijn het krachtige tools voor elke generatieve kunsttoepassing waarbij parameterinterpolatie of ruimtelijke distributie een rol speelt.
Gradientgeneratie
Easing-functies transformeren lineaire gradients in perceptueel rijkere kleurovergangen. Door een easing-functie toe te passen op de positieparameter van de gradient kun je gradients maken die in bepaalde kleurgebieden blijven hangen en door andere zones juist snel heen bewegen. Dit is vooral effectief om focuspunten te creëren of specifieke tinten in een kleurverloop te benadrukken.
function createEasedGradient(ctx, x0, y0, x1, y1, color1, color2, easeFn) {
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
// Sample the gradient with easing
const steps = 20;
for (let i = 0; i <= steps; i++) {
const t = i / steps;
const easedT = easeFn(t);
const color = lerpColor(color1, color2, easedT);
gradient.addColorStop(t, color);
}
return gradient;
}Radiale gradients profiteren nog sterker van easing, omdat de niet-lineaire verdeling een natuurlijker ogende lichtafval of atmosferische effecten kan creëren die echte belichting en diepte nabootsen.
Ruimtelijke distributie
Bij het verdelen van elementen in de ruimte—of het nu om deeltjes, vormen of rasterpunten gaat—bepalen easing-functies de dichtheid en clustering. Lineaire spreiding zorgt voor een uniforme verdeling, maar met eased spreiding kun je elementen concentreren in specifieke gebieden terwijl de overgangen toch vloeiend blijven.
// Distribute points with easing for non-uniform density
function distributePoints(count, start, end, easeFn) {
const points = [];
for (let i = 0; i < count; i++) {
const t = i / (count - 1);
const easedT = easeFn(t);
const position = start + (end - start) * easedT;
points.push(position);
}
return points;
}
// Example: concentrate points toward the end
const points = distributePoints(50, 0, 800, easeInQuad);Deze techniek is van onschatbare waarde voor het creëren van visuele hiërarchieën, het sturen van de blik van de toeschouwer, of het simuleren van natuurlijke fenomenen zoals gravitationele clustering of atmosferische dichtheidsgradients.
Parametermapping
Elke parameter die over een domein varieert, kan profiteren van easing. Grootteverlopen, opacity-curves, rotatiehoeken, lijndiktes en noise-amplitudes worden allemaal expressiever wanneer ze worden aangestuurd door easing-functies. De kerninzichten is dat easing-functies domeinonafhankelijk zijn—ze transformeren simpelweg het ene continue bereik in een ander, met een specifiek acceleratieprofiel.
Noise-modulatie
Easing-functies kunnen noise-functies moduleren om gebieden met variërende turbulentie of detail te creëren. Door een eased waarde te gebruiken om de amplitude of frequentie van noise te sturen, kun je vloeiende overgangen maken tussen kalme en chaotische regio’s, of tussen fijne en grove detailniveaus.
// Vary noise amplitude across space using easing
function easedNoise(x, y, width, easeFn) {
const t = x / width;
const easedT = easeFn(t);
const amplitude = easedT * 100;
return noise(x * 0.01, y * 0.01) * amplitude;
}Implementatie-overwegingen
Bij het implementeren van easing-functies in generatieve kunstsystemen duiken verschillende praktische aandachtspunten op. Performance is zelden een probleem voor standaard easing-functies, omdat ze slechts eenvoudige wiskundige operaties gebruiken. Maar als je easing toepast op duizenden elementen of in real-time rendering, is het zinvol om eased waarden vooraf te berekenen in lookup-tables.
Domeinmapping vraagt om aandacht voor randgevallen. Zorg dat je easing-functies t = 0 en t = 1 correct afhandelen, en waar nodig exact 0 en 1 teruggeven. Sommige exponentiële en circulaire functies vereisen speciale behandeling aan deze grenzen om numerieke instabiliteit te voorkomen.
Omkeerbaarheid is vaak nuttig. Veel generatieve systemen profiteren ervan als een easing-functie omkeerbaar is – zodat je van een ge-easede waarde terug kunt naar de oorspronkelijke lineaire waarde. Dit is eenvoudig voor simpele polynoomfuncties, maar kan numerieke methoden vereisen voor complexere curves.
Esthetische impact
De keuze van easing-functie beïnvloedt het esthetische karakter van generatief werk op een diepgaande manier. Lineaire interpolatie levert mechanische, voorspelbare resultaten op die koud of computationeel kunnen aanvoelen. Zachte easing (sine, laagwaardige polynoom) creëert organische, vloeiende composities die natuurlijk en harmonieus aanvoelen. Agressieve easing (exponential, hoogwaardige polynoom) zorgt voor dramatische, opvallende effecten met sterk contrast tussen gebieden.
De richting van easing is net zo belangrijk als de intensiteit. Ease-in creëert anticipatie en opbouw, en trekt het oog naar de bestemming. Ease-out zorgt voor ontlading en verstilling, en legt de nadruk op het startpunt. Ease-in-out creëert balans en symmetrie, geschikt voor composities zonder duidelijke richting.
Easing-functies begrijpen als algemene interpolatietools – niet alleen als animatiehulpmiddelen – opent enorme creatieve mogelijkheden in generatieve kunst. Het zijn fundamentele bouwstenen om te bepalen hoe elke parameter verandert over elk domein, waardoor kunstenaars precieze perceptuele ervaringen kunnen vormgeven en de aandacht van de kijker kunnen sturen met wiskundige elegantie.
