Kitty Graphics Protocol in OCaml
terminal
graphics
ocaml
1(** Animation Control
2
3 Operations for controlling animation playback. The protocol supports
4 both terminal-driven and client-driven animation modes.
5
6 {2 Protocol Overview}
7
8 Animation control uses action [a=a] with various keys:
9 - [s]: Set playback state (1=stop, 2=loading, 3=run)
10 - [c]: Set current frame (1-based frame number)
11 - [r]: Target frame number for gap changes
12 - [z]: Frame gap/delay in milliseconds
13 - [v]: Loop count
14
15 {2 Terminal-Driven Animation}
16
17 The terminal automatically advances frames based on each frame's gap
18 (delay). To start terminal-driven animation:
19
20 {[
21 (* Start infinite loop *)
22 Kgp.animate ~image_id:1 (Animation.set_state ~loops:1 `Run)
23
24 (* Run 3 times then stop *)
25 Kgp.animate ~image_id:1 (Animation.set_state ~loops:4 `Run)
26
27 (* Stop animation *)
28 Kgp.animate ~image_id:1 (Animation.set_state `Stop)
29 ]}
30
31 {2 Client-Driven Animation}
32
33 The client manually controls which frame is displayed:
34
35 {[
36 (* Display specific frame *)
37 Kgp.animate ~image_id:1 (Animation.set_current_frame 5)
38
39 (* Advance to next frame in application logic *)
40 let next_frame = (current_frame mod total_frames) + 1 in
41 Kgp.animate ~image_id:1 (Animation.set_current_frame next_frame)
42 ]}
43
44 {2 Modifying Frame Timing}
45
46 Frame gaps can be changed during playback:
47
48 {[
49 (* Slow down frame 3 *)
50 Kgp.animate ~image_id:1 (Animation.set_gap ~frame:3 ~gap_ms:200)
51
52 (* Make frame 5 instant/gapless *)
53 Kgp.animate ~image_id:1 (Animation.set_gap ~frame:5 ~gap_ms:(-1))
54 ]}
55
56 {2 Loop Counting}
57
58 The [loops] parameter in {!set_state}:
59 - 0: Ignored (doesn't change loop setting)
60 - 1: Infinite loop
61 - n > 1: Loop (n-1) times, then stop *)
62
63type t =
64 [ `Set_state of Kgp_animation_state.t * int option
65 | `Set_gap of int * int
66 | `Set_current of int ]
67(** Animation control operations.
68
69 - [`Set_state (state, loops)] - Set animation playback state with
70 optional loop count.
71 - [`Set_gap (frame, gap_ms)] - Set the delay for a specific frame.
72 - [`Set_current frame] - Jump to a specific frame (1-based). *)
73
74val set_state : ?loops:int -> Kgp_animation_state.t -> t
75(** Set animation playback state.
76
77 @param loops Loop count: 0 = ignored, 1 = infinite, n > 1 = (n-1) loops.
78 Protocol key: [v].
79 @param state The target playback state.
80
81 Examples:
82 {[
83 set_state `Run (* Run with current loop setting *)
84 set_state ~loops:1 `Run (* Run infinitely *)
85 set_state ~loops:3 `Run (* Run twice, then stop *)
86 set_state `Stop (* Pause animation *)
87 set_state `Loading (* Run, wait for more frames at end *)
88 ]} *)
89
90val set_gap : frame:int -> gap_ms:int -> t
91(** Set the gap (delay) for a specific frame.
92
93 @param frame 1-based frame number to modify. Protocol key: [r].
94 @param gap_ms Delay in milliseconds before next frame. Negative values
95 create gapless frames (not displayed, instant skip). Protocol key: [z].
96
97 Note: Frame 1 is the root/base image. Use 2+ for added frames. *)
98
99val set_current_frame : int -> t
100(** Make a specific frame the current displayed frame.
101
102 @param frame 1-based frame number to display. Protocol key: [c].
103
104 Used for client-driven animation where the application controls
105 frame advancement rather than the terminal. *)