webchalk-animate - v0.31.0
    Preparing search index...

    Class AnimClip<TPresetEffectDefinition, TClipConfig>Abstract

    A "clip" is the smallest building block of a timeline. It is essentially a [DOM element, effect] pair, where a "DOM element" is some HTML element on the page and the effect is the animation effect that will be applied to it (asynchronously).

    The AnimClip class is abstract, meaning it cannot be instantiated. But it has several subclasses such as EntranceClip, MotionClip, TransitionClip, etc. Webchalk provides convenient factory functions that can be used to create such clips—the factory functions can be obtained from Webchalk.createAnimationClipFactories. Examples are shown below.

    Generally (with some exceptions), using a clip factory function follows this format: const clip = <factory func>(<some element>, <effect name>, [<effect options>], {<optional clip configuration>});

    // retrieve the clip factory functions
    const clipFactories = webchalk.createAnimationClipFactories();

    // select an element from the DOM
    const square = document.querySelector('.square');

    // A = element, B = effect name, C = effect options, D = configuration (optional)

    // create 3 animation clips using the clip factory functions Entrance(), Motion(), and Emphasis()
    // A B C
    const entClip = clipFactories.Entrance(square, '~fade-in', []);
    // A B C
    const motClip = clipFactories.Motion(square, '~translate', [{translate: '500px 0px', selfOffset: '50% 50%'}]);
    // A B C D
    const empClip = clipFactories.Emphasis(square, '~highlight', ['red'], {duration: 2000, easing: 'ease-in'});

    (async () => {
    // play the clips one at a time
    await entClip.play();
    await motClip.play();
    await empClip.play();
    // rewind the clips one at a time
    await empClip.rewind();
    await motClip.rewind();
    await entClip.rewind();
    })();

    Type Parameters

    Hierarchy (View Summary)

    Index

    Structure

    Methods and/or fields related to the structure of the clip, including the element it targets and any parent structures it belongs to.

    Properties

    Property Getter Methods

    Methods that return objects that contain various internal fields of the clip (such as duration from getTiming(), inProgress from getStatus(), etc.).

    Accessors

    Playback Methods

    Methods that control the playback of the animation clip.

    Timing Event Methods

    Methods that involve listening to the progress of the animation clip to perform tasks at specific times.

    Configuration

    Methods and/or fields related to the configuration settings of the clip, including configuration settings specific to the effect category of the clip.

    Helper Methods

    Methods to help with the functionality of clip operations.

    Methods

    Structure

    domElem: DOMElement

    The DOM element that is to be animated.

    • get root(): | AnimClip<
          Readonly<
              StripDuplicateMethodAutocompletion<
                  {
                      defaultConfig?: Partial<unknown> & object;
                      howOftenBuildGenerators?: "on-first-play-only" | "on-every-play";
                      immutableConfig?: Partial<unknown> & object;
                      buildFrameGenerators(
                          this: Readonly<
                              Pick<
                                  (
                                      AnimClip<Readonly<StripDuplicateMethodAutocompletion<{ defaultConfig?: (Partial<unknown> & object) | undefined; immutableConfig?: (Partial<unknown> & object) | undefined; howOftenBuildGenerators?: "on-first-play-only" | "on-every-play" | undefined; buildFrameGenerators(this: Readonly<Pick<AnimClip<Readonly<StripDuplicateMethodAutocompletion<any>>, AnimClipConfig>, "computeTween">>, ...effectOptions: unknown[]): EffectFrameGeneratorSet; }>>, AnimClipConfig>
                                  ),
                                  "computeTween",
                              >,
                          >,
                          ...effectOptions: unknown[],
                      ): EffectFrameGeneratorSet;
                  },
              >,
          >,
          AnimClipConfig,
      >
      | AnimSequence
      | AnimTimeline

      The highest level of this clip's lineage.

      • If the clip is nested within an AnimTimeline: that timeline,
      • Else, if the clip is within an AnimSequence: that sequence,
      • Else: the clip itself

      Returns
          | AnimClip<
              Readonly<
                  StripDuplicateMethodAutocompletion<
                      {
                          defaultConfig?: Partial<unknown> & object;
                          howOftenBuildGenerators?: "on-first-play-only" | "on-every-play";
                          immutableConfig?: Partial<unknown> & object;
                          buildFrameGenerators(
                              this: Readonly<
                                  Pick<
                                      (
                                          AnimClip<Readonly<StripDuplicateMethodAutocompletion<{ defaultConfig?: (Partial<unknown> & object) | undefined; immutableConfig?: (Partial<unknown> & object) | undefined; howOftenBuildGenerators?: "on-first-play-only" | "on-every-play" | undefined; buildFrameGenerators(this: Readonly<Pick<AnimClip<Readonly<StripDuplicateMethodAutocompletion<any>>, AnimClipConfig>, "computeTween">>, ...effectOptions: unknown[]): EffectFrameGeneratorSet; }>>, AnimClipConfig>
                                      ),
                                      "computeTween",
                                  >,
                              >,
                              ...effectOptions: unknown[],
                          ): EffectFrameGeneratorSet;
                      },
                  >,
              >,
              AnimClipConfig,
          >
          | AnimSequence
          | AnimTimeline

    Properties

    animation: WebchalkAnimation
    direction: "forward" | "backward" = 'forward'
    effectFrameGeneratorSetMetadata: {
        bFramesMirrored: boolean;
        bRafMirrored: boolean;
        noKeyframes: boolean;
        noRaf: boolean;
    } = ...
    effectName: string
    effectOptions: Parameters<TPresetEffectDefinition["buildFrameGenerators"]> = ...
    firstRun: boolean = true
    generateError: ClipErrorGenerator = ...
    id: number

    A number that uniquely identifies the clip from other clips. Automatically generated.

    inProgress: boolean = false
    isFinished: boolean = false
    isPaused: boolean = false
    isRunning: boolean = false
    nestedEffectFrameGeneratorSetMetadataArray: {
        bFramesMirrored: boolean;
        bRafMirrored: boolean;
        noKeyframes: boolean;
        noRaf: boolean;
    }[] = []
    presetEffectDefinition: TPresetEffectDefinition
    timescaleType: "duration" | "rate" = 'duration'
    MIN_DURATION: number = 0.01

    Property Getter Methods

    • Returns an object containing the specified style properties of the specified element.

      • Normal CSS properties must be written in camelCase (e.g., ['marginBottom', 'backgroundColor'], NOT ['margin-bottom', 'background-color']),
      • CSS variables should be written normally (e.g., ['--nav-edge-color', '--brand-red']).

      Parameters

      • element: Element

        The DOM element from which to read the styles.

      • styleProps: StyleProperty[]

        An array of strings representing camelCase CSS property names.

      Returns { [key: string]: string }

      An object where the keys are the specified camelCase strings and the values are the CSS property values.

    • Returns the string value of the specified CSS property name for the specified element.

      • Normal CSS properties must be written in camelCase (e.g., 'marginBottom', NOT 'margin-bottom'),
      • CSS variables should be written normally (e.g., '--brand-red').

      Parameters

      Returns string

      The string value of the specified camelCase CSS property name.

    • Returns an object containing the specified style properties of this clip's DOM element.

      • Normal CSS properties must be written in camelCase (e.g., ['marginBottom', 'backgroundColor'], NOT ['margin-bottom', 'background-color']),
      • CSS variables should be written normally (e.g., ['--nav-edge-color', '--brand-red']).

      Parameters

      • styleProps: StyleProperty[]

        An array of strings representing camelCase CSS property names.

      Returns { [key: string]: string }

      An object where the keys are the specified camelCase strings and the values are the CSS property values.

    • Returns the string value of the specified CSS property name for this clip's DOM element.

      • Normal CSS properties must be written in camelCase (e.g., 'marginBottom', NOT 'margin-bottom'),
      • CSS variables should be written normally (e.g., '--brand-red').

      Parameters

      Returns string

      The string value of the specified camelCase CSS property name.

    Accessors

    Playback Methods

    Timing Event Methods

    • Returns a Promise that is resolved when the animation clip reaches the specified time in the specified direction.

      Parameters

      • direction: "forward" | "backward"

        The direction the animation will be going when the Promise is resolved.

      • phase: "delayPhase" | "activePhase" | "endDelayPhase" | "whole"

        The phase of the animation where the Promise will be resolved.

      • timePosition: number | "end" | `${number}%` | "beginning"

        The time position within the phase when the Promise will be resolved.

      Returns Promise<void>

      A promise that is resolved at the specific time point of the animation.

      async function testFunc() {
      const { Entrance } = webchalk.createAnimationClipFactories();
      const square = document.querySelector('.square');
      const ent = Entrance(square, '~fade-in', []);
      // wait until ent is played and gets 1/5 of the way through the active phase of the animation
      await ent.generatePromise('forward', 'activePhase', '20%');
      console.log('1/5 done playing!');
      }

      testFunc();
      async function testFunc() {
      const { Entrance } = webchalk.createAnimationClipFactories();
      const square = document.querySelector('.square');
      const ent = Entrance(square, '~fade-in', []);
      // wait until ent is eventually rewound and gets 4/5 of the way through rewinding the active phase of the animation
      await ent.generatePromise('backward', 'activePhase', '20%');
      console.log('4/5 done rewinding!');
      }

      testFunc();
    • Pauses the animation clip when it reaches the specified time and performs the specified task, unpausing once the task is complete.

      • If the clip is part of a structure (like a sequence), the entire structure is paused as well.

      Parameters

      • phase: "delayPhase" | "activePhase" | "endDelayPhase" | "whole"

        The phase of the animation to place the blocks in.

      • timePosition: number | "end" | `${number}%` | "beginning"

        The time position within the phase when the task should be performed.

      • task: ScheduledTask

        An object that contains the functions that should be called when timePosition is reached.

      • schedulingOptions: { frequencyLimit?: number } = {}

        An options object defining the behavior of the scheduling.

        • OptionalfrequencyLimit?: number

          The maximum number of times the task can be performed.

          Infinity
          

      Returns string

      The string id (auto-generated) referring to the task and its spot in the schedule.

      async function wait(milliseconds: number) { // Promise-based timer
      return new Promise(resolve => setTimeout(resolve, milliseconds));
      }

      const square = document.querySelector('.square');
      const { Entrance } = webchalk.createAnimationClipFactories();
      const ent = Entrance(square, '~fade-in', [], {endDelay: 1500});

      // adds 1 task that will pause the clip for 2 seconds once the clip is 15% through the active phase
      ent.scheduleTask('activePhase', '15%', {onPlay: () => wait(2000)});
      // adds 1 more task at the same point that will pause the clip for 3 seconds.
      ent.scheduleTask('activePhase', '15%', {onPlay: () => wait(3000)});
      // adds 1 task at 40% into the endDelay phase that will...
      // ... log 'HELLO' if the clip is playing forward
      // ... log 'WORLD' if the clip is rewinding
      ent.scheduleTask('endDelayPhase', '40%', {
      onPlay: () => console.log('HELLO'),
      onRewind: () => console.log('WORLD')
      }, {frequencyLimit: 2});

      (async () => {
      // 1) First play
      await ent.play();
      // ↑
      // Once ent is 15% through the active phase, it will pause and handle its scheduled tasks.
      // -- "wait(2000)" resolves after 2 seconds.
      // -- "wait(3000)" resolves after 3 seconds.
      // There are no more tasks at this point, so playback is resumed.
      // Once ent is 40% through the endDelay phase, it will pause and handle its tasks
      // -- 'HELLO' is logged to the console
      // There are no more tasks at this point, so playback is resumed.

      // 2) First rewind
      await ent.rewind();
      // ↑
      // Once ent rewinds back to the 40% point of the endDelay phase, it will pause and...
      // ... handle its scheduled tasks
      // -- 'WORLD' is logged to the console
      // There are no more tasks at this point, so playback is resumed.

      // 3) Second play
      await ent.play();
      // ↑
      // Once ent is 15% through the active phase, it will pause and handle its scheduled tasks.
      // -- "wait(2000)" resolves after 2 seconds.
      // -- "wait(3000)" resolves after 3 seconds.
      // There are no more tasks at this point, so playback is resumed.
      // Once ent is 40% through the endDelay phase, it will pause and handle its tasks
      // -- 'HELLO' is logged to the console
      // -- -- Since the frequency limit was 2, this subtask is removed
      // There are no more tasks at this point, so playback is resumed.

      // 4) Second rewind
      await ent.rewind();
      // ↑
      // Once ent rewinds back to the 40% point of the endDelay phase, it will pause and...
      // ... handle its scheduled tasks
      // -- 'WORLD' is logged to the console
      // -- -- Since the frequency limit was 2, this subtask is removed
      // There are no more tasks at this point, so playback is resumed.

      // 5) Third play
      await ent.play();
      // ↑
      // Once ent is 15% through the active phase, it will pause and handle its scheduled tasks.
      // -- "wait(2000)" resolves after 2 seconds.
      // -- "wait(3000)" resolves after 3 seconds.
      // There are no more tasks at this point, so playback is resumed.

      // 6) Third rewind
      await ent.rewind();
      // ↑ No scheduled tasks, so playback runs uninterrupted
      })();

    Configuration

    config: TClipConfig = ...
    • get categoryDefaultConfig(): TClipConfig

      The default configuration for clips in a specific effect category, which includes any additional configuration options that are specific to the effect category.

      • This never changes, and it available mostly just for reference. Consider it a static property.
      • This does NOT include any default configuration from preset effect definitions or configurations passed in from clip factory functions.

      Returns TClipConfig

    • get baseDefaultConfig(): {
          commitsStyles: true;
          composite: "replace";
          cssClasses: {
              toAddOnFinish: [];
              toAddOnStart: [];
              toRemoveOnFinish: [];
              toRemoveOnStart: [];
          };
          delay: 0;
          duration: 500;
          easing: "linear";
          endDelay: 0;
          playbackRate: 1;
          startsNextClipToo: false;
          startsWithPrevious: false;
      }

      The base default configuration for any animation clip before any category-specific configuration, preset effect definition configuration, or configuration passed in through clip factory functions are applied.

      Returns {
          commitsStyles: true;
          composite: "replace";
          cssClasses: {
              toAddOnFinish: [];
              toAddOnStart: [];
              toRemoveOnFinish: [];
              toRemoveOnStart: [];
          };
          delay: 0;
          duration: 500;
          easing: "linear";
          endDelay: 0;
          playbackRate: 1;
          startsNextClipToo: false;
          startsWithPrevious: false;
      }

    Helper Methods

    • Calculates the value partway between two fixed numbers (an initial value and a final value) based on the progress of the animation.

      Parameters

      • initialVal: number

        The starting value.

      • finalVal: number

        The ending value.

      Returns number

      The number that is a percentage of the way between initialVal and finalVal based on the percentage of completion of the animation (playing or rewinding).

      const {Entrance} = webchalk.createAnimationClipFactories({
      additionalEntranceEffectBank: {
      rotate: {
      buildFrameGenerators(degrees: number) {
      return {
      // when playing, keep computing the value between 0 and 'degrees'
      mutatorGenerator_play: () => () => { this.domElem.style.rotate = this.computeTween(0, degrees)+'deg'; },
      // when rewinding, keep computing the value between 'degrees' and 0
      mutatorGenerator_rewind: () => () => { this.domElem.style.rotate = this.computeTween(degrees, 0)+'deg'; }
      };
      }
      }
      },
      });

      const someElement = document.querySelector('.some-element');

      (async () => {
      await Entrance(someElement, 'rotate', [360], {duration: 2000}).play();
      // ↑ At 1.5 seconds (or 1500ms), the animation is 1.5/2 = 75% done playing.
      // Thus, computeTween(0, 360) at that exactly moment would...
      // return the value 75% of the way between 0 and 360 (= 270).
      // Therefore, at 1.5 seconds of playing, someElement's rotation is set to "270deg".

      await Entrance(someElement, 'rotate', [360], {duration: 2000}).rewind();
      // ↑ At 0.5 seconds (or 500ms), the animation is 0.5/2 = 25% done rewinding.
      // Thus, computeTween(360, 0) at that exactly moment would...
      // return the value 25% of the way between 360 and 0 (= 270).
      // Therefore, at 0.5 seconds of rewinding, someElement's rotation is set to "270deg".
      })();
    • Returns Readonly<
          StripDuplicateMethodAutocompletion<
              {
                  defaultConfig?: Partial<unknown> & object;
                  howOftenBuildGenerators?: "on-first-play-only" | "on-every-play";
                  immutableConfig?: Partial<unknown> & object;
                  buildFrameGenerators(
                      this: Readonly<
                          Pick<
                              AnimClip<
                                  (
                                      Readonly<StripDuplicateMethodAutocompletion<{ defaultConfig?: (Partial<unknown> & object) | undefined; immutableConfig?: (Partial<unknown> & object) | undefined; howOftenBuildGenerators?: "on-first-play-only" | "on-every-play" | undefined; buildFrameGenerators(this: Readonly<Pick<AnimClip<Readonly<StripDuplicateMethodAutocompletion<any>>, AnimClipConfig>, "computeTween">>, ...effectOptions: unknown[]): EffectFrameGeneratorSet; }>>
                                  ),
                                  AnimClipConfig,
                              >,
                              "computeTween",
                          >,
                      >,
                      ...effectOptions: unknown[],
                  ): EffectFrameGeneratorSet;
              },
          >,
      >

      An effect definition with a function that returns empty arrays (so no actual keyframes).

      This static method is purely for convenience.

    Methods

    • Updates the duration of rate-based animation clips.

      Parameters

      • duration: number

        The duration computed once the clip plays.

      • rescheduleTasks: boolean = true

      Returns void