返回 slidev
SlideWrapper.vue
根目录 / packages / client / internals / SlideWrapper.vue
1 <script setup lang="ts">
2 import type { ClicksContext, RenderContext, SlideRoute } from '@slidev/types'
3 import type { CSSProperties, PropType } from 'vue'
4 import { provideLocal } from '@vueuse/core'
5 import { computed, ref, toRef } from 'vue'
6 import { SlideBottom, SlideTop } from '#slidev/global-layers'
7 import { injectionClicksContext, injectionCurrentPage, injectionFrontmatter, injectionRenderContext, injectionRoute, injectionSlideZoom } from '../constants'
8 import { configs } from '../env'
9 import { getSlideClass } from '../utils'
10
11 const props = defineProps({
12 clicksContext: {
13 type: Object as PropType<ClicksContext>,
14 required: true,
15 },
16 renderContext: {
17 type: String as PropType<RenderContext>,
18 default: 'slide',
19 },
20 route: {
21 type: Object as PropType<SlideRoute>,
22 required: true,
23 },
24 })
25
26 const zoom = computed(() => props.route.meta?.slide?.frontmatter.zoom ?? 1)
27
28 provideLocal(injectionRoute, props.route)
29 provideLocal(injectionFrontmatter, props.route.meta.slide.frontmatter)
30 provideLocal(injectionCurrentPage, ref(props.route.no))
31 provideLocal(injectionRenderContext, ref(props.renderContext))
32 provideLocal(injectionClicksContext, toRef(props, 'clicksContext'))
33 provideLocal(injectionSlideZoom, zoom)
34
35 const style = computed<CSSProperties>(() => ({
36 'user-select': configs.selectable ? undefined : 'none',
37 '--slidev-slide-zoom-scale': zoom.value === 1 ? undefined : zoom.value,
38 }))
39 </script>
40
41 <template>
42 <div
43 :data-slidev-no="props.route.no"
44 :class="getSlideClass(route, ['slide', 'presenter'].includes(props.renderContext) ? '' : 'disable-view-transition')"
45 :style="style"
46 :lang="props.route.meta.slide.frontmatter.lang"
47 >
48 <SlideBottom />
49 <component :is="props.route.component" />
50 <SlideTop />
51 </div>
52 </template>
53
54 <style scoped>
55 .disable-view-transition:deep(*) {
56 view-transition-name: none !important;
57 }
58
59 .slidev-page {
60 position: absolute;
61 inset: 0;
62
63 /* Zoom handling */
64 --slidev-slide-zoom-scale: 1;
65 width: calc(100% / var(--slidev-slide-zoom-scale));
66 height: calc(100% / var(--slidev-slide-zoom-scale));
67 transform-origin: top left;
68 scale: var(--slidev-slide-zoom-scale);
69 /* slide scale = container scale * zoom scale */
70 --slidev-slide-scale: calc(var(--slidev-slide-container-scale) * var(--slidev-slide-zoom-scale));
71 }
72 </style>
73
73 lines Plain Text