2d-inc / Flare-React

Example React Component to display Flare animations.
MIT License
103 stars 11 forks source link

Scale property not tweening when animation mixing #14

Closed Justinette2175 closed 4 years ago

Justinette2175 commented 5 years ago

Hello,

I am implementing a Controller to progressively switch between two animations over a period of time. The two animations are mixing really well for almost all properties (opacity, color, X and Y position), but the scale of the elements jumps directly as I toggle from one item to another.

Here is the code for the controller:

import FlareComponent from 'flare-react';

class FlareController extends FlareComponent.Controller {
  constructor(animations, totalSwitchingTime) {
    super();
    this._totalSwitchingTime = totalSwitchingTime;
    this._animations = animations;
    this._totalAnimationTime = 0;
    this._currentAnimation = null;
    this._pastAnimation = null;
    this._currentSwitchingTime = 0;
  }

  initialize(artboard) {
    const animations = this._animations;
    Object.keys(animations).forEach((key) => {
      this[`_${key}`] = artboard.getAnimation(animations[key].name);
    }) 
  }

  advance(artboard, elapsed) {
    // advance animations
    this._totalAnimationTime += elapsed; // Time elapsed since component load
    // If no current animation is loaded:
    if (!this._currentAnimation) {
      this._currentAnimation = this._animation1;
    } 

    // The mixing value is 1 (show all of the animation without tweening)
    let newMix = 1;

    // If there is a past animation (we are currently switching from one to another)
    if (this._pastAnimation) {
      let animationStage = this._totalAnimationTime % this._pastAnimation.duration; // Where we currently are in the animation
      newMix = this._currentSwitchingTime / this._totalSwitchingTime; //Mix value for new animation is amount of time spent switching so far over total switch time
      const pastMix = 1 - newMix; // Mix value for leaving animation
      this._pastAnimation.apply(animationStage, artboard, pastMix); 

      //Add elapsed to the amount of time spent switching so far
      this._currentSwitchingTime += elapsed;

      // If we're almost done switching, remove switching state
      if (pastMix < 0.1) {
        this._pastAnimation = null;
      }
    }

    // Apply mix to current (or incoming) animation
    this._currentAnimation.apply(this._totalAnimationTime % this._currentAnimation.duration, artboard, newMix);
    return true;
  }

  switchToNextAnimation(newAnimation) {
    this._pastAnimation = this._currentAnimation;
    this._currentAnimation = this[`_${newAnimation}`]
    this._currentSwitchingTime = 0;
  }
};

export default FlareController;

And here is the react component implementation:

const ANIMATIONS = {
  animation1: {
    name: "1",
  },
  animation2: {
    name: "2",
  },
};

const MAX_SWITCHING_TIME = 5;
class FlareTest extends Component {
  constructor(props) {
    super(props);
    this._animation = React.createRef();
    this.flareController = new FlareController(ANIMATIONS, MAX_SWITCHING_TIME);
    this.state = {
      paused: false,
    }
  }

  switchAnimation(newAnimation) {
    this.flareController.switchToNextAnimation(newAnimation);
  }

  togglePause() {
    this.setState((prevState) => { return { paused: !prevState.paused } });
  }

  render() {
    return (
      <section>
        <button onClick={() => this.switchAnimation('animation1')}>1</button>
        <button onClick={() => this.switchAnimation('animation2')}>2</button>
        <button onClick={() => this.togglePause()}>{this.state.paused ? 'Start' : 'Pause'}</button>
        <FlareComponent
          ref={this._animation}
          controller={this.flareController}
          width={200}
          height={200}
          file={animationtest}
          transparent
          animateToPosition
          isPaused={this.state.paused}
        />
      </section>
    )
  }
}

export default FlareTest;

I am using this test file: https://www.2dimensions.com/a/justinegagnepain/files/flare/flare-test

As I tween between the two animations (called '1' and '2'), the red and green dots progressively darken in fill color, the white rectangle changes opacity, and the circles do a circle motion to switch between vertical movement and horizontal movement. However, the scale jumps from one to another.

Thank you for your help!

luigi-rosso commented 4 years ago

Thanks for the helpful write-up, I think we solved this one over email correct? Where Flare wasn't interpolating the scale values properly. Please let me know if this is still causing problems!

Justinette2175 commented 4 years ago

Yes! Thanks for your help, it's all resolved!