Effects and Animations

Everything that can be added on a Clip’s timeline is an Incident and as we say in MotorCortex everything is an Incident. The "native" Incidents provided by MotorCortex itself are the Clip, the Group and the Combo which we have already analysed, but how about plugins?
What kind of Incidents do plugins expose?

Plugins can expose three distinct types of Incidents:

  • Effects
  • Animations
  • Custom Clips


Effects are Incidents that animate the attributes' values of selected elements of the context.

All Effects take exactly two arguments on initialisation:

  • attributes
  • properties

Both attributes and properties are of type object.


The attributes that a plugin Effect expects vary from plugin to plugin and from Effect to Effect, depending on the action it executes/represents. Two things are common in all of them though: the animatedAttrs and the (optional) initialValues.

As mentioned, Effects animate the value of elements' attributes. The attributes that the Effect handles and changes are always included on the animatedAttrs key of its attributes. Each key's value represents the final value that the attribute will reach at the end of the Effect (target value).

As an example, by the use of the Anime Plugin, we animate the background and the fontSize of all elements of class ".my-class" to "#000000" and "45px" respectively:

const myEffect = new AnimePlugin.Anime(
animatedAttrs: {
background: "#000000",
fontSize: "45px"
selector: ".my-class",
duration: 1000

The initialValues key (optionally) provides initialValues for the animatedAttrs of the Effect. If no initialValues is provided MotorCortex automatically detects the current value of the animatedAttr and keeps that as its initial value for the animation. Example:

const myEffect = new AnimePlugin.Anime(
animatedAttrs: {
background: "#000000",
fontSize: "45px"
initialValues: {
fontSize: "12px"
selector: ".my-class",
duration: 1000

On the provided example the initialValues key only defines the initial value of the fontSize as background is absent. In this case, when the animation starts, MotorCortex will use the 12px as the initial value of fontSize while it will automatically detect the current value of the background and keep this as the initial value.

Except the animatedAttrs and the initialValues an Effect might expect / accept other keys as well on its attributes. This strongly depends on the implementation of each Effect and thus developers should always consult the plugin's documentation for details.


Unlike attributes, the properties object is standard and the same for all Effects and it supports the following keys:

  • selector: the selector that defines the elements that the Effect should be applied to
  • duration: the duration of the Effect in milliseconds
  • delay: (optional, defaults to 0) if provided add a delay before the Effect execution. Delay is provided in milliseconds
  • repeats: (optional, defaults to 1) if provided it repeats the execution of the Effect as many times as the provided integer
  • hiatus: (optional, defaults to 0) if provided it adds a hiatus after the Effect execution. Hiatus is provided in milliseconds
  • id: (bad practice for production, use just for debugging purposes). The id of the Effect
  • name: Optionally, each Effect can have a name that the user can give for easy reference
  • easing: (optional, defaults to ‘linear’) if provided it sets the easing of the Effect. The supported easings are:
    • 'linear',
    • 'easeInQuad',
    • 'easeOutQuad',
    • 'easeInOutQuad',
    • 'easeInCubic',
    • 'easeOutCubic',
    • 'easeInOutCubic',
    • 'easeInQuart',
    • 'easeOutQuart',
    • 'easeInOutQuart',
    • 'easeInQuint',
    • 'easeOutQuint',
    • 'easeInOutQuint',
    • 'easeInSine',
    • 'easeOutSine',
    • 'easeInOutSine',
    • 'easeInExpo',
    • 'easeOutExpo',
    • 'easeInOutExpo',
    • 'easeInCirc',
    • 'easeOutCirc',
    • 'easeInOutCirc',
    • 'easeInElastic',
    • 'easeOutElastic',
    • 'easeInOutElastic',
    • 'easeInBack',
    • 'easeOutBack',
    • 'easeInOutBack',
    • 'easeInBounce',
    • 'easeOutBounce',
    • 'easeInOutBounce'

These props are standard among all Effects of any plugin, they are handled directly from MotorCortex and no other key out of this list can enter the properties object.


Animations are self-contained, parametric Incidents that accept some parameters and render a full Clip on selected host elements. The concept is that the final users of Animations have absolutely no control over the context and Effects of the them. The only way users can interact with Animations is via parametrisation achieved through the attributes of the Animation.

Long story short, Animations represent fix Clips that accept parameters, render a full Clip on a selected host element and they are positioned on any other Clip's timeline, exactly as any other Incident of the MotorCortex ecosystem.


The attributes that each Animation supports is 100% custom and vary from Animation to Animation and from plugin to plugin. Plugins' documentation always provides useful guidelines on how to use and parametrise them.


The properties that Animations accept are standard. Animations' properties support the following keys:

  • selector: a selector string that defines the elements that the Animation should be rendered to
  • easing: (optional, defaults to ‘linear’) The execution of an Animation, positioned on another Clip's timeline, can be eased by any of the supported easings of MotorCortex
  • containerParams: (optional, object) an object that accepts either 'width', 'height' or both 'width' and 'height'. As all Animations have their original dimensions, via containerParams final users have the chance to alter them by defining their own, desired dimensions
  • name: Optionally, each Animation can have a name that the user can give for easy reference
  • id: (bad practice for production, use just for debugging purposes). A unique id for the Animation


Let's create a Clip that uses both Effects and Animations, from various plugins

// first import MotorCortex
import MotorCortex from "@kissmybutton/motorcortex";
// import @kissmybutton/motorcortex-player player plugin
import Player from "@kissmybutton/motorcortex-player";
// import and load @kissmybutton/motorcortex-anime plugin
import AnimePluginDefinition from "@kissmybutton/motorcortex-anime";
const AnimePlugin = MotorCortex.loadPlugin(AnimePluginDefinition);
// import and load @kissmybutton/motorcortex-animetitles plugin
import AnimeTitlesPluginDefinition from "@kissmybutton/motorcortex-animetitles";
const AnimeTitlesPlugin = MotorCortex.loadPlugin(AnimeTitlesPluginDefinition);
// import and load @kissmybutton/motorcortex-backgrounds plugin
import BackgroundsPluginDefinition from "@kissmybutton/motorcortex-backgrounds";
const BgPlugin = MotorCortex.loadPlugin(BackgroundsPluginDefinition);
// create an HTMLClip
const myClip = new MotorCortex.HTMLClip({
host: document.getElementById("app"),
html: (initParams) => (
<div class="container">
<div class="layer layer-1"></div>
<div class="layer layer-2"></div>
<div class="layer layer-3">
<p>This sample Clip</p>
<p>has three different plugins' Incidents</p>
css: `
background: black;
position: relative;
width: 600px;
height: 400px;
position: absolute;
width: 600px;
height: 400px;
z-index: 1;
z-index: 2;
top: 100px;
z-index: 3;
color: white;
text-align: center;
padding-top: 100px;
font-size: 20px;
.layer-3 p{
font-family: 'Open Sans', sans-serif;
opacity: 0;
fonts: [
type: "google-font",
"https://fonts.googleapis.com/css2?family=Open+Sans:[email protected]&display=swap"
containerParams: {
width: "600px",
height: "400px"
// crate a motorcortex-backgrounds plugin's Incident
// Grid is an Animation
const grid = new BgPlugin.Grid(
width: 600,
height: 400,
color: "#FFF",
columns: 6,
rows: 4,
timing: 2.5
selector: ".layer-1"
// create a motorcortex-animetitles plugin's Incident
// RotatadLineReveal is an Animation
const title1 = new AnimeTitlesPlugin.RotatadLineReveal(
duration: 7500,
width: 600,
size: "M",
lineColor: "#ffff00",
textColor: "#FFF",
title: "Welcome to sample",
subtitle: "animetitles plugin Incident",
leftEnd: 100,
stopOnLast: false,
delayEnd: 200
selector: ".layer-2"
// create a motorcortex-anime Anime Incident
// Anime is an Effect
const opacityIncident = new AnimePlugin.Anime(
animatedAttrs: {
opacity: 1
selector: ".layer-3 p",
duration: 2000,
delay: "@stagger(0, 1000)"
// we add our Incidents on our Clip's timeline
myClip.addIncident(grid, 0);
myClip.addIncident(title1, 1000);
myClip.addIncident(opacityIncident, 7800);
// assign to Player the execution of our Clip
const player = new Player({ clip: myClip });

Result (codesandbox):

This example uses both Effects and Animations from various plugins.

  • Effects
    • motorcortex-anime > Anime is an Effect applied to selected elements of the Clip's context
  • Animations
    • motorcortex-animetitles > RotatadLineReveal
    • motorcortex-backgrounds > Grid