Effects
Effects are Incidents that tween the attributes' values of selected elements of the context. Before writing your first Effect let’s have a look at some internals that will help you nail it.
As you most probably already know as a MotorCortex user, all Effects take a “selector” on their props which defines the elements of the context that it should be applied to. Also, on all Effects’ attrs there is a special key with the name “animatedAttrs”, which is an object holding all attributes that should be tweened and their final values.
The most characteristic example of Effect is the built-in CSSEffect of MotorCortex. Let's examine the way this Effect works under the hood as it's identical with the way any other (plugin) Effect works.
const myEffect = new CSSEffect(
{
// attrs
animatedAttrs: {
width: "600px",
top: "30px",
},
},
{
// props
selector: ".class-a",
duration: 2000,
}
);
This Effect will change the value of “width” and “top” of each element of the class “.class-a” until it reaches the final values (600px and 30px respectively). That’s the concept. Let’s see how it’s done.
The moment the Incident enters the Clip it automatically (and internally) gets dissolved into smaller pieces up until it reaches the point where the initial Incident has been analysed to Incidents of a single element and a single attribute (we call them Mono-Incidents). The final number of Mono-Incidents that will be produced is the product: numberOfAnimatedAttrs * numberOfElements. For example, continuing with our example, if we have three elements of the class “.class-a” then we will have 6 in total MonoIncidents created internally on MotorCortex:
- First element / width
- First element / top
- Second element / width
- Second element / top
- Third element / width
- Thrid element / top
When extending MotorCortex.Effect you are actually coding the mono-Incident that will be internally produced by MotorCortex.
MotorCortex.Effect offers the following properties (which you can use on your code), out of the box:
- element: the element that the Incident will be applied to
- attributeKey: the attribute name that will be animated (this will either be “top” or “width” in our example, depending on which of the six MonoIncidents runs at the time)
- targetValue: the value of the animated attribute to be animated (e.g. “600px” or “30px”). Even if the final user uses dynamic values of its attributes (e.g. “@stagger” or “@expression”), the targetValue here will always be a specific, already calculated by MC value
- selector: a selector string that only returns this.element
- initialValue: the initial value of the animated attribute (you don’t care where this comes from. As a Plugin Developer you only know that MotorCortex has this calculated for you at all times)
Effect has also the following methods:
- onGetContext
- getScratchValue
- onProgress which you should overwrite in order to define your own Effect.
onGetContext
On instantiation of an Effect, the Effect doesn’t yet belong to a Clip and thus has no context. Once the Incident enters a Clip it gains context, and that's when it gets dissolved to its MonoIncidents.
onGetContext runs when the MonoIncident you coded gains context. This is a great place to configure or even completely craft your tween. Full access to this.element, this.targetValue, this.initialValue and to all the other properties listed beyond is available here.
getScratchValue
As mentioned MotorCortex provides the “initialValue” property on MonoIncidents, which always has the calculated initial value of the attribute. The initial value of an attribute is calculated by MotorCortex by the following, hierarchy ordered ways:
- From the user’s “initialValues” (if provided)
- From the final value of the previous MonoIncident on the same element and on the same attribute, and...
- If this is the very first MonoIncident of the specific element-attribute pair, from the getScratchValue method of the MonoIncident.
Effects are multi-purpose and MotorCortex can’t and doesn't know this value. Only the MonoIncident developer can define that by overriding the “getScratchValue” method and return the “scratch value” for the specific element and for the specific attribute.
For example, for the implementation of the CSSEffect the getScratchValue method returns the value of the css property (attributeKey) from window.getComputedStyle.
onProgress
Action time! onProgress gets the milliseconds argument:
- milliseconds (the milliseconds passed within the Incident) MonoIncident Developers can, here, affect their MonoIncident’s element in any way they want
If the developer needs to know the fraction (from 0 to 1) they can use the this.getFraction
method
passing the millisecond.
What you don't need to care about
We listed all props and methods you should care about when developing an Effect. Here is a list of things you don’t care about at all, as are handled directly by MotorCortex:
- repeats
- delay
- hiatus
- easing
- duration
Examples
Two good examples of plugins exposing Effects are: