修改动画播放状态会影响动画与音频的同步。

huangapple go评论54阅读模式
英文:

Altering animation play state messes up my animation synching with audio

问题

I am syncing a div scrolling effect animation with an audio, the syncing works fine when I set the element.style.animation property to 'none' when the audio is paused. The problem is when I try to pause the animation instead when the audio is paused. When I pause and play multiple times, the animation is not synced with the audio anymore (animation is too advanced).

//This is the audio element
const pupHymn = document.querySelector(".pup-hymn");
//This is the container div of the lyrics
const hymnLyrics = document.querySelector(".lyrics");

const init = () => {
    pupHymn.volume = 0.3;
    // Sync when playing manually 
    pupHymn.addEventListener('play', () => {
        audioTime = pupHymn.currentTime;
        playbackRate = pupHymn.playbackRate;
        hymnLyrics.style.animation = `scroll-effect ${160/playbackRate}s ${(12-audioTime)/playbackRate}s forwards running`;
    );

    pupHymn.addEventListener('pause', () => {
        hymnLyrics.style.animation = 'none';
    });

    // This works fine.
    pupHymn.addEventListener('pause', () => {
        hymnLyrics.style.animation = 'none';
    });
}

But when I paused the animationPlayState instead, it won't sync properly when I pause and play multiple times.

pupHymn.addEventListener('pause', () => {
    hymnLyrics.style.animationPlayState = 'paused';
});

I already have tried logging the animation property of my div when the audio will be played, even though the delay is still a positive value, the animation started already.

英文:

I am synching a div scrolling effect animation with an audio, the synching works fine when I set the element.style.animation property to 'none' when the audio is paused. The problem is when I try to pause the animation instead when the audio is paused. When I pause and play multiple times, the animation is not synched with the audio anymore (animation is too advanced).

//This is the audio element
const pupHymn = document.querySelector(".pup-hymn");
//This is the container div of the lyrics
const hymnLyrics = document.querySelector(".lyrics");

const init = () => {
    pupHymn.volume = 0.3;
    //Sync when playing manually 
    pupHymn.addEventListener('play', () => {
        audioTime = pupHymn.currentTime;
        playbackRate = pupHymn.playbackRate;
        hymnLyrics.style.animation = `scroll-effect ${160/playbackRate}s ${(12-audioTime)/playbackRate}s forwards running`;
    );

    pupHymn.addEventListener('pause', () => {
        hymnLyrics.style.animation = 'none'; 
    });

//This works fine.
pupHymn.addEventListener('pause', () => {
        hymnLyrics.style.animation = 'none'; });
}

But when I paused the animationPlayState instead, it won't synch properly when I pause and play multiple times.

pupHymn.addEventListener('pause', () => {
        hymnLyrics.style.animationPlayState = 'paused'; });

I already have tried logging the animation property of my div when the audio will be played, even though the delay is still a positive value, the animation started already.

答案1

得分: 1

以下是代码部分的翻译:

const audio = document.querySelector("audio");
const target = document.querySelector(".content");
audio.addEventListener("loadedmetadata", (evt) => {
  const { duration } = audio;
  const keys = new KeyframeEffect(
    target,
    [{ transform: "translate(0px, -1300px)" },],
    { duration: duration * 1000, fill: "forwards" }
  );
  const anim = new Animation(keys);
  const sync = () => anim.currentTime = audio.currentTime * 1000;
  audio.addEventListener("seeked", sync);
  audio.addEventListener("play", () => {
    sync();
    anim.play();
  });
  audio.addEventListener("pause", () => {
    anim.pause();
    sync();
  });
}, { once: true });
for (let i = 0; i < 46; i++) {
  const el = document.createElement("p");
  el.textContent = i;
  target.append(el);
}
.container {
  width: 300px;
  height: 300px;
  border: 1px solid;
  overflow: hidden;
}
.content {
  height: 1600px;
  background-image: linear-gradient(to bottom, red, blue);
}
.content p {
  margin-top: 0;
}
<audio controls src="https://upload.wikimedia.org/wikipedia/en/transcoded/d/dc/Strawberry_Fields_Forever_%28Beatles_song_-_sample%29.ogg/Strawberry_Fields_Forever_%28Beatles_song_-_sample%29.ogg.mp3"></audio>
<div class=container>
  <div class="content"></div>
</div>

如果您有任何其他翻译需求,请告诉我。

英文:

The most reliable way here is probably through the Web Animation API, which allows you to manage the current time of your animation with relatively high precision. You can hook to some events on your &lt;audio&gt; element and map its .currentTime to the Animation's one (beware the former is in seconds while the latter is in milliseconds).

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const audio = document.querySelector(&quot;audio&quot;);
const target = document.querySelector(&quot;.content&quot;);
audio.addEventListener(&quot;loadedmetadata&quot;, (evt) =&gt; {
  const { duration } = audio;
  const keys = new KeyframeEffect(
    target,
    [{ transform: &quot;translate(0px, -1300px)&quot; },],
    { duration: duration * 1000, fill: &quot;forwards&quot; }
  );
  const anim = new Animation(keys);
  const sync = () =&gt; anim.currentTime = audio.currentTime * 1000;
  audio.addEventListener(&quot;seeked&quot;, sync);
  audio.addEventListener(&quot;play&quot;, () =&gt; {
    sync();
    anim.play();
  });
  audio.addEventListener(&quot;pause&quot;, () =&gt; {
    anim.pause();
    sync();
  });
}, { once: true });
for (let i = 0; i &lt; 46; i++) {
  const el = document.createElement(&quot;p&quot;);
  el.textContent = i;
  target.append(el);
}

<!-- language: lang-css -->

.container {
  width: 300px;
  height: 300px;
  border: 1px solid;
  overflow: hidden;
}
.content {
  height: 1600px;
  background-image: linear-gradient(to bottom, red, blue);
}
.content p {
  margin-top: 0;
}

<!-- language: lang-html -->

&lt;audio controls src=&quot;https://upload.wikimedia.org/wikipedia/en/transcoded/d/dc/Strawberry_Fields_Forever_%28Beatles_song_-_sample%29.ogg/Strawberry_Fields_Forever_%28Beatles_song_-_sample%29.ogg.mp3&quot;&gt;&lt;/audio&gt;

&lt;div class=container&gt;
  &lt;div class=&quot;content&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月11日 10:38:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75982033.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定