@@ -46,6 +46,8 @@ const { isPrintMode } = useNav()
4646const id = makeId ()
4747
4848const stepIndex = ref (0 )
49+ // Used to skip the animation on the first tick.
50+ const isFirstTick = ref (true )
4951const container = ref <HTMLElement >()
5052
5153const showCopyButton = computed (() => {
@@ -93,6 +95,7 @@ onMounted(() => {
9395 const clickInfo = clicks .calculateSince (props .at , clickCounts - 1 )
9496 clicks .register (id , clickInfo )
9597
98+ let cancelTick: () => void = () => { }
9699 watch (
97100 () => clicks .current ,
98101 () => {
@@ -111,9 +114,24 @@ onMounted(() => {
111114 currentClickSum += current .length || 1
112115 }
113116
117+ // It seems ticks may not be executed in order. Cancel previous ones, because
118+ // clicks.current is first 0 then immediately updated when refreshing the slide.
119+ cancelTick ()
120+ let isCanceled = false
121+ cancelTick = () => {
122+ isCanceled = true
123+ }
124+
114125 nextTick (async () => {
126+ if (isCanceled ) {
127+ return
128+ }
115129 stepIndex .value = step
116-
130+ if (isFirstTick .value ) {
131+ nextTick (() => {
132+ isFirstTick .value = false
133+ })
134+ }
117135 await sleep (0 )
118136
119137 const pre = container .value ?.querySelector (' .shiki' ) as HTMLElement
@@ -162,7 +180,10 @@ onMounted(() => {
162180 :animate =" !isPrintMode"
163181 :options =" {
164182 globalScale: scale * zoom,
165- duration: $props.duration,
183+ // Use duration 0 to skip animation instead of using the animate prop,
184+ // because moving from non-animated to animated causes issues with
185+ // new elements. Unfortunately, this causes a flash.
186+ duration: isFirstTick ? 0 : $props.duration,
166187 stagger: 1,
167188 }"
168189 />
0 commit comments