static Mixin()

in src/core/animpack/AnimationPlayerInterface.js [185:434]


  static Mixin(BaseClass = class {}) {
    const AnimationPlayerMixin = class extends BaseClass {
      constructor(options = {}, ...args) {
        super(options, ...args);

        this._transitionState = new TransitionState();
        this._states = this._states !== undefined ? this._states : new Map();
        this._currentState = null;
        this._paused = false;

        this._transitionTime =
          Number(options.transitionTime) >= 0
            ? Number(options.transitionTime)
            : 0;

        this._easingFn =
          typeof options.easingFn === 'function' ? options.easingFn : undefined;
      }

      get paused() {
        return this._paused;
      }

      get transitionTime() {
        return this._transitionTime;
      }

      set transitionTime(seconds) {
        seconds = Number(seconds);

        if (!(seconds >= 0)) {
          throw new Error(
            `Cannot set transition time for ${this.constructor.name} to ${seconds}. Seconds must be a numeric value greather than or equal to zero.`
          );
        }

        this._transitionTime = seconds;
      }

      get easingFn() {
        return this._easingFn;
      }

      set easingFn(fn) {
        this._easingFn = fn;
      }

      get currentState() {
        return this._currentState;
      }

      get currentAnimation() {
        if (this._currentState) {
          return this._currentState.name;
        }

        return null;
      }

      get isTransitioning() {
        return this._currentState === this._transitionState;
      }

      _prepareCurrentState(
        name,
        playMethod,
        transitionTime,
        easingFn,
        onError
      ) {
        if (name !== null && !this._states.has(name)) {
          const e = new Error(
            `Cannot ${playMethod} animation ${name}. No animation exists with this name.`
          );

          if (typeof onError === 'function') {
            onError(e);
          }

          throw e;
        }

        const targetState = name !== null ? this._states.get(name) : null;

        // Make sure the new state isn't already playing
        if (this.currentAnimation !== name) {
          // Switch to the new state immediately
          if (transitionTime <= 0) {
            // Cancel the current state and set its weight to 0
            if (this._currentState) {
              this._currentState.cancel();
              this._currentState.weight = 0;
              this._currentState.deactivate();
            }

            this._currentState = targetState;
          }
          // Blend to the new state over time
          else {
            // Make sure to transition out of any states with non-zero weight
            const currentStates = [...this._states.values()].filter(
              s => s !== targetState && (s.weight || s.weightPending)
            );

            // Update the transition state with new inputs
            this._transitionState.configure(
              currentStates,
              targetState,
              transitionTime,
              easingFn,
              () => {
                this._currentState = targetState;
                this._transitionState.weight = 0;
              }
            );

            this._currentState = this._transitionState;
          }
        } else if (playMethod === 'play') {
          this._currentState.cancel();

          if (this._currentState === this._transitionState) {
            this._transitionState.reset(transitionTime, easingFn, () => {
              this._currentState = targetState;
              this._transitionState.weight = 0;
            });
          }
        }

        // Update weight for the new current state so it has full influence for the player
        this._currentState.weight = 1;
        this._currentState.updateInternalWeight(this._internalWeight);
      }

      playAnimation(
        name,
        transitionTime,
        easingFn,
        onFinish,
        onError,
        onCancel,
        onNext
      ) {
        let error;
        let reject = false;
        try {
          this._prepareCurrentState(
            name,
            'play',
            transitionTime !== undefined
              ? transitionTime
              : this._transitionTime,
            easingFn !== undefined ? easingFn : this._easingFn,
            onError
          );
        } catch (e) {
          error = e;
          reject = true;
        }

        if (reject) {
          return Deferred.reject(error);
        }

        return this._currentState.play(onFinish, onError, onCancel, onNext);
      }

      pauseAnimation() {
        if (this._currentState) {
          return this._currentState.pause();
        } else {
          return false;
        }
      }

      resumeAnimation(
        name,
        transitionTime,
        easingFn,
        onFinish,
        onError,
        onCancel,
        onNext
      ) {
        if (name === undefined && this._currentState) {
          name = this._currentState.name;
        }

        let error;
        let reject = false;
        try {
          this._prepareCurrentState(
            name,
            'resume',
            transitionTime !== undefined
              ? transitionTime
              : this._transitionTime,
            easingFn !== undefined ? easingFn : this._easingFn,
            onError
          );
        } catch (e) {
          error = e;
          reject = true;
        }

        if (reject) {
          return Deferred.reject(error);
        }

        return this._currentState.resume(onFinish, onError, onCancel, onNext);
      }

      cancelAnimation() {
        if (this._currentState) {
          return this._currentState.cancel();
        } else {
          return false;
        }
      }

      stopAnimation() {
        if (this._currentState) {
          return this._currentState.stop();
        } else {
          return false;
        }
      }

      update(deltaTime) {
        if (super.update) {
          super.update(deltaTime);
        }

        if (this._currentState) {
          this._currentState.update(deltaTime);
        }
      }

      discard() {
        if (super.discard) {
          super.discard();
        }

        this._transitionState.discard();
        delete this._transitionState;
      }
    };

    return AnimationPlayerMixin;
  }