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

[feature request]: Record/replay css animation's currentTime #1491

Open
1 task done
oceanMa1 opened this issue Jun 4, 2024 · 6 comments
Open
1 task done

[feature request]: Record/replay css animation's currentTime #1491

oceanMa1 opened this issue Jun 4, 2024 · 6 comments
Labels
bug Something isn't working feature request Things want to be added

Comments

@oceanMa1
Copy link

oceanMa1 commented Jun 4, 2024

Preflight Checklist

  • I have searched the issue tracker for a bug report that matches the one I want to file, without success.

What package is this bug report for?

rrweb

Version

2.0.0-alpha.13

Expected Behavior

When I use checkoutEveryNms: 2000 for recording, if the content being recorded contains animation, then every 2s this animation will be triggered repeatedly during playback. However, it works normally if checkoutEveryNms are not used.

Actual Behavior

When I use checkoutEveryNms: 2000 for recording, if the content being recorded contains animation, then every 2s this animation will be triggered repeatedly during playback. However, it works normally if checkoutEveryNms are not used.

Steps to Reproduce

<template>
  <div id="container" style="display: flex">
    <div
      id="container2"
      style="border: 1px solid; width: 800px; height: 600px"
    ></div>
    <div
    v-if="showTable"
    class="animate__animated animate__fadeInUp" 
    >animate__fadeInUp
    animate__fadeInUp
    animate__fadeInUp</div>
    <div>
      <button @click="showTable=true">Show</button>
      <button @click="rePlay">Replay</button>
    </div>
  </div>
</template>
<script setup>
import * as rrweb from 'rrweb';
import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
import { onMounted, ref } from 'vue';
import 'animate.css';
const showTable=ref(false);
let events = [];

onMounted(() => {
  _initRecorder();
});
const _initRecorder = () => {
  rrweb.record({
  checkoutEveryNms: 2000,
  emit(event) {
    events.push(event);
  },
  });
}
const rePlay = () => {
  const replayer =new rrwebPlayer({
    target: document.getElementById('container2'), 
    props: {
      events,
    },
  });
};
</script>

Testcase Gist URL

https://rrwebdebug.com/play/index.html?url=https%3A%2F%2Fgist.github.com%2Fmhy17376555322%2F775375301a91079cc13a0e06dc44eafe&version=2.0.0-alpha.13&virtual-dom=on&play=on

Additional Information

No response

@oceanMa1 oceanMa1 added the bug Something isn't working label Jun 4, 2024
@oceanMa1 oceanMa1 changed the title [Bug]: [Bug]: Animation repetition triggering Jun 4, 2024
@Juice10
Copy link
Contributor

Juice10 commented Jun 5, 2024

You've found a tricky one @oceanMa1, to get this working we'd need to call document.getAnimations() and register the currentTime of each animation. And then of course we'd also have set these currentTime on animation replay as well.

Also we can listen for animationstart events on window/document which will let us know when an animation was started: https://developer.mozilla.org/en-US/docs/Web/API/Element/animationstart_event same for animationend

@Juice10
Copy link
Contributor

Juice10 commented Jun 5, 2024

This is very much related to #1143

@Juice10 Juice10 changed the title [Bug]: Animation repetition triggering [feature request]: Record/replay css animation's currentTime Jun 5, 2024
@eoghanmurray
Copy link
Contributor

Is the problem caused because the checkouteverynth approach creates a FullSnapshot event which causes an entire rebuild of the replayer state?
If that's the case, I wonder would some sort of diff application via rrdom be the right thing to do instead, whereby an animation would naturally avoid being retriggered if it's dom hasn't changed?

@oceanMa1
Copy link
Author

oceanMa1 commented Jun 7, 2024

I think you're correct. When I replay and filter out all the snapshots after the first one, this issue can be resolved. The code is as follows. @Juice10

const rePlay = () => {
  const filtered =[]
  let firstSnapshotFind =false
  events.forEach((item)=>{
    if (!firstSnapshotFind){
      filtered.push(item)
    }else if (item.type!=2&&item.type!=4){//Filter the snapshot behind
      filtered.push(item)
    } 
    if (!firstSnapshotFind&&item.type==2){
      firstSnapshotFind=true
    }
  })
  const replayer =new rrwebPlayer({
    target: document.getElementById('container2'), 
    props: {
      events:filtered,
    },
  });
};

@Juice10
Copy link
Contributor

Juice10 commented Jun 11, 2024

Is the problem caused because the checkouteverynth approach creates a FullSnapshot event which causes an entire rebuild of the replayer state?

I think that is exactly what is happening, entire rebuild is triggering the animation every time it's rebuilt.

If that's the case, I wonder would some sort of diff application via rrdom be the right thing to do instead, whereby an animation would naturally avoid being retriggered if its dom hasn't changed?

That would also solve this issue in this instance I think. And it could really help for performance by eliminating repaints.

@eoghanmurray
Copy link
Contributor

We don't use checkouteverynth and I don't understand why that is a preferred approach as it must massively increase the size of recordings.

And it could really help for performance by eliminating repaints.

Yes; although you probably want a full refresh for a regular FullSnapshot (as probably calculating the diff would be more work than replacing and e.g you might actually want to do the full refresh to restart animations)

Would using some of the other approaches instead of checkouteverynth solve this for you or is that not an option?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working feature request Things want to be added
Projects
None yet
Development

No branches or pull requests

3 participants