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. *)