fix. any로 지정되어 있던 부분 명시적으로 수정
This commit is contained in:
@@ -1,15 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { Splide, SplideSlide } from '@splidejs/vue-splide'
|
||||
import { getFirstGroup, isTypeVideo } from '#layers/utils/dataUtil'
|
||||
import { getMediaSrc, getYouTubeEmbedUrl } from '#layers/utils/youtube'
|
||||
import { getComponentGroup, isTypeVideo } from '#layers/utils/dataUtil'
|
||||
import {
|
||||
getMediaSrc,
|
||||
getYouTubeEmbedUrl,
|
||||
getMediaImgSrc,
|
||||
} from '#layers/utils/youtube'
|
||||
import type { Splide as SplideType, Options } from '@splidejs/splide'
|
||||
import type {
|
||||
PageDataResourceGroups,
|
||||
PageDataTemplateComponentSet,
|
||||
PageDataResourceGroup,
|
||||
} from '#layers/types/api/pageData'
|
||||
|
||||
interface Props {
|
||||
slideData: { media: PageDataResourceGroups; set_order: number }[]
|
||||
slideData: PageDataTemplateComponentSet[]
|
||||
videoPlay?: PageDataResourceGroup
|
||||
arrows?: boolean
|
||||
pagination?: boolean
|
||||
@@ -19,6 +23,9 @@ interface Props {
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
let mainInst: SplideType | null = null
|
||||
let thumbsInst: SplideType | null = null
|
||||
|
||||
const mainRef = ref<InstanceType<typeof Splide> | null>(null)
|
||||
const thumbsRef = ref<InstanceType<typeof Splide> | null>(null)
|
||||
const playingSlideIndex = ref<number | null>(null)
|
||||
@@ -33,6 +40,7 @@ const mainOptions = computed<Options>(() => ({
|
||||
pagination: false,
|
||||
drag: false,
|
||||
}))
|
||||
|
||||
const thumbOptions = computed<Options>(() => ({
|
||||
type: 'slide',
|
||||
rewind: true,
|
||||
@@ -51,39 +59,46 @@ const thumbOptions = computed<Options>(() => ({
|
||||
},
|
||||
}))
|
||||
|
||||
const isPassVideo = (groups: PageDataResourceGroups, index: number) => {
|
||||
const firstGroup = getFirstGroup(groups)
|
||||
return (
|
||||
firstGroup &&
|
||||
isTypeVideo(firstGroup?.resource_type) &&
|
||||
index !== playingSlideIndex.value
|
||||
)
|
||||
const getMediaComponent = (item: PageDataTemplateComponentSet) => {
|
||||
return getComponentGroup(item, 'media')
|
||||
}
|
||||
|
||||
const getMediaImgSrcFromItem = (item: PageDataTemplateComponentSet) => {
|
||||
const mediaComponent = getMediaComponent(item)
|
||||
return mediaComponent ? getMediaImgSrc(mediaComponent) : ''
|
||||
}
|
||||
|
||||
const getYouTubeEmbedUrlFromMedia = (item: PageDataTemplateComponentSet) => {
|
||||
const mediaComponent = getMediaComponent(item)
|
||||
if (!mediaComponent) return ''
|
||||
const mediaSrc = getMediaSrc(mediaComponent)
|
||||
return mediaSrc ? getYouTubeEmbedUrl(mediaSrc, true) : ''
|
||||
}
|
||||
|
||||
const isPassVideo = (item: PageDataTemplateComponentSet, index: number) => {
|
||||
const mediaComponent = getMediaComponent(item)
|
||||
const isNotPlaying = index !== playingSlideIndex.value
|
||||
const isVideoType =
|
||||
mediaComponent && isTypeVideo(mediaComponent?.resource_type)
|
||||
|
||||
return isVideoType && isNotPlaying
|
||||
}
|
||||
|
||||
const handleVideoClick = (index: number) => {
|
||||
playingSlideIndex.value = index
|
||||
}
|
||||
|
||||
const getYouTubeEmbedUrlFromMedia = (
|
||||
resourceGroups: PageDataResourceGroup[]
|
||||
) => {
|
||||
const resourceGroup = getFirstGroup(resourceGroups)
|
||||
const mediaSrc = getMediaSrc(resourceGroup)
|
||||
return mediaSrc ? getYouTubeEmbedUrl(mediaSrc, true) : ''
|
||||
const stopVideo = () => {
|
||||
playingSlideIndex.value = null
|
||||
}
|
||||
|
||||
let mainInst: SplideType | null = null
|
||||
let thumbsInst: SplideType | null = null
|
||||
|
||||
onMounted(() => {
|
||||
mainInst = mainRef.value?.splide ?? null
|
||||
thumbsInst = thumbsRef.value?.splide ?? null
|
||||
|
||||
if (mainInst && thumbsInst) {
|
||||
mainInst.sync(thumbsInst)
|
||||
|
||||
mainInst.on('moved', () => {
|
||||
playingSlideIndex.value = null
|
||||
})
|
||||
mainInst.on('moved', stopVideo)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -103,21 +118,21 @@ onBeforeUnmount(() => {
|
||||
class="main-slide"
|
||||
>
|
||||
<img
|
||||
:src="getMediaImgSrc(item.media)"
|
||||
:src="getMediaImgSrcFromItem(item)"
|
||||
alt="main image"
|
||||
class="slide-image"
|
||||
:class="{ 'opacity-0': playingSlideIndex === index }"
|
||||
/>
|
||||
<AtomsButtonPlay
|
||||
v-if="isPassVideo(item.media, index)"
|
||||
v-if="isPassVideo(item, index)"
|
||||
:resources-data="videoPlay"
|
||||
class="btn-play"
|
||||
@click="handleVideoClick(index)"
|
||||
/>
|
||||
<iframe
|
||||
v-if="playingSlideIndex === index"
|
||||
:src="getYouTubeEmbedUrlFromMedia(item.media)"
|
||||
class="absolute top-0 left-0 w-full h-full"
|
||||
:src="getYouTubeEmbedUrlFromMedia(item)"
|
||||
class="video-iframe"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
@@ -133,7 +148,7 @@ onBeforeUnmount(() => {
|
||||
class="thumbnail-slide"
|
||||
>
|
||||
<img
|
||||
:src="getMediaImgSrc(item.media)"
|
||||
:src="getMediaImgSrcFromItem(item)"
|
||||
alt="thumbnail image"
|
||||
class="slide-image"
|
||||
/>
|
||||
@@ -143,8 +158,6 @@ onBeforeUnmount(() => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 비디오 iframe 전환 애니메이션 */
|
||||
|
||||
.thumbnail-carousel {
|
||||
@apply w-full md:max-w-[944px];
|
||||
}
|
||||
@@ -161,6 +174,9 @@ onBeforeUnmount(() => {
|
||||
.btn-play {
|
||||
@apply absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2;
|
||||
}
|
||||
.video-iframe {
|
||||
@apply absolute top-0 left-0 w-full h-full;
|
||||
}
|
||||
|
||||
.thumbnail-splide {
|
||||
@apply overflow-hidden flex justify-center w-screen mt-[20px] mx-[-20px] sm:mx-[-40px] md:w-auto md:mx-0 md:px-[120px] md:mt-[28px];
|
||||
|
||||
Reference in New Issue
Block a user