-
Notifications
You must be signed in to change notification settings - Fork 40
Open
Labels
Description
First, this is quite trivial: The animation can easily cache "from" and "to" BlMatrixDecomposition2D
(currently, they are calculated again each step!).
But I think more can be optimized. When a BlElement
has a BlTransformAnimation
, the following steps execute each animation frame:
- The animation sends
interpolate:to:
to that decomposition to create a new temporary decomposition. - The animation creates a temporary
BlMatrix2D
by sendingcomposition
to the decomposition. - The animation creates a temporary
BlElementAbsoluteTransformation
from the matrix, and sets it in the animated element. - The animated element sends
asCachedTransformation
to the transformation to finally obtain aBlElementCachedExplicitTransformation
, that will be used on the new render.
Some involved methods, to be analyzed:
BlMatrixDecomposition2D >>
interpolate: aFactor to: anotherDecomposition
"Algorithm is based on https://drafts.csswg.org/css-transforms/#interpolation-of-decomposed-2d-matrix-values"
| aScaleX aScaleY anAngle anotherAngle |
aScaleX := scale x.
aScaleY := scale y.
anAngle := angle.
anotherAngle := anotherDecomposition angle.
((aScaleX < 0 and: [ anotherDecomposition scale y < 0 ]) or:
[ aScaleY < 0 and: [ anotherDecomposition scale x < 0 ] ])
ifTrue: [
aScaleX := aScaleX negated.
aScaleY := aScaleY negated.
anAngle := anAngle < 0
ifTrue: [ anAngle + 180 ]
ifFalse: [ anAngle - 180 ] ].
"Don't rotate the long way around."
anAngle isZero ifTrue: [ anAngle := 360 ].
anotherAngle isZero ifTrue: [ anotherAngle := 360 ].
(anAngle - anotherAngle) abs > 180 ifTrue: [
anAngle > anotherAngle
ifTrue: [ anAngle := anAngle - 360 ]
ifFalse: [ anotherAngle := anotherAngle - 360 ] ].
"Interpolate all values."
^ BlMatrixDecomposition2D new
translation: translation + ((anotherDecomposition translation - translation) * aFactor);
scale: scale + ((anotherDecomposition scale - (BlVector x: aScaleX y: aScaleY)) * aFactor);
angle: anAngle + ((anotherAngle - anAngle) * aFactor);
sx: sx + ((anotherDecomposition sx - sx) * aFactor);
sy: sy + ((anotherDecomposition sy - sy) * aFactor);
shx: shx + ((anotherDecomposition shx - shx) * aFactor);
shy: shy + ((anotherDecomposition shy - shy) * aFactor);
yourself
BlMatrixDecomposition2D >>
composition
| aMatrix |
aMatrix := BlMatrix2D new.
aMatrix sx: sx.
aMatrix sy: sy.
aMatrix shx: shx.
aMatrix shy: shy.
"Translate matrix"
aMatrix x: (translation x * aMatrix sx) + (translation y * aMatrix shx).
aMatrix y: (translation x * aMatrix shy) + (translation y * aMatrix sy).
"Rotate matrix"
aMatrix := (BlMatrix2D rotation: angle degreesToRadians) multiplyBy: aMatrix.
"Scale matrix."
aMatrix sx: aMatrix sx * scale x.
aMatrix shy: aMatrix shy * scale x.
aMatrix shx: aMatrix shx * scale y.
aMatrix sy: aMatrix sy * scale y.
^ aMatrix