Skip to content

Commit

Permalink
fix: 🐛 start_time not updated on set_frame
Browse files Browse the repository at this point in the history
  • Loading branch information
theashraf committed Jan 25, 2024
1 parent 668ee6c commit 63753f7
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 25 deletions.
52 changes: 30 additions & 22 deletions dotlottie-rs/src/dotlottie_player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,27 +117,7 @@ impl DotLottieRuntime {
pub fn play(&mut self) -> bool {
if self.is_loaded && !self.is_playing() {
if self.is_paused() {
let start_frame = self.start_frame();
let end_frame = self.end_frame();

let total_frames = self.total_frames();
let duration = self.duration();
let effective_total_frames = end_frame - start_frame;
let effective_duration =
(duration * effective_total_frames / total_frames) / self.config.speed;

let current_frame = self.current_frame().clamp(start_frame, end_frame);
let frame_duration = effective_duration / effective_total_frames;

// estimate elapsed time for current frame based on direction and segments
let elapsed_time_for_current_frame = match self.direction {
Direction::Forward => (current_frame - start_frame) * frame_duration,
Direction::Reverse => (end_frame - current_frame) * frame_duration,
};

// update start_time to account for the already elapsed time
self.start_time =
Instant::now() - Duration::from_secs_f32(elapsed_time_for_current_frame);
self.update_start_time_for_frame(self.current_frame());
} else {
self.start_time = Instant::now();
}
Expand Down Expand Up @@ -327,8 +307,36 @@ impl DotLottieRuntime {
}
}

fn update_start_time_for_frame(&mut self, frame_no: f32) {
let start_frame = self.start_frame();
let end_frame = self.end_frame();

let total_frames = self.total_frames();
let duration = self.duration();
let effective_total_frames = end_frame - start_frame;
let effective_duration =
(duration * effective_total_frames / total_frames) / self.config.speed;

let frame_duration = effective_duration / effective_total_frames;

// estimate elapsed time for current frame based on direction and segments
let elapsed_time_for_frame = match self.direction {
Direction::Forward => (frame_no - start_frame) * frame_duration,
Direction::Reverse => (end_frame - frame_no) * frame_duration,
};

// update start_time to account for the already elapsed time
self.start_time = Instant::now() - Duration::from_secs_f32(elapsed_time_for_frame);
}

pub fn set_frame(&mut self, no: f32) -> bool {
self.renderer.set_frame(no).is_ok()
let is_ok = self.renderer.set_frame(no).is_ok();

if self.is_playing() {
self.update_start_time_for_frame(no);
}

is_ok
}

pub fn render(&mut self) -> bool {
Expand Down
37 changes: 34 additions & 3 deletions web-example.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
step="0.01"
/>
</div>
<button id="jump">Jump</button>
<script type="module">
import createDotLottiePlayerModule from "./release/wasm/DotLottiePlayer.mjs";

const playBtn = document.querySelector("#play");
const pauseBtn = document.querySelector("#pause");
const progressBar = document.querySelector("#progress-bar");
const jumpBtn = document.querySelector("#jump");

const Module = await createDotLottiePlayerModule({
locateFile: (path, prefix) => {
Expand Down Expand Up @@ -82,7 +84,7 @@
dotLottiePlayer.setConfig({
...dotLottiePlayer.config(),
mode: Module.Mode.values[3],
segments: createSegments(20, 80),
segments: createSegments(),
});

console.log("Loaded: ", loaded);
Expand All @@ -96,6 +98,8 @@
const ctx = canvas.getContext("2d");
const imageData = ctx.createImageData(width, height);

let animationFrameId = null;

function animationLoop() {
const nextFrameNumber = dotLottiePlayer.requestFrame();
// console.log(nextFrameNumber);
Expand All @@ -116,10 +120,10 @@
}
}

requestAnimationFrame(animationLoop);
animationFrameId = requestAnimationFrame(animationLoop);
}

requestAnimationFrame(animationLoop);
animationFrameId = requestAnimationFrame(animationLoop);

playBtn.addEventListener("click", () => {
dotLottiePlayer.play();
Expand All @@ -128,6 +132,33 @@
pauseBtn.addEventListener("click", () => {
dotLottiePlayer.pause();
});

jumpBtn.addEventListener("click", () => {
dotLottiePlayer.setFrame(44);
});

progressBar.addEventListener("mousedown", () => {
cancelAnimationFrame(animationFrameId);
});

progressBar.addEventListener("mouseup", () => {
animationFrameId = requestAnimationFrame(animationLoop);
});

progressBar.addEventListener("input", (event) => {
const newFrame =
(event.target.value / 100) * dotLottiePlayer.totalFrames();

const updated = dotLottiePlayer.setFrame(newFrame);
if (updated) {
const rendered = dotLottiePlayer.render();
if (rendered) {
const frameBuffer = dotLottiePlayer.buffer();
imageData.data.set(frameBuffer);
ctx.putImageData(imageData, 0, 0);
}
}
});
</script>
</body>
</html>

0 comments on commit 63753f7

Please sign in to comment.