Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After animation sequence ended, the animation went back to previous frame after rebuilding. #112

Closed
yjoo9317 opened this issue Jun 26, 2019 · 7 comments

Comments

@yjoo9317
Copy link

yjoo9317 commented Jun 26, 2019

Dear, @luigi-rosso

Repro steps.

  1. Open the card-like page and wait until the animation icon's sequence ends.
  2. Dragging the page around which triggered rebuilding the page
  3. Then notice the animation goes back to previous frame after being rebuilt.

Here is the code snippet from the controller's advance() and captured images are following.

   _currentPosition += elapsed;

    if (widget.isLooping) {
      _currentPosition %= _animation.duration;
    }
    else {
      _animation.apply(_currentPosition, artboard, MIX); // MIX 1.0
      return _currentPosition < _animation.duration;
    }
    _animation.apply(_currentPosition, artboard, MIX);
    return true;
  1. When checkmark played to the end

Screen Shot 2019-06-26 at 4 40 58 PM

  1. When the widget has been rebuilt.

Screen Shot 2019-06-26 at 4 41 15 PM

Only way that I can keep the animation locked to the end is to keep advancing by returning true and applying the current position (i.e., _animation.duraton) repeatedly.

@yjoo9317
Copy link
Author

@luigi-rosso,
I figure out the issue (sort of).
I found the followings.

  1. Once the controller's advance() returns false, it will not run again (i.e., won't call advance() again) even after setState() has been called.
    In order to make it run again (at least make it actor call advance() again), I needed set isActive value true since I guess having advance() return false did set isActive as false.
  2. The above issue has been resolved by setting isActive as true. But still I don't understand why it
    actually showed the previous frame though. Internally, it didn't cache the latest frame?

Anyway, I will leave the issue open until you confirm what I've found here.

@luigi-rosso
Copy link
Contributor

That does seem strange. It could be a few different things...Any chance you could share the full source or an isolated example so I can take a better look at what's going on?

@yjoo9317
Copy link
Author

Hi,

Here is Flare widget part

@override
  Widget build(BuildContext context) {

    FlareActor actor = FlareActor(
      AnimationAssetDir + widget.asset,
      alignment: Alignment.center,
      fit: widget.fit ?? BoxFit.none,
      controller: this,
    );

    if (_artboard == null) {
      return Container(width: 1.0, height: 1.0);
    }
    else {
      Widget flare = Container(
        child: actor,
        width: _artboard.width,
        height: _artboard.height,
      );

      /// make sure it will call advance anyway even after being deactivated.
      this.isActive.value = true;
      return flare;
    }
  }

here is controller part

  bool advance(FlutterActorArtboard artboard, double elapsed) {
    // adding up each elapsed time to know where we are
    _currentPosition += elapsed;

    if (!widget.isPlaying) {
      _animation.apply(_currentPosition, artboard, MIX);
      _currentPosition -= elapsed;
      return false;
    }

    // if it is looping, make it loop by replacing current position with modulo
    if (widget.isLooping) {
      _currentPosition %= _animation.duration;
    }
    // if it is not looping,
    // then run until it reaches the end of duration
    else {
      _animation.apply(_currentPosition, artboard, MIX);
      return _currentPosition < _animation.duration;
    }
    _animation.apply(_currentPosition, artboard, MIX);
    return true;
  }

@yjoo9317
Copy link
Author

yjoo9317 commented Jul 2, 2019

Hello, @luigi-rosso
do you have any update on this? or do you find anything particular from above?

@luigi-rosso
Copy link
Contributor

I'll look into this today! Thanks for the code.

@luigi-rosso
Copy link
Contributor

I ran (as best I could) a local implementation of your code but I couldn't reproduce the issue. Could you expand on how you're getting the artboard in your widget? Does it look any different using the intrinsic_size_experiment (so not having to load the artboard separately)?

Alternatively, could you share a complete example with me (including the Flare file) so I can make sure I'm looking at the same thing you are? Feel free to email me at luigi@2dimensions.com if you don't want to share it publicly. I'll follow up here with a solution to make sure the answer is publicly available.

@yjoo9317
Copy link
Author

yjoo9317 commented Jul 3, 2019

@luigi-rosso
Thanks for the trials.

I set isActive = true in build(). If you tried with it, then it wouldn't happen.
If you remove it then it will happen I think.
Here I am not using the intrinsic size you shared before since it wasn't in the dev channel.
When the usingArtboardSize attribute is available in dev channel, I will switch to using it.
(Is it available on dev channel already? Let me know.)
FYI, I put the cachedActor in initState.
If you can't reproduce it, then I will share more via email since this is as much as I can do in public space.

PS:
These are some logs that I am getting while testing flare related pages.
You might want to make them better formatted if you need them, or customize so that it won't print out in release mode.

flare_dart/lib/actor_ik_constraint.dart:85:        print("Bone not in chain: " + bone.bone.name);
flare_dart/lib/dependency_sorter.dart:27:      print("Dependency cycle!");
flare_flutter/lib/flare_cache_asset.dart:25:              print("Failed to load flare file from $filename.");```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants