web-animations/web-animations-js

.finished Promise does not exist in Safari

tomciopp opened this issue · 2 comments

If you run a sequence of promises and you are relying on finished property it will fail in Safari.
After doing some research, I stumbled upon this polyfill that fixes the issue and am pasting it here in case it helps anyone else. Ideally this library should include this code as well.

// only polyfill .finished in browsers that already support animate()
if (document.body.animate) {

  // Chrome does not seem to expose the Animation constructor globally
  if (typeof Animation === "undefined") {
    window.Animation = document.body.animate({}).constructor;
  }

  if (!Animation.prototype.hasOwnProperty("finished")) {
    Object.defineProperty(Animation.prototype, "finished", {
      get() {
        if (!this._finished) {
          this._finished = this.playState === "finished" ?
            Promise.resolve() :
            new Promise((resolve, reject) => {
              this.addEventListener("finish", resolve, { once: true });
              this.addEventListener("cancel", reject, { once: true });
            });
        }
        return this._finished;
      }
    });
  }
}
motss commented

Not only Safari. Chrome does not support that too. Alternatively, you can leverage finish event to achieve the same result:

const divEl = document.body.querySelector('.animatable');
const fadeOutAnimation = new Promise(yay => divEl.animate([
 { opacity: '1' },
 { opacity: '0' },
]).onfinish = yay);

fadeOutAnimation.then(() => /** Do more stuff */);