@@ -4,6 +4,12 @@ import { useIntervalFn } from '@vueuse/core';
44import { Maybe } from ' @/src/types' ;
55import { useSliceConfig } from ' @/src/composables/useSliceConfig' ;
66import { getCineImage } from ' @/src/core/cine/isCineImage' ;
7+ import {
8+ clampCineFps ,
9+ MAX_CINE_FPS ,
10+ MIN_CINE_FPS ,
11+ useCinePlaybackStore ,
12+ } from ' @/src/store/view-configs/cine-playback' ;
713
814type Props = {
915 viewId: string ;
@@ -15,28 +21,48 @@ const { imageId, viewId } = toRefs(props);
1521
1622const cine = computed (() => getCineImage (imageId .value ));
1723const { slice, range } = useSliceConfig (viewId , imageId );
24+ const playbackStore = useCinePlaybackStore ();
1825
19- const playing = ref (false );
20- const fps = ref (0 );
2126const fpsInput = ref (' ' );
2227
23- const MIN_FPS = 1 ;
24- const MAX_FPS = 120 ;
28+ const playbackConfig = computed (() =>
29+ playbackStore .getConfig (
30+ viewId .value ,
31+ imageId .value ,
32+ cine .value ?.header .frameTimeMs
33+ )
34+ );
2535
26- function setFps(value : number ) {
27- fps .value = value ;
28- fpsInput .value = value > 0 ? String (value ) : ' ' ;
36+ function updatePlayback(
37+ patch : Parameters <typeof playbackStore .updateConfig >[2 ]
38+ ) {
39+ if (! viewId .value || ! imageId .value ) return ;
40+ playbackStore .updateConfig (
41+ viewId .value ,
42+ imageId .value ,
43+ patch ,
44+ cine .value ?.header .frameTimeMs
45+ );
2946}
3047
48+ const playing = computed ({
49+ get : () => playbackConfig .value .playing ,
50+ set : (value : boolean ) => {
51+ updatePlayback ({ playing: value });
52+ },
53+ });
54+
55+ const fps = computed ({
56+ get : () => playbackConfig .value .fps ,
57+ set : (value : number ) => {
58+ updatePlayback ({ fps: value });
59+ },
60+ });
61+
3162watch (
32- cine ,
33- (image ) => {
34- if (! image ) {
35- setFps (0 );
36- return ;
37- }
38- const frameTime = image .header .frameTimeMs ;
39- setFps (frameTime && frameTime > 0 ? Math .round (1000 / frameTime ) : 24 );
63+ fps ,
64+ (value ) => {
65+ fpsInput .value = String (value );
4066 },
4167 { immediate: true }
4268);
@@ -56,24 +82,39 @@ const { pause, resume } = useIntervalFn(
5682 { immediate: false , immediateCallback: false }
5783);
5884
59- watch (playing , (isPlaying ) => {
60- if (isPlaying ) resume ();
61- else pause ();
62- });
85+ watch (
86+ playing ,
87+ (isPlaying ) => {
88+ if (isPlaying ) resume ();
89+ else pause ();
90+ },
91+ { immediate: true }
92+ );
6393
6494// Pause when the cine clip changes (or is removed).
65- watch (imageId , () => {
66- playing .value = false ;
95+ watch (imageId , (nextImageId , previousImageId ) => {
96+ if (previousImageId && previousImageId !== nextImageId && viewId .value ) {
97+ playbackStore .updateConfig (
98+ viewId .value ,
99+ previousImageId ,
100+ {
101+ playing: false ,
102+ },
103+ getCineImage (previousImageId )?.header .frameTimeMs
104+ );
105+ }
106+
107+ if (nextImageId && previousImageId !== nextImageId && viewId .value ) {
108+ updatePlayback ({ playing: false });
109+ }
67110});
68111
69112function togglePlay() {
70113 playing .value = ! playing .value ;
71114}
72115
73116function clampFpsValue(value : string | number ) {
74- const parsed = Number (value );
75- if (! Number .isFinite (parsed )) return null ;
76- return Math .min (MAX_FPS , Math .max (MIN_FPS , Math .round (parsed )));
117+ return clampCineFps (value );
77118}
78119
79120function clampFpsInput(event : Event ) {
@@ -83,13 +124,16 @@ function clampFpsInput(event: Event) {
83124
84125 const clamped = clampFpsValue (fpsInput .value );
85126 if (clamped == null ) return ;
86- setFps (clamped );
127+ fps .value = clamped ;
128+ fpsInput .value = String (clamped );
87129 input .value = fpsInput .value ;
88130}
89131
90132function commitFpsInput() {
91133 const clamped = clampFpsValue (fpsInput .value );
92- setFps (clamped ?? (fps .value > 0 ? fps .value : MIN_FPS ));
134+ const value = clamped ?? fps .value ;
135+ fps .value = value ;
136+ fpsInput .value = String (value );
93137}
94138 </script >
95139
@@ -108,8 +152,8 @@ function commitFpsInput() {
108152 <input
109153 :value =" fpsInput"
110154 type =" number"
111- :min =" MIN_FPS "
112- :max =" MAX_FPS "
155+ :min =" MIN_CINE_FPS "
156+ :max =" MAX_CINE_FPS "
113157 class =" fps-input"
114158 title =" Frames per second"
115159 @input =" clampFpsInput"
0 commit comments