| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- <template>
- <div
- class="thumbnail-slide"
- :style="{
- width: size + 'px',
- height: size * 0.5625 + 'px',
- }"
- >
- <!-- viewportRatio -->
- <div
- class="elements"
- :style="{
- width: viewportSize + 'px',
- height: viewportSize * viewportRatio + 'px',
- transform: `scale(${scale})`,
- position: 'absolute',
- }"
- v-if="visible"
- >
- <div class="background" :style="backgroundStyle"></div>
- <ThumbnailElement
- v-for="(element, index) in slide.elements"
- :key="element.id"
- :scale="scale"
- :slide="slide"
- :elementInfo="element"
- :elementIndex="index + 1"
- />
- <!-- 遮罩层:确保iframe不会阻止缩略图点击事件 -->
- <div class="thumbnail-mask" @click="handleMaskClick"></div>
- </div>
- <div class="placeholder" v-else>{{ lang.ssLoading }}</div>
- </div>
- </template>
- <script lang="ts" setup>
- import { computed, provide } from "vue";
- import { storeToRefs } from "pinia";
- import { useSlidesStore } from "@/store";
- import type { Slide } from "@/types/slides";
- import { injectKeySlideScale } from "@/types/injectKey";
- import useSlideBackgroundStyle from "@/hooks/useSlideBackgroundStyle";
- import { lang } from "@/main";
- import ThumbnailElement from "./ThumbnailElement.vue";
- const props = withDefaults(
- defineProps<{
- slide: Slide;
- size: number;
- visible?: boolean;
- }>(),
- {
- visible: true,
- }
- );
- const emit = defineEmits<{
- (event: "click"): void;
- }>();
- // 处理遮罩层点击事件
- const handleMaskClick = (e: MouseEvent) => {
- e.stopPropagation();
- emit("click");
- };
- const { viewportRatio, viewportSize } = storeToRefs(useSlidesStore());
- const background = computed(() => props.slide.background);
- const { backgroundStyle } = useSlideBackgroundStyle(background);
- const scale = computed(() => props.size / viewportSize.value);
- provide(injectKeySlideScale, scale);
- </script>
- <style lang="scss" scoped>
- .thumbnail-slide {
- background-color: #fff;
- overflow: hidden;
- user-select: none;
- position: relative;
- }
- .elements {
- transform-origin: 0 0;
- }
- .background {
- width: 100%;
- height: 100%;
- background-position: center;
- position: absolute;
- }
- .placeholder {
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .thumbnail-mask {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: transparent;
- pointer-events: auto; /* 拦截所有点击事件 */
- z-index: 9999; /* 确保在所有元素之上,包括iframe */
- cursor: pointer;
- }
- </style>
|