123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- <template>
- <div
- class="mobile-player"
- :style="{
- width: playerSize.width + 'px',
- height: playerSize.height + 'px',
- transform: `rotate(90deg) translateY(-${playerSize.height}px)`,
- }"
- >
- <div
- class="screen-slide-list"
- @click="toolVisible = !toolVisible"
- @touchstart="($event) => touchStartListener($event)"
- @touchend="($event) => touchEndListener($event)"
- >
- <div
- :class="[
- 'slide-item',
- `turning-mode-${slide.turningMode || 'slideY'}`,
- {
- current: index === slideIndex,
- before: index < slideIndex,
- after: index > slideIndex,
- hide:
- (index === slideIndex - 1 || index === slideIndex + 1) &&
- slide.turningMode !==
- slidesWithTurningMode[slideIndex].turningMode,
- last: index === slideIndex - 1,
- next: index === slideIndex + 1,
- },
- ]"
- v-for="(slide, index) in slidesWithTurningMode"
- :key="slide.id"
- >
- <div
- class="slide-content"
- :style="{
- width: slideSize.width + 'px',
- height: slideSize.height + 'px',
- }"
- v-if="Math.abs(slideIndex - index) < 2"
- >
- <ThumbnailSlide :slide="slide" :size="slideSize.width" />
- </div>
- </div>
- </div>
- <template v-if="toolVisible">
- <div class="header">
- <div class="back" @click="changeMode('preview')">
- <IconLogout /> 退出播放
- </div>
- </div>
- <MobileThumbnails class="thumbnails" />
- </template>
- </div>
- </template>
- <script lang="ts" setup>
- import { computed, onMounted, ref } from "vue";
- import { storeToRefs } from "pinia";
- import { useSlidesStore } from "@/store";
- import type { Mode } from "@/types/mobile";
- import useSlidesWithTurningMode from "../Screen/hooks/useSlidesWithTurningMode";
- import ThumbnailSlide from "@/views/components/ThumbnailSlide/index.vue";
- import MobileThumbnails from "./MobileThumbnails.vue";
- defineProps<{
- changeMode: (mode: Mode) => void;
- }>();
- const slidesStore = useSlidesStore();
- const { slides, slideIndex, viewportRatio } = storeToRefs(slidesStore);
- const { slidesWithTurningMode } = useSlidesWithTurningMode();
- const toolVisible = ref(false);
- const playerSize = ref({ width: 0, height: 0 });
- onMounted(() => {
- if (slideIndex.value !== 0) slidesStore.updateSlideIndex(0);
- playerSize.value = {
- width: document.body.clientHeight,
- height: document.body.clientWidth,
- };
- });
- const slideSize = computed(() => {
- const playerRatio = playerSize.value.height / playerSize.value.width;
- let slideWidth = 0;
- let slideHeight = 0;
- if (playerRatio >= viewportRatio.value) {
- slideWidth = playerSize.value.width;
- slideHeight = slideWidth * viewportRatio.value;
- } else {
- slideHeight = playerSize.value.height;
- slideWidth = slideHeight / viewportRatio.value;
- }
- return {
- width: slideWidth,
- height: slideHeight,
- };
- });
- const touchInfo = ref<{ x: number; y: number } | null>(null);
- const touchStartListener = (e: TouchEvent) => {
- touchInfo.value = {
- x: e.changedTouches[0].pageX,
- y: e.changedTouches[0].pageY,
- };
- };
- const touchEndListener = (e: TouchEvent) => {
- if (!touchInfo.value) return;
- const offsetX = e.changedTouches[0].pageX - touchInfo.value.x;
- const offsetY = e.changedTouches[0].pageY - touchInfo.value.y;
- const offsetAbsX = Math.abs(offsetX);
- const offsetAbsY = Math.abs(offsetY);
- if (offsetAbsX > offsetAbsY && offsetAbsX > 50) {
- if (offsetX < 0 && slideIndex.value > 0)
- slidesStore.updateSlideIndex(slideIndex.value - 1);
- if (offsetX > 0 && slideIndex.value < slides.value.length - 1)
- slidesStore.updateSlideIndex(slideIndex.value + 1);
- }
- if (offsetAbsY > offsetAbsX && offsetAbsY > 50) {
- if (offsetY > 0 && slideIndex.value > 0)
- slidesStore.updateSlideIndex(slideIndex.value - 1);
- if (offsetY < 0 && slideIndex.value < slides.value.length - 1)
- slidesStore.updateSlideIndex(slideIndex.value + 1);
- }
- };
- </script>
- <style lang="scss" scoped>
- .mobile-player {
- transform-origin: 0 0;
- background-color: #1d1d1d;
- position: relative;
- }
- .screen-slide-list {
- position: relative;
- width: 100%;
- height: 100%;
- }
- .slide-item {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- &:not(.last, .next) {
- z-index: -1;
- }
- &.current {
- z-index: 2;
- }
- &.hide {
- opacity: 0;
- }
- &.turning-mode-no {
- &.before {
- transform: translateY(-100%);
- }
- &.after {
- //transform: translateY(100%);
- }
- }
- &.turning-mode-fade {
- transition: opacity 0.75s;
- &.before {
- pointer-events: none;
- opacity: 0;
- }
- &.after {
- pointer-events: none;
- opacity: 0;
- }
- }
- &.turning-mode-slideX {
- transition: transform 0.35s;
- &.before {
- transform: translateX(-100%);
- }
- &.after {
- transform: translateX(100%);
- }
- }
- &.turning-mode-slideY {
- transition: transform 0.35s;
- &.before {
- transform: translateY(-100%);
- }
- &.after {
- //transform: translateY(100%);
- }
- }
- }
- .slide-content {
- background-color: #fff;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .header {
- width: 100%;
- height: 40px;
- line-height: 40px;
- padding: 0 15px;
- position: absolute;
- top: 0;
- left: 0;
- z-index: 99;
- background-color: rgba($color: #1d1d1d, $alpha: 0.7);
- text-align: right;
- font-size: 13px;
- color: #fff;
- animation: slideInDown 0.15s;
- .back {
- height: 100%;
- }
- }
- .thumbnails {
- width: 100%;
- position: absolute;
- bottom: 0;
- left: 0;
- z-index: 99;
- background-color: rgba($color: #1d1d1d, $alpha: 0.7);
- overflow: auto !important;
- animation: slideInUp 0.15s;
- }
- @keyframes slideInUp {
- from {
- //transform: translateY(100%);
- }
- to {
- transform: translateY(0);
- }
- }
- @keyframes slideInDown {
- from {
- transform: translateY(-100%);
- }
- to {
- transform: translateY(0);
- }
- }
- </style>
|