Optional
Readonly
defaultDefault configuration options that are appropriate for the effect (and can be overwritten while calling the clip factory function). This makes it convenient to rely on some preset behaviors that make sense without having to set them in a clip factory function.
When creating custom effects, the configuration options that you are allowed to set here may be limited by the AnimClip
value for AnimClip.categoryImmutableConfig (which you cannot modify). For example, for exit animation clips,
ExitClip.categoryImmutableConfig sets a value for commitsStyles
, so you cannot set a value for commitsStyles
in
defaultConfig for any entries in the exit effects bank.
const clipFactories = webchalk.createAnimationClipFactories({
customEntranceEffects: {
// Element fades in, starting from 0 opacity.
fadeIn: {
composeEffect() {
return {
forwardKeyframesGenerator: () => {
return [ {opacity: '0'}, {} ];
},
} as const;
},
},
fadeIn_default: {
composeEffect() {
return {forwardKeyframesGenerator: () => {
return [ {opacity: '0'}, {} ];
},
} as const;
},
defaultConfig: {
duration: 2000,
},
},
}
});
// select element from DOM
const element = document.querySelector('.some-element');
const ent1 = clipFactories.Entrance(element, 'fadeIn', [], {});
// ↑ duration will be set to whatever the default duration is for all
// EntranceClip objects
const ent2 = clipFactories.Entrance(element, 'fadeIn_default', [], {});
// ↑ duration will be set to 2000 because that is what was specified in
// the 'fadeIn_default' effect definition
const ent3 = clipFactories.Entrance(element, 'fadeIn_default', [], {duration: 1000});
// ↑ duration will be set to 1000 because configuration settings set in the
// clip factory function call will overwrite any default settings
Optional
Readonly
immutableImmutable configuration options for the effect that are appropriate for the effect (but cannot be overwritten while calling the clip factory function). This makes it possible to set in stone some expected behaviors of clips that use certain effects.
When creating custom effects, the configuration options that you are allowed to set here may be limited by the AnimClip
value for AnimClip.categoryImmutableConfig (which you cannot modify). For example, for exit animation clips,
ExitClip.categoryImmutableConfig sets a value for commitsStyles
, so you cannot set a value for commitsStyles
in
immutableConfig for any entries in the exit effects bank.
const clipFactories = webchalk.createAnimationClipFactories({
customEntranceEffects: {
appear: {
composeEffect() {
return {
forwardKeyframesGenerator: () => {
return [];
},
};
},
},
appear_immutable: {
composeEffect() {
return {
forwardKeyframesGenerator: () => {
return [];
},
};
},
immutableConfig: {
duration: 0,
easing: 'linear',
composite: 'replace',
},
},
}
});
// select element from DOM
const element = document.querySelector('.some-element');
const ent1 = clipFactories.Entrance(element, 'appear', [], {duration: 1000});
// ↑ no issues
const ent2 = clipFactories.Entrance(element, 'appear_immutable', [], {endDelay: 1000});
// ↑ no issues (there is no immutable setting on endDelay for 'appear_immutable')
const ent3 = clipFactories.Entrance(element, 'appear_immutable', [], {duration: 1000});
// ↑ TypeScript compiler error will be thrown because duration is not allowed to be set
// when using the 'appear_immutable' effect. When running the code, this duration will
// simply be ignored in favor of the immutable duration setting.
Optional
Readonly
effectDetermines how frequently the effect will be composed (i.e., how often composeEffect will be run). SUGGESTION: Read the documentation for composeEffect first.
on-first-play-only
, composeEffect will run the first time
play()
is called and never again. The one ComposedEffect object's functions and the closure created during the one call to
composeEffect will be used for the clip's entire lifetime.
on-first-play-only
when code in the closure of composeEffect
only needs to (or perhaps must only) run once for the returned generators to be correct.on-every-play
, composeEffect will run every time
the clip plays forward, which creates a new closure and returns a new ComposedEffect each time.// global variable that will be used in the fadeOut_exclusive effect.
let usedFadeOutEx = false;
const clipFactories = webchalk.createAnimationClipFactories({
customExitEffects: {
// A custom effect you wrote for fading an element out.
// Here, it makes no difference what effectCompositionFrequency is set to.
//
// - If set to 'on-first-play-only', then composeEffect() will run only once
// (on the first play()). Thus, forwardKeyframesGenerator() is defined
// only once and is set to return [{}, {opacity: 0}].
//
// - If set to 'on-every-play', then EVERY time the clip
// plays, composeEffect() plays. Thus, forwardKeyframesGenerator()
// will keep being redefined and set to be a function that
// returns [{}, {opacity: 0}]. It made no difference because
// the body of forwardKeyframesGenerator() remains the same.
//
// Thus, it makes no difference what effectCompositionFrequency is set to.
// For the sake of optimization, you decide to set it to 'on-first-play-only'
// (which is the default value anyway, but it adds more clarity).
fadeOut: {
composeEffect() {
return {
forwardKeyframesGenerator: () => {
return [{}, {opacity: 0}];
},
};
},
effectCompositionFrequency: 'on-first-play-only',
},
// A custom animation effect you made that can only be used by one animation clip
// (Why you would ever do something this is unclear, but the reason does not matter.)
// Here, effectCompositionFrequency must be set to 'on-first-play-only'.
//
// - If set to 'on-first-play-only', then the global variable usedFadeOutEx is
// checked for truthiness and then set to true on the first (and only) running of
// composeEffect(). On subsequent calls to play(), composeEffect() does not re-run, so
// the if-condition is not run again. However, any OTHER clip that uses the fadeOut_exclusive
// effect will fail on their first play() because they need to run composeEffect() for
// the first time and will throw the error (because usedFadeOutEx is already set to true).
// This is the desired behavior.
//
// - If set to 'on-every-play', then composeEffect() will run on every play(). Thus,
// playing the same clip twice will always cause an error because it will run into
// the if-conditional again after usedFadeOutEx is already set to true, which is
// NOT the desired behavior.
//
// The difference is that 'on-first-play-only' causes the if-conditional to run
// only once, while 'on-every-play' causes it to be encountered a second time.
fadeOut_exclusive: {
composeEffect() {
if (usedFadeOutEx) {
throw new Error(`Only one clip is allowed to use the 'fadeOut_exclusive' effect.`);
}
usedFadeOutEx = true;
return {
forwardKeyframesGenerator: () => {
return [ {}, {opacity: 0} ];
},
};
},
effectCompositionFrequency: 'on-first-play-only',
},
// A custom animation effect you made for flying out to the left side of the screen.
// Here, it makes no difference what effectCompositionFrequency is set to.
//
// - If set to 'on-first-play-only', then composeEffect() will run only once. Thus,
// forwardKeyframesGenerator() is defined only once, and the closure containing
// computeTranslationStr() will also only be made once. On every play(),
// forwardKeyframesGenerator() uses computeTranslationStr() to compute
// the translation, so the translation will always be recomputed.
// This is the desired behavior.
//
// - If set to 'on-every-play', then every time play() is called to play the clip,
// composeEffect() is called again, creating a new closure containing a function
// called computeTranslationStr() and returning a new forwardKeyframesGenerator()
// that uses computeTranslationStr() to compute the translation. It makes no
// difference since the bodies of computeTranslationStr() and
// forwardKeyframesGenerator() remain the same, so this is functionally the
// same as the previous paragraph.
// This is the desired behavior.
//
// Thus, it makes no difference what effectCompositionFrequency is set to.
// For the sake of optimization, you decide to set it to 'on-first-play-only'.
flyOutLeft1: {
composeEffect() {
const computeTranslationStr = () => {
// compute distance between right side of element and left side of viewport
const orthogonalDistance = -(this.domElem.getBoundingClientRect().right);
// create translation string
const translationString = `${orthogonalDistance}px 0px`;
return translationString;
}
return {
forwardKeyframesGenerator: () => {
return [
{translate: computeTranslationStr()}
];
},
// backwardKeyframesGenerator could have been omitted, but for ease of
// visual understanding, they are kept for the flyOut effects
backwardKeyframesGenerator: () => {
return [
{translate: computeTranslationStr()},
{translate: `0 0`}
];
}
};
},
immutableConfig: {
composite: 'accumulate',
},
effectCompositionFrequency: 'on-first-play-only',
},
// A custom animation effect for flying out either left or right (random).
// Here, effectCompositionFrequency must be set to 'on-every-play'.
//
// - If set to 'on-first-play-only', then leftOrRight is defined only once. Thus,
// once the clip plays for the first time, leftOrRight will be permanently set
// to 'go left' or 'go right' within the closure created by composeEffect(),
// so the element's direction will not be randomized each time.
// This is NOT the desired effect.
//
// - If set to 'on-every-play', then every time play() is called to play the clip,
// composeEffect() is called again. The variable leftOrRight is thus recomputed, so
// the result of computeTranslationStr() will be randomly left or right every time
// the clip is played.
// This is the desired behavior.
//
// The difference is that 'on-every-play' causes the effect to use a fresh
// leftOrRight on each play, while 'on-first-play-only' does not.
flyOutRandom: {
composeEffect() {
// 50% change of going left or right
const leftOrRight = Math.random() < 0.5 ? 'go left' : 'go right';
const computeTranslationStr = () => {
// compute distance between right side of element and left side of viewport
const distGoingLeft = -(this.domElem.getBoundingClientRect().right);
// compute distance between left side of element and right side of viewport
const distGoingRight = window.innerWidth - this.domElem.getBoundingClientRect().left;
// choose distance based on leftOrRight
const orthogonalDistance = leftOrRight === 'go left' ? distGoingLeft : distGoingRight;
// create translation string
const translationString = `${orthogonalDistance}px 0px`;
return translationString;
}
return {
forwardKeyframesGenerator: () => {
return [
{translate: computeTranslationStr()}
];
},
backwardKeyframesGenerator: () => {
return [
{translate: computeTranslationStr()},
{translate: `0 0`}
];
}
};
},
immutableConfig: {
composite: 'accumulate',
},
effectCompositionFrequency: 'on-every-play',
},
}
});
Readonly
composeRuns when the clip is played and returns a ComposedEffect, which contains callback functions that will produce the effects for both playing and rewinding the animation.
Rest
...effectOptions: unknown[]parameters used to set the behavior for the specific animation effect when calling the clip factory function
An object containing 4 possible callback functions that return Keyframes and/or Mutator.
Overview
Whenever composeEffect runs (how often it runs depends on
effectCompositionFrequency), it returns a new ComposedEffect containing
callback functions—which can be referred to as "effect generators"—which the clip will use to generate the keyframes/mutators for the animation.
Naturally, the generators have access to the closure created by the call to
composeEffect, which is useful for storing stateful data.
For the sake of code clarity, it is recommended that you keep a final return statement at the bottom of
composeEffect (as opposed to several return statements scattered throughout).
Special this
For both convenience and utility, using this
inside a call to EffectComposer.composedEffect | composedEffect
gives access to a subset of useful properties and methods of the clip.
Forward Keyframes Generator
In a typical case, you will return a ComposedEffect containing the callback function ComposedEffect.forwardKeyframesGenerator.
When the clip is played, the callback function will be called to produce the keyframes for the animation to play. When the clip
is rewound, the same callback function will be called again to produce keyframes for the animation to play, but the direction will
be reversed. This means that every time playback is initiated (playing or rewinding), a new set of keyframes is produced.
When writing your keyframes you must always define the full course of the effect. For example, from the forward keyframes generator,
do not return [{}, {backgroundColor: 'blue'}, {backgroundColor: 'red', opacity: '0.5'}]
.
Instead, store the original styles—something like const initialStyles = this.getStyles(['backgroundColor', 'opacity']);
, and return
[{...initialStyles}, {backgroundColor: 'blue'}, {backgroundColor: 'red', opacity: 0.5}]
(taking advantage of the fact that
initialStyles
will still be accessible even after the ComposedEffect is returned). This ensures
that the initial styles can be restored when the clip is rewound. The helper method AnimClip.getStyles is a convenient way
to get the current style properties of an element.
Forward Mutator Generator
You can also animate JavaScript values using ComposedEffect.forwardMutatorGenerator.
Like the keyframes generator, it is a callback function that will be called when the clip is played, and when the clip is rewound,
it will be called again with its effect being reversed this time. The difference is that instead of returning
a Keyframes, it will return a Mutator—a function that will be repeatedly called at the device's framerate.
If some JavaScript value is changed within the mutator with respect to the clip's progress, then the result is the illusion of a
smooth animation that couldn't be achieved using normal CSS-based animations (since CSS cannot animate JavaScript values).
(Under the hood, requestAnimationFrame loops are being used.)
See the documentation of ComposedEffect for details on how to use mutator generators.
Backward Effect Generators
In addition to the forward keyframes/mutator generators, you may also define ComposedEffect.backwardKeyframesGenerator and/or
ComposedEffect.backwardMutatorGenerator, giving you the ability to define more complex effects. When the clip is played,
the full ComposedEffect will be produced. Only the forward keyframes/mutator generators will be called at first since they will be used for
playing a clip (just as before). When the clip is eventually rewound, then the backward keyframes/mutator generators will be called and
used for the animation (instead of reusing the forward generators). When the clip is eventually played again, the forward generators
will be called to produce the effect again. Then when the clip is eventually rewound again, the backward generators will once again
be called to produce the effect—so on and so forth.
Composition Frequency
By default, composeEffect only runs the first time the clip is played, so the
resulting generators will exist for the lifetime of the clip. To allow composeEffect
to re-run and remake the ComposedEffect, set EffectComposer.effectCompositionFrequency to 'on-every-play'
.
Caution with composite
Be mindful of how the value of AnimClipConfig.composite
('replace'
, 'add'
or 'accumulate'
) may affect the effect when rewinding. This will less often be an issue
for entrance and exit effects since changes resulting from effects in these
categories are never committed (meaning composite
-related bugs are less likely), but for motion and
emphasis effects, you should be especially cognizant of potential logic errors.
// EXAMPLES WHERE BACKWARD GENERATORS CAN BE OMITTED
const clipFactories = webchalk.createAnimationClipFactories({
customEmphasisEffects: {
// -----------------------------------------------------------------
// ----------------------------EXAMPLE 1----------------------------
// -------------------------transparencyHalf------------------------
// -----------------------------------------------------------------
transparencyHalf: {
composeEffect() {
const initialOpacity = this.getStyles('opacity');
// return ComposedEffect
return {
forwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [{opacity: initialOpacity}, {opacity: 0.5}];
},
// Notice how the backward generator would be equivalent to running the forward generator
// and reversing the effect of the keyframes. That means that the forward keyframes
// generator is invertible, and the backward generator can be omitted.
backwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [{opacity: 0.5}, {opacity: initialOpacity}];
},
};
},
},
// Exactly equivalent to transparencyHalf because the keyframe generator
// is invertible
transparencyHalf_shortcut: {
composeEffect() {
const initialOpacity = this.getStyles('opacity');
// return ComposedEffect
return {
forwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [{opacity: initialOpacity}, {opacity: 0.5}];
},
};
},
},
},
customEntranceEffects: {
// -----------------------------------------------------------------
// ----------------------------EXAMPLE 2----------------------------
// ------------------------------shyIn------------------------------
// -----------------------------------------------------------------
// Element shyly enters, hesitantly fading and scaling in and out until it
// reaches full opacity and scale
shyIn: {
composeEffect() {
// return ComposedEffect
return {
forwardKeyframesGenerator: () => {
// return Keyframes (PropertyIndexedKeyframes)
return {
opacity: [0, 0.5, 0.1, 0.7, 0, 1],
scale: [0, 0.5, 0.1, 0.7, 0, 1],
};
},
// Notice how the backward generator would be equivalent to running the forward generator
// and reversing the effect of the keyframes. That means that the forward keyframes
// generator is invertible.
backwardKeyframesGenerator: () => {
// return Keyframes (PropertyIndexedKeyframes)
return {
opacity: [1, 0, 0.7, 0.1, 0.5, 0],
scale: [1, 0, 0.7, 0.1, 0.5, 0],
};
},
};
},
},
// Exactly equivalent to shyIn because the keyframes generator is invertible.
shyIn_shortcut: {
composeEffect() {
// return ComposedEffect
return {
forwardKeyframesGenerator: () => {
// return Keyframes (PropertyIndexedKeyframes)
return {
opacity: [0, 0.5, 0.1, 0.7, 0, 1],
scale: [0, 0.5, 0.1, 0.7, 0, 1],
};
},
};
},
},
// -----------------------------------------------------------------
// ----------------------------EXAMPLE 3----------------------------
// -----------------------riseUp and sinkDown-----------------------
// -----------------------------------------------------------------
// Replicates PowerPoint's Rise Up animation.
// Element flies in from the bottom of the screen and ends up
// slightly too high, then settles down to its final position.
riseUp: {
composeEffect() {
const belowViewportDist = () => {
return window.innerHeight - this.domElem.getBoundingClientRect().top;
};
// return Composed Effect
return {
forwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [
{
opacity: 0,
composite: 'replace'
},
{
translate: `0 ${belowViewportDist()}px`,
offset: 0,
easing: useEasing('power2-out')
},
{
translate: `0 -25px`,
offset: 0.83333
},
{
translate: `0 -25px`,
offset: 0.86,
easing: useEasing('power1-in')
},
{translate: `0 0`},
];
},
// It would be a pain to figure out what the backward keyframes should look like
// for rewinding this effect. Fortunately, the forward generator is invertible,
// (trust me—it is true) so backwardKeyframesGenerator() can be omitted.
// ---------------------------------------------------------------------------------------
// backwardKeyframesGenerator: () => {
// // return Keyframes (Keyframe[])
// return [] // ??????
// },
};
},
defaultConfig: {
composite: 'accumulate',
},
immutableConfig: {},
},
},
customExitEffects: {
// Replicates PowerPoint's Sink Down animation, which is the opposite of Rise Up.
// Element floats up slightly and then accelerates to the bottom of the screen.
sinkDown: {
composeEffect() {
const belowViewportDist = () => {
return window.innerHeight - this.domElem.getBoundingClientRect().top;
};
// return Composed Effect
return {
// Most of the time, when you write your own custom entrance/exit effect, you will want
// to write the corresponding exit/entrance effect. If you write flyIn, you'll probably
// write flyOut; if you write slideOut, you'll probably write slideIn; if you write riseUp,
// you'll probably write sinkDown. The beauty is that if riseUp and sinkDown are opposites,
// then we know that playing riseUp should be the same as rewinding sinkDown. Therefore,
// we can copy-paste the logic from riseUp's forwardKeyframesGenerator() and simply set
// reverseKeyframesEffect to true. Once again, we have gotten
// away with just figuring out what the forward keyframes look like without having
// to figure out what the other set looks like.
// ---------------------------------------------------------------------------------------
reverseKeyframesEffect: true,
forwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [
{
opacity: 0,
composite: 'replace'
},
{
translate: `0 ${belowViewportDist()}px`,
offset: 0,
easing: useEasing('power2-out'),
},
{
translate: `0 -25px`,
offset: 0.83333
},
{
translate: `0 -25px`,
offset: 0.86,
easing: useEasing('power1-in')
},
{translate: `0 0`},
];
},
// backwardKeyframesGenerator: () => {
// // return Keyframes (Keyframe[])
// return [] // ??????
// },
};
},
defaultConfig: {
composite: 'accumulate',
},
immutableConfig: {},
},
// -----------------------------------------------------------------
// ----------------------------EXAMPLE 4----------------------------
// ----------------------------flyOutLeft---------------------------
// -----------------------------------------------------------------
// a custom animation effect for flying out to the left side of the screen
// while displaying the percentage progress in the element's text content
flyOutLeft: {
composeEffect() {
const computeTranslationStr = () => {
const orthogonalDistance = -(this.domElem.getBoundingClientRect().right);
const translationString = `${orthogonalDistance}px 0px`;
return translationString;
}
// return ComposedEffect
return {
forwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [
{translate: computeTranslationStr()}
];
},
// Notice how the backward generator would be equivalent to running the forward generator
// and reversing the effect of the keyframes (even though the composite value is
// 'accumulate', it's still invertible because exit effects' changes are never committed).
// That means that the forward keyframes generator is invertible.
// --------------------------------------------------------------------------------------
backwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [
{translate: computeTranslationStr()},
{translate: `0 0`}
];
},
forwardMutatorGenerator: () => {
// return Mutator
return () => {
this.domElem.textContent = `${this.computeTween(0, 100)}%`;
};
},
// Notice how the backward generator would be equivalent to running the forward generator
// and reversing the effect of the mutator. That means that the mutator generator is
// invertible. (Note that it may not always be the case that BOTH the keyframes
// generators and the forward mutator generator are invertible).
// --------------------------------------------------------------------------------------
backwardMutatorGenerator: () => {
// return Mutator
return () => {
this.domElem.textContent = `${this.computeTween(100, 0)}%`;
};
},
};
},
defaultConfig: {
duration: 1000,
easing: "ease-in",
},
immutableConfig: {
// this means that the translation is added onto the element's position
// instead of replacing it
composite: 'accumulate',
},
},
// Exactly equivalent to flyOutLeft
flyOutLeft_shortcut: {
composeEffect() {
const computeTranslationStr = () => {
const orthogonalDistance = -(this.domElem.getBoundingClientRect().right);
const translationString = `${orthogonalDistance}px 0px`;
return translationString;
}
// return ComposedEffect
return {
forwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [
{translate: computeTranslationStr()}
];
},
forwardMutatorGenerator: () => {
// return Mutator
return () => {
this.domElem.textContent = `${this.computeTween(0, 100)}%`;
};
},
};
},
defaultConfig: {
duration: 1000,
easing: "ease-in",
},
immutableConfig: {
composite: 'accumulate',
},
},
},
});
// EXAMPLES WHERE BACKWARD GENERATORS CANNOT BE OMITTED
const clipFactories = webchalk.createAnimationClipFactories({
customMotionEffects: {
// a custom animation for translating a certain number of pixels to the right
translateRight: {
composeEffect(numPixels: number) {
// a helper function you wrote that will exist within a closure scoped to composeEffect()
const createTranslationString = () => {
if (numPixels <= 0) { throw RangeError(`Number of pixels must exceed 0.`) }
const translationString = `${numPixels}px`;
return translationString;
}
// return ComposedEffect
return {
forwardKeyframesGenerator: () => {
// return Keyframes (Keyframe][])
return [
{translate: createTranslationString()} // Keyframe
];
},
// backwardKeyframesGenerator() must be specified because reversing the keyframes produced
// by forwardKeyframesGenerator() would not have the intended effect (due to
// {composite: 'accumulate'}, trying to simply use the reversal of
// {translate: createTranslationString()} from forwardKeyframesGenerator() would actually
// cause the target element to jump an additional numPixels pixels to the right
// before sliding left, which is not the intended rewinding effect).
backwardKeyframesGenerator: () => {
// return Keyframes (Keyframe[])
return [
{translate: '-'+createTranslationString()}, // Keyframe
];
}
};
},
immutableConfig: {
// this means that the translation is added onto the element's position
// instead of replacing it
composite: 'accumulate',
},
},
// a custom animation for scrolling to a specific point on the page.
scrollTo: {
composeEffect(yPosition: number) {
const initialPosition = this.domElem.scrollTop;
// return ComposedEffect
return {
// The mutation is to use the scrollTo() method on the element.
// Thanks to computeTween(), there will be a smooth scroll
// from initialPosition to yPosition
forwardMutatorGenerator: () => {
// return Mutator
return () => {
this.domElem.scrollTo({
top: this.computeTween(initialPosition, yPosition),
behavior: 'instant'
});
};
},
// The forward mutation loop is not invertible because reversing it requires
// re-computing the element's scroll position at the time of rewinding
// (which may have since changed for any number of reasons, including user
// scrolling, size changes, etc.). So we must define backwardMutatorGenerator()
// to do exactly that.
backwardMutatorGenerator: () => {
// return Mutator
return () => {
const currentPosition = this.domElem.scrollTop;
this.domElem.scrollTo({
top: this.computeTween(currentPosition, initialPosition),
behavior: 'instant'
});
};
}
};
},
},
}
});
Readonly
lengthReadonly
nameReturns the name of the function. Function names are read-only and can not be changed.
Determines whether the given value inherits from this function if this function was used as a constructor function.
A constructor function can control which objects are recognized as its instances by 'instanceof' by overriding this method.
Calls the function, substituting the specified object for the this value of the function, and the specified array for the arguments of the function.
The object to be used as the this object.
Optional
argArray: anyA set of arguments to be passed to the function.
For a given function, creates a bound function that has the same body as the original function. The this object of the bound function is associated with the specified object, and has the specified initial parameters.
An object to which the this keyword can refer inside the new function.
Rest
...argArray: any[]A list of arguments to be passed to the new function.
Calls a method of an object, substituting another object for the current object.
The object to be used as the current object.
Rest
...argArray: any[]A list of arguments to be passed to the method.
Object representing an entry in an EffectComposerBank. It contains