diff --git a/demo/starter/slides.md b/demo/starter/slides.md index 9e65e48145..e6c3a1a7da 100644 --- a/demo/starter/slides.md +++ b/demo/starter/slides.md @@ -45,6 +45,7 @@ The last comment block of each slide will be treated as slide notes. It will be --- transition: fade-out +split: 30 --- # What is Slidev? @@ -87,6 +88,7 @@ Here is another comment. --- transition: slide-up level: 2 +split: 60 --- # Navigation diff --git a/packages/client/composables/useNav.ts b/packages/client/composables/useNav.ts index e1500c42a4..1cf03a09b2 100644 --- a/packages/client/composables/useNav.ts +++ b/packages/client/composables/useNav.ts @@ -5,7 +5,7 @@ import { slides } from '#slidev/slides' import { clamp } from '@antfu/utils' import { parseRangeString } from '@slidev/parser/utils' import { createSharedComposable } from '@vueuse/core' -import { computed, ref, watch } from 'vue' +import { computed, ref, toRaw, watch } from 'vue' import { useRoute, useRouter } from 'vue-router' import { CLICKS_MAX } from '../constants' import { configs } from '../env' @@ -292,6 +292,16 @@ const useNavState = createSharedComposable((): SlidevContextNavState => { const currentSlideRoute = computed(() => slides.value[currentSlideNo.value - 1]) const printRange = ref(parseRangeString(slides.value.length, currentRoute?.query?.range as string | undefined)) + watch(currentSlideRoute, () => { + window.dispatchEvent(new CustomEvent('slidev-slide-changed', { + detail: { + slideNumber: currentSlideNo.value, + slide: toRaw(currentSlideRoute.value?.meta.slide), + frontmatter: toRaw(currentSlideRoute.value?.meta.slide.frontmatter), + }, + })) + }) + const queryClicksRaw = useRouteQuery('clicks', '0') const clicksContext = computed(() => getPrimaryClicks(currentSlideRoute.value)) diff --git a/packages/client/pages/presenter.vue b/packages/client/pages/presenter.vue index 0ad2ae3075..6e9b5898aa 100644 --- a/packages/client/pages/presenter.vue +++ b/packages/client/pages/presenter.vue @@ -88,6 +88,21 @@ const SideEditor = shallowRef() if (__DEV__ && __SLIDEV_FEATURE_EDITOR__) import('../internals/SideEditor.vue').then(v => SideEditor.value = v.default) +function parseTimerString(timeString: string) { + const [seconds, minutes = 0, hours = 0] = timeString.split(':').toReversed().map(n => Number.parseInt(n, 10)) + return hours * 3600 + minutes * 60 + seconds +} + +window.addEventListener('slidev-slide-changed', (e) => { + const timerCounter = parseTimerString(timer.value) + const splitCounter = typeof (e as CustomEvent).detail.frontmatter.split === 'string' ? parseTimerString((e as CustomEvent).detail.frontmatter.split) : (e as CustomEvent).detail.frontmatter.split || 0 + + if (splitCounter) { + const delta = timerCounter - splitCounter + console.warn('delta', delta) + } +}) + // sync presenter cursor onMounted(() => { const slidesContainer = main.value!.querySelector('#slide-content')!