How do I save the final state of a neon animation in Polymer?

Is there a way to save the final state of the neon animation? I tried using fill: 'forwards'

, but doesn't seem to do anything.

  <template>
    <div id="rect" style="width:100px;height:100px;background-color:red"></div>
  ...

  properties: {
    animationConfig: {
      value: function () {
        return {
          'hide': [{
            name: 'fade-out-animation',
            node: this.$.rect,
            // this doesn't work!
            fill: 'forwards'
          }]
        }
      }
    }
  },

      

Basically I want to div

hide after the animation finishes hide

. In the demo, you can see that the red div

disappears, but then reappears immediately after the animation ends.

+3


source to share


2 answers


I tracked down the source of the problem.

Open neon-animation-runner-behavior.html

and find the function playAnimation

.

Internally this._player.onfinish

, a note is called this._player.cancel()

. This one cancel

is basically

Set the source to null and clear any effects associated with the previous source.

Update



At the end, I added another parameter to the function playAnimation

, so when I need to enforce a final state, I add a flag false

to a function like this -

this.playAnimation('unloadCells', null, false);

      

This is the safest option I have come up with as it won't interrupt existing Polymer animations on different elements. I'm sure the Polymer team will be able to come up with a great solution in the future, but so far this is doing the trick. :)

playAnimation: function (type, cookie, cancellable) {
  // default its value to true so existing stuff won't be affected
  cancellable = typeof cancellable !== 'undefined' ? cancellable : true;

  var allConfigs = this.getAnimationConfig(type);
  if (!allConfigs) {
    return;
  }
  var allAnimations = this._configureAnimationEffects(allConfigs);
  var allEffects = allAnimations.map(function(animation) {
    return animation.effect;
  });

  if (allEffects.length > 0) {
    this._player = this._runAnimationEffects(allEffects);
    this._player.onfinish = function() {
      this._completeAnimations(allAnimations);

      if (this._player) {
        // when manually set to false, this._player.cancel() will be skipped 
        // so we get to maintain the end state for some scenarios
        if (cancellable) {
          this._player.cancel();
        }
        this._player = null;
      }

      this.fire('neon-animation-finish', cookie, {bubbles: false});
    }.bind(this);

  } else {
    this.fire('neon-animation-finish', cookie, {bubbles: false});
  }
},

      

+2


source


Use a listener to detect the end of the animation. Then call the function that hides the div.

properties: {
  animationConfig: {
    value: function () {
      return {
        'hide': [{
          name: 'fade-out-animation',
          node: this.$.rect,
        }]
      }
    }
  }
},

listeners: {
  // this event is fired when the animation finishes
  "neon-animation-finish": "animationComplete"
},

animationComplete: function() {
    this.$.rect.style.display = "none";
}

      

If you have many different animations to listen to to end, use a switch statement to separate each animation.

properties: {
  animationConfig: {
    value: function () {
      return {
        'hide': [{
          name: 'fade-out-animation',
          node: this.$.rect,
        }]
      }
    }
  }
},

listeners: {
  // this event is fired when the animation finishes
  "neon-animation-finish": "animationComplete"
},

animationComplete: function(event, animHandler) {
    switch (animHandler) {

        case "hide":
                this.hideFinished();
                break;

        case "show":
                this.showFinished();
                break;

        default: null

    }
},

hideFinished: function() {
//do something
},

showFinished: function() {
//do something
}

      



When using this method, you need to add a second parameter to the function playAnimation

that acts as an identifier. Like this:

this.playAnimation("hide", "hide");

      

Then, for each animation you add, just add another case to the switch statement with the value in the second parameter of the function playAnimation()

. I usually use the same line to keep track of it easily.

+1


source







All Articles