Mathe vor Ostern: Easing
bearbeitet von Rolf BHallo,
easing-Funktionen sind ja etwas, das die diversen Animationstools von Haus aus mitbringen.
Es ist aber nicht so einfach, wenn man bspw. mit SVG einen Pfeil animieren möchte, der von Länge 0 entlang eines Pfades wächst und dessen Pfeilspitze beim Wachsen mitläuft (und natürlich dabei in die richtige Richtung zeigt).
Das Problem "Pfeilspitze" ist gut machbar, akt. Punkt und letzten Punkt nehmen, Differenz, Math.atan2 und man hat die Richtung. Das mit SVG um den richtigen Punkt zu drehen ist nochmal ein bisschen Drama, aber geht auch.
Aber nun. Ich habe einen Path für den Pfeil.
"M410,580 A100,40,0 0 1 310,620 A290,420,0 0 1 020,200"
So ein Schnörkel untenrum und dann nach links oben weg.
[So was hier...](http://www.borchmann.one/test/animationspline.html) - mit Space die Animation starten.
Mit `getTotalLength()` komm ich an die Länge L dieses Pfades ran. Und mit `getPointAtLength(l)` bekomm ich die Koordinaten des Punktes an der Stelle `l` auf dem Pfad. Wollte ich also meinen Pfeil mit linearem Tempo wachsen lassen, würde ich einfach in requestAnimationFrame Dreisatz machen und zum Zeitpunkt t der Animationsdauer d rechnen: $$\displaystyle l = \frac{t}{d}\cdot L$$
Aber ich möchte nicht linear. Ich möchte ein ease-in-out Verhalten. Ich könnte die h10-Funktion der [Kubisch-Hermiteschen Splines](https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline) verwenden, die macht ein **bisschen** ease-in-out. Aber ich will den Effekt stärker, und ich hätt's auch gern konfigurierbar.
Meine aktuelle Lösung ist ein Spline von (0,0) nach (d,L), mit Richtungsvektoren (2d,0) vorn und hinten für einen symmetrischen ease-in-out. Dieser Spline modelliert die gewünschte Timing-Kurve, nicht etwa den Pfeilverlauf.
Problem dabei: Parameter der Spline-Funktion ist t - und zwar nicht mein t, sondern ein Wert im Intervall $$[0, 1]$$, mit dem man alle x- und y-Koordinaten auf der Splinekurve bekommt.
Ich muss also die kubische Funktion $$S_x(t)$$, die mir die X-Koordinate der Splinekurve liefert, umkehren, um t zu erhalten, und bekomme dann über $$S_y(t)$$ das y. Setzt natürlich voraus, dass der Spline eine Funktion und keine Relation ist - wenn die Richtungsvektoren zu lang werden, läuft so ein Ding ja auch mal rückwärts oder dreht ein Löckchen. Aber das ist dann GIGO[^1].
[^1]: Garbage In, Garbage Out
Ich mache also eine Nullstellensuche für die Funktion $$S_x$$ mit Intervallhalbierung über $$t \in [0,1]$$, um das passende t zum x zu finden. Und kriege ein y. Sieht auch am Ende gar nicht so schlecht aus.
Aber - BOAH EY - ist das ein umständliches Vorgehen…
Ich würde lieber mit Spatzen auf Kanonen schießen als umgekehrt. Gibt's dafür eine elegantere Lösung? Kann SVG/SMIL sowas vielleicht sogar von Hause aus und ich breche mir die Finger ab für nichts?
_Rolf_
Mathe vor Ostern: Easing
bearbeitet von Rolf BHallo,
easing-Funktionen sind ja etwas, das die diversen Animationstools von Haus aus mitbringen.
Es ist aber nicht so einfach, wenn man bspw. mit SVG einen Pfeil animieren möchte, der von Länge 0 entlang eines Pfades wächst und dessen Pfeilspitze beim Wachsen mitläuft (und natürlich dabei in die richtige Richtung zeigt).
Das Problem "Pfeilspitze" ist gut machbar, akt. Punkt und letzten Punkt nehmen, Differenz, Math.atan2 und man hat die Richtung. Das mit SVG um den richtigen Punkt zu drehen ist nochmal ein bisschen Drama, aber geht auch.
Aber nun. Ich habe einen Path für den Pfeil.
"M410,580 A100,40,0 0 1 310,620 A290,420,0 0 1 020,200"
So ein Schnörkel untenrum und dann nach links oben weg.
[So was hier...](http://www.borchmann.one/test/animationspline.html) - mit Space die Animation starten.
Mit `getTotalLength()` komm ich an die Länge L dieses Pfades ran. Und mit `getPointAtLength(l)` bekomm ich die Koordinaten des Punktes an der Stelle `l` auf dem Pfad. Wollte ich also meinen Pfeil mit linearem Tempo wachsen lassen, würde ich einfach in requestAnimationFrame Dreisatz machen und zum Zeitpunkt t der Animationsdauer d rechnen: $$\displaystyle l = \frac{t}{d}\cdot L$$
Aber ich möchte nicht linear. Ich möchte ein ease-in-out Verhalten. Ich könnte die h10-Funktion der [Kubisch-Hermiteschen Splines](https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline) verwenden, die macht ein **bisschen** ease-in-out. Aber ich will den Effekt stärker, und ich hätt's auch gern konfigurierbar.
Meine aktuelle Lösung ist ein Spline von (0,0) nach (d,L), mit Richtungsvektoren (2d,0) vorn und hinten für einen symmetrischen ease-in-out.
Problem dabei: Parameter der Spline-Funktion ist t - und zwar nicht mein t, sondern ein Wert im Intervall $$[0, 1]$$, mit dem man alle x- und y-Koordinaten auf der Splinekurve bekommt.
Ich muss also die kubische Funktion $$S_x(t)$$, die mir die X-Koordinate der Splinekurve liefert, umkehren, um t zu erhalten, und bekomme dann über $$S_y(t)$$ das y. Setzt natürlich voraus, dass der Spline eine Funktion und keine Relation ist - wenn die Richtungsvektoren zu lang werden, läuft so ein Ding ja auch mal rückwärts oder dreht ein Löckchen. Aber das ist dann GIGO[^1].
[^1]: Garbage In, Garbage Out
Ich mache also eine Nullstellensuche für die Funktion $$S_x$$ mit Intervallhalbierung über $$t \in [0,1]$$, um das passende t zum x zu finden. Und kriege ein y. Sieht auch am Ende gar nicht so schlecht aus.
Aber - BOAH EY - ist das ein umständliches Vorgehen…
Ich würde lieber mit Spatzen auf Kanonen schießen als umgekehrt. Gibt's dafür eine elegantere Lösung? Kann SVG/SMIL sowas vielleicht sogar von Hause aus und ich breche mir die Finger ab für nichts?
_Rolf_
Mathe vor Ostern: Easing
bearbeitet von Rolf BHallo,
easing-Funktionen sind ja etwas, das die diversen Animationstools von Haus aus mitbringen.
Es ist aber nicht so einfach, wenn man bspw. mit SVG einen Pfeil animieren möchte, der von Länge 0 entlang eines Pfades wächst und dessen Pfeilspitze beim Wachsen mitläuft (und natürlich dabei in die richtige Richtung zeigt).
Das Problem "Pfeilspitze" ist gut machbar, akt. Punkt und letzten Punkt nehmen, Differenz, Math.atan2 und man hat die Richtung. Das mit SVG um den richtigen Punkt zu drehen ist nochmal ein bisschen Drama, aber geht auch.
Aber nun. Ich habe einen Path für den Pfeil.
"M410,580 A100,40,0 0 1 310,620 A290,420,0 0 1 020,200"
So ein Schnörkel untenrum und dann nach links oben weg.
Mit `getTotalLength()` komm ich an die Länge L dieses Pfades ran. Und mit `getPointAtLength(l)` bekomm ich die Koordinaten des Punktes an der Stelle `l` auf dem Pfad. Wollte ich also meinen Pfeil mit linearem Tempo wachsen lassen, würde ich einfach in requestAnimationFrame Dreisatz machen und zum Zeitpunkt t der Animationsdauer d rechnen: $$\displaystyle l = \frac{t}{d}\cdot L$$
Aber ich möchte nicht linear. Ich möchte ein ease-in-out Verhalten. Ich könnte die h10-Funktion der [Kubisch-Hermiteschen Splines](https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline) verwenden, die macht ein **bisschen** ease-in-out. Aber ich will den Effekt stärker, und ich hätt's auch gern konfigurierbar.
Meine aktuelle Lösung ist ein Spline von (0,0) nach (d,L), mit Richtungsvektoren (2d,0) vorn und hinten für einen symmetrischen ease-in-out.
Problem dabei: Parameter der Spline-Funktion ist t - und zwar nicht mein t, sondern ein Wert im Intervall $$[0, 1]$$, mit dem man alle x- und y-Koordinaten auf der Splinekurve bekommt.
Ich muss also die kubische Funktion $$S_x(t)$$, die mir die X-Koordinate der Splinekurve liefert, umkehren, um t zu erhalten, und bekomme dann über $$S_y(t)$$ das y. Setzt natürlich voraus, dass der Spline eine Funktion und keine Relation ist - wenn die Richtungsvektoren zu lang werden, läuft so ein Ding ja auch mal rückwärts oder dreht ein Löckchen. Aber das ist dann GIGO[^1].
[^1]: Garbage In, Garbage Out
Ich mache also eine Nullstellensuche für die Funktion $$S_x$$ mit Intervallhalbierung über $$t \in [0,1]$$, um das passende t zum x zu finden. Und kriege ein y. Sieht auch am Ende gar nicht so schlecht aus.
Aber - BOAH EY - ist das ein umständliches Vorgehen…
Ich würde lieber mit Spatzen auf Kanonen schießen als umgekehrt. Gibt's dafür eine elegantere Lösung? Kann SVG/SMIL sowas vielleicht sogar von Hause aus und ich breche mir die Finger ab für nichts?
[Visuelles Ergebnis bisher](http://www.borchmann.one/test/animationspline.html) - mit Space geht's los.
_Rolf_