Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
recording). `Shift+S` is used to start a recording. (#270)
- Diagnostics on `slipshow compile` are sorted by location (#277)
- Improve location of "Wrong Type" diagnostic (#277)
- Hint that step counter and toc entries are clickable. (#278)
- Pressing play in drawing editor when the cursor is at the end of the recording
now replays from the beginning. (#278)
- Round sub-millisecond time precision in drawing editor. (#278)

### Fixed

Expand All @@ -38,6 +42,9 @@
- Improve uri vs local path detection. (#271)
- Improve locations of errors in `css:` and `js:` frontmatter fields. (#271)
- Allow spaces and tabs after frontmatter delimiters. (#275)
- Fix drawing replay in editor stuck on a pause. (#278)
- Fix last point of a stroke not being displayed when the recording ends at this
time. (#278)

### Docs

Expand Down
43 changes: 10 additions & 33 deletions src/engine/runtime/drawing/drawing_controller/ui.ml
Original file line number Diff line number Diff line change
Expand Up @@ -167,40 +167,17 @@ let global_panel recording =

let play (replaying_state : replaying_state) =
Lwd.set replaying_state.is_playing true;
let max = Lwd.peek replaying_state.recording.total_time in
let start_time = now () -. Lwd.peek replaying_state.time in
let current_time = ref @@ Tools.now () in
let rec loop _ =
let now = Tools.now () in
let increment = now -. !current_time in
current_time := now;
let now = now -. start_time in
let before = now -. increment in
let has_crossed_pause =
Lwd_table.fold
(fun b (pause : Drawing_state.pause) ->
match b with
| Some _ as b -> b
| None ->
let at = Lwd.peek pause.p_at in
if before <= at && at < now then Some at else None)
None replaying_state.recording.pauses
in
match has_crossed_pause with
| Some max_time ->
Lwd.set replaying_state.time (Float.next_after max_time Float.infinity);
Lwd.set replaying_state.is_playing false
| None ->
if now <= max && Lwd.peek replaying_state.is_playing then
let () = Lwd.set replaying_state.time now in
let _animation_frame_id = Brr.G.request_animation_frame loop in
()
else if now > max && Lwd.peek replaying_state.is_playing then
let () = Lwd.set replaying_state.time max in
Lwd.set replaying_state.is_playing false
else ()
let () =
if
Lwd.peek replaying_state.time
>= Lwd.peek replaying_state.recording.total_time
then Lwd.set replaying_state.time 0.
in
loop 0.
Drawing_state.play
~continue:(fun () ->
if Lwd.peek replaying_state.is_playing then `Continue else `Stop)
~finish:(fun () -> Lwd.set replaying_state.is_playing false)
replaying_state

let play_button editing_state =
let$* is_playing = Lwd.get editing_state.is_playing in
Expand Down
7 changes: 4 additions & 3 deletions src/engine/runtime/drawing/drawing_controller/ui_widgets.ml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let float ?(callback = fun _ -> ()) ?(ev = []) ?st ?(prop = []) ?type'
let el = ev |> Brr.Ev.target |> Brr.Ev.target_to_jv in
let new_value = Jv.get el "value" |> Jv.to_string |> float_of_string in
callback new_value;
Lwd.set var new_value;
if Brr.Ev.is_trusted ev then Lwd.set var new_value;
Comment thread
panglesd marked this conversation as resolved.
let () =
let el = ev |> Brr.Ev.target |> Brr.Ev.target_to_jv |> Brr.El.of_jv in
(* We unfocus so that shortcuts work *)
Expand All @@ -29,8 +29,9 @@ let float ?(callback = fun _ -> ()) ?(ev = []) ?st ?(prop = []) ?type'
in
let prop =
let v =
let$ v = Lwd.get var in
(Jstr.v "value", Jv.of_float v)
let$ f = Lwd.get var in
let i = Float.to_int f in
(Jstr.v "value", Jv.of_int i)
in
`R v :: prop
in
Expand Down
56 changes: 56 additions & 0 deletions src/engine/runtime/drawing/drawing_state/drawing_state.ml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,62 @@ let finish_recording
recording_temp;
Status.set Editing

let play ?(speedup = 1.) ?(continue = fun () -> `Continue) ~finish state =
let start_replay = now () in
let original_time = Lwd.peek state.time in
let max_time = Lwd.peek state.recording.total_time in
let max_time = Float.next_after max_time Float.infinity in
(* Timestamp of the frame preceding the one being computed *)
let previous_frame = ref start_replay in
let time_of frame = original_time +. ((frame -. start_replay) *. speedup) in
let skip_to_next_pause () =
let from = Lwd.peek state.time in
let next_time =
Lwd_table.fold
(fun acc pause ->
let at = Lwd.peek pause.p_at in
if at <= from then acc else Float.min acc at)
max_time state.recording.pauses
in
Lwd.set state.time next_time;
finish ()
in
let rec loop _ =
match continue () with
| `Stop -> ()
| `Skip_to_next_pause -> skip_to_next_pause ()
| `Continue -> (
let frame = now () in
let time_before = time_of !previous_frame in
let new_time = time_of frame in
previous_frame := frame;
let crossed_pause =
Lwd_table.fold
(fun acc pause ->
let at = Lwd.peek pause.p_at in
if time_before < at && at <= new_time then
match acc with
| Some earliest when earliest < at -> acc
| _ -> Some at
else acc)
None state.recording.pauses
in
match crossed_pause with
| Some at ->
Lwd.set state.time at;
finish ()
Comment thread
coderabbitai[bot] marked this conversation as resolved.
| None ->
if new_time > max_time then (
Lwd.set state.time max_time;
finish ())
else (
Lwd.set state.time new_time;
let _animation_frame_id = Brr.G.request_animation_frame loop in
()))
in
let _animation_frame_id = Brr.G.request_animation_frame loop in
()

type selection = {
s_strokes : (stro Lwd_table.row * stro) list;
s_erasures : (stro * erased) list;
Expand Down
74 changes: 10 additions & 64 deletions src/engine/runtime/step/actions_.ml
Original file line number Diff line number Diff line change
Expand Up @@ -799,71 +799,17 @@ module Draw = struct

let setup = Some setup

let replay ?(speedup = 1.) mode (record : Drawing_state.replaying_state) =
let replay ?speedup mode (record : Drawing_state.replaying_state) =
let fut, resolve_fut = Fut.create () in
let start_replay = Drawing_controller.Tools.now () in
let original_time = Lwd.peek record.time in
let max_time = Lwd.peek record.recording.total_time in
let current_time = ref @@ Drawing_controller.Tools.now () in
let rec draw_loop _ =
let when_slow () =
let now = Drawing_controller.Tools.now () in
let increment = now -. !current_time in
current_time := now;
let before = now -. increment in
let new_time = original_time +. ((now -. start_replay) *. speedup) in
let time_before =
original_time +. ((before -. start_replay) *. speedup)
in
let has_crossed_pause =
Lwd_table.fold
(fun b (pause : Drawing_state.pause) ->
match b with
| Some _ as b -> b
| None ->
let at = Lwd.peek pause.p_at in
if time_before <= at && at < new_time then Some at else None)
None record.recording.pauses
in
Lwd.set record.time new_time;
match has_crossed_pause with
| Some max_time ->
Lwd.set record.time (Float.next_after max_time Float.infinity);
resolve_fut ()
| None ->
if new_time >= max_time then (
Lwd.set record.time max_time;
resolve_fut ())
else
let _animation_frame_id = G.request_animation_frame draw_loop in
()
in
match mode with
| Fast.Slow -> when_slow ()
| Fast.Normal hurry_bomb when not (Fast.has_detonated hurry_bomb) ->
when_slow ()
| _ ->
let now = Drawing_controller.Tools.now () in
let increment = now -. !current_time in
current_time := now;
let before = now -. increment in
let time_before =
original_time +. ((before -. start_replay) *. speedup)
in
let next_time =
Lwd_table.fold
(fun acc (pause : Drawing_state.pause) ->
let at = Lwd.peek pause.p_at in
if at < time_before then acc
else Float.min acc (Float.next_after at (at +. 1.)))
(Lwd.peek record.recording.total_time)
record.recording.pauses
in
Lwd.set record.time next_time;
resolve_fut ()
(* | Counting_for_toc -> assert false (\* See "only_if_not_fast" *\) *)
in
let _animation_frame_id = G.request_animation_frame draw_loop in
Drawing_state.play ?speedup
~continue:(fun () ->
match mode with
| Fast.Slow -> `Continue
| Fast.Normal hurry_bomb when not (Fast.has_detonated hurry_bomb) ->
`Continue
| _ -> `Skip_to_next_pause
(* | Counting_for_toc -> assert false (\* See "only_if_not_fast" *\) *))
~finish:resolve_fut record;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
fut

type js_args = El.t list
Expand Down
4 changes: 4 additions & 0 deletions src/engine/runtime/step/step.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
pointer-events: none;
}

#slipshow-counter:hover {
text-decoration: underline;
}

#slipshow-counter {
position: absolute;
bottom: 0;
Expand Down
4 changes: 4 additions & 0 deletions src/engine/runtime/table_of_content/table_of_content.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
display: inline-block;
}

.slipshow-toc-step:hover {
box-shadow: 2px 2px 2px black;
}

.slipshow-toc-entry {
cursor: pointer;
}
Expand Down
Loading