123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- <template>
- <div class="tour-list" v-if="tours.length > 0" :class="{ ban: flying || isSelect,barshow: showTours }">
- <div class="part-content" ref="tourScroll">
- <!-- 多个片段 -->
- <ul class="part-list" v-if="tours.length>1">
- <li class="part-item" v-for="(item, index) in tours" :key="index"
- @click="changeFrame(1, index)"
- :class="{
- active: partId == index && progressNum > 0,
- loopspan: item.name.length > spanlength && partId == index,
- disabled: isPlay && partId != index }"
- :name="index">
- <span v-if="partId == index">{{item.name}}</span>
- <span v-else>{{ item.name.length > spanlength ? item.name.slice(0, spanlength) : item.name }}</span>
- <div v-if="partId == index && progressNum > 0" class="tourbar">
- <div :style="`width:${progressNum}%;`" class="tourline"></div>
- </div>
- </li>
- </ul>
- <!-- 只有一个片段 -->
- <ul class="part-list" v-else>
- <li class="part-item" v-for="(item, index) in tours[0].list" :key="index"
- @click="changeFrame(2, index)"
- :class="{
- active: frameId == index && progressNum > 0,
- disabled: isPlay && frameId != index }"
- :name="index">
- <span>片段</span>
- <div v-if="frameId == index && progressNum > 0" class="tourbar">
- <div :style="`width:${progressNum}%;`" class="tourline"></div>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </template>
- <script setup>
- import { computed, inject, onMounted,watch, ref, nextTick } from 'vue'
- import { Scrollbar, Dialog } from '@/global_components'
- import { useApp, getApp } from '@/app'
- import { useStore } from 'vuex'
- import common from '@/utils/common'
- import { useMusicPlayer } from '@/utils/sound'
- const musicPlayer = useMusicPlayer()
- const spanlength = ref(5)
- const triggerTour = inject("triggerTour");
- const isOpenTours = inject("isOpenTours");
- let timer = null
- const isSelect = ref(false)
- const store = useStore()
- const tourScroll = ref(null)
- const flying = computed(() => store.getters['flying'])
- const controls = computed(() => store.getters['scene/metadata'].controls || {})
- const showTours = computed(() => store.getters['tour/showTours'])
- const partId = computed(() => {
- let id = store.getters['tour/partId']
- if (isPlay.value) {
- slideScroll()
- }
- return id
- })
- const frameId = computed(() => {
- let id = store.getters['tour/frameId']
- if (isPlay.value) {
- slideScroll()
- }
- return id
- })
- const progressNum = ref(0)
- const isPlay = computed(() => {
- let status = store.getters['tour/isPlay']
- let map = document.querySelector('.kankan-app div[xui_min_map]')
- if (map) {
- if (status) {
- map.classList.add('disabled')
- } else {
- map.classList.remove('disabled')
- }
- }
- return status
- })
- const isInit = ref(false)
- const tours = computed(() => {
- let tours = store.getters['tour/tours']
- if (tours.length > 0) {
- if (tourScroll.value && !isInit.value) {
- isInit.value = true
- new Scrollbar(tourScroll.value, { onlyHorizontal: true })
- }
- }
- return tours
- })
- const onModeChange = name => {
- store.commit('setMode', name)
- }
- const playTour = async () => {
- let player = await getApp().TourManager.player
- if (isPlay.value) {
- store.commit('tour/setData', { isPlay: true })
- player.pause()
- } else {
- store.commit('tour/setData', { isPlay: true })
- player.play(partId.value)
- }
- }
- const hanlderTourPartPlay = time => {
- if (!timer) {
- timer = KanKan.Animate.transitions.start(progress => {
- progressNum.value = progress * 100
- }, time)
- }
- }
- const cancelTimer = () => {
- if (timer) {
- KanKan.Animate.transitions.cancel(timer)
- timer = null
- }
- }
- const slideScroll = () => {
- nextTick(() => {
- let t = setTimeout(() => {
- clearTimeout(t)
- let id = tours.value.length > 1 ? partId.value : frameId.value
- let item = document.querySelector(`.part-item[name="${id}"]`)
- item.scrollIntoView({ block: 'center', behavior: 'smooth', inline: 'center' })
- }, 100)
- })
- }
- const hanlderTour = async () => {
- let player = await getApp().TourManager.player
- player.on('play', data => {
- musicPlayer.pause(true)
- })
- player.on('pause', tours => {
- console.log('pause', player)
- musicPlayer.resume()
- progressNum.value = 0
- cancelTimer()
- store.commit('tour/setData', { isPlay: false })
- })
- player.on('end', tours => {
- musicPlayer.resume()
- progressNum.value = 100
- slideScroll()
- store.commit('tour/setData', { isPlay: false })
- cancelTimer()
- })
- let currPartId = null
- let currProgress = 0
- let currFrames = 0
- player.on('progress', data => {
- if (tours.value.length == 1) {
- progressNum.value = data.progress * 100
- } else {
- if (currPartId != data.partId) {
- currPartId = data.partId
- currFrames = tours.value[data.partId].list.length
- currProgress = 0
- } else {
- currProgress += data.progress / currFrames
- if (currProgress >= 100) {
- currProgress = 100
- }
- progressNum.value = currProgress
- }
- }
- store.commit('tour/setData', { partId: data.partId, frameId: data.frameId, isPlay: true })
- })
- }
- const getPartTime = partId => {
- cancelTimer()
- let time = 0
- for (let i = 0; i < tours.value[partId].list.length; i++) {
- if (!tours.value[partId].list[i]._end) {
- time += tours.value[partId].list[i].time - 0
- if (!tours.value[partId].list[i]._notrans) {
- time += 1000
- }
- }
- }
- return time
- }
- const openTours = () => {
- // showTours.value = !showTours.value
- store.commit('tour/setData', { showTours: !showTours.value })
-
- nextTick(() => {
- if (isPlay.value) {
- slideScroll()
- }
- })
- }
- const changeFrame = async (type, id) => {
- progressNum.value = 0
- // recorder.selectFrame(id)
- let player = await getApp().TourManager.player
- // player.selectFrame(id)
- isSelect.value = true
- if (type == 1) {
- player.selectPart(id)
- console.log(tours.value[id].frameId)
- let f_id = 0
- if (tours.value[id].frameId) {
- f_id = tours.value[id].frameId
- }
- player.selectFrame(f_id).then(() => {
- isSelect.value = false
- })
- store.commit('tour/setData', {
- frameId: f_id,
- partId: id,
- })
- } else {
- player.selectFrame(id).then(() => {
- isSelect.value = false
- })
- store.commit('tour/setData', {
- frameId: id,
- })
- }
- slideScroll()
- }
- const onClickHandler = async () => {
- if (isPlay.value) {
- let player = await getApp().TourManager.player
- player.pause()
- musicPlayer.resume()
- }
- }
- watch(triggerTour,()=>{
- playTour()
- })
- watch(isOpenTours,()=>{
- openTours()
- })
- watch(isPlay,()=>{
- window.parent.postMessage(
- {
- source: "qjkankan",
- event: "isPlayTours",
- params: {
- isPlay:isPlay.value,
- },
- },
- "*"
- );
- })
- onMounted(() => {
- useApp().then(async sdk => {
- hanlderTour()
- })
- nextTick(() => {
- let player = document.querySelector('.player[name="main"]')
- player.addEventListener('click', onClickHandler)
- })
- })
- </script>
- <style lang="scss" scoped>
- $width: 1150px;
- .controls-left-buttons {
- margin-left: 20px;
- margin-bottom: 20px;
- display: flex;
- }
- .buttons.tour {
- margin-right: 10px;
- >div {
- margin-left: 0px;
- margin-right: 0px;
- padding: 0 10px;
- &.show-list {
- border-left: solid 1px var(--editor-font-color);
- }
- .icon-pull-down {
- font-size: 12px;
- }
- span {
- right: -10px;
- }
- }
- }
- .tour-list {
- position: fixed;
- bottom: 68px;
- left: 50%;
- transform: translateX(-50%);
- text-align: center;
- max-width: $width;
- overflow: hidden;
- max-height: 0;
- transition: .3s all ease;
- z-index: 9;
- &.ban {
- pointer-events: none;
- }
- .part-content {
- display: flex;
- flex-direction: row;
- overflow: hidden;
- padding: 10px 30px;
- min-width: 400px;
- background: linear-gradient(268deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.5) 8%, rgba(0, 0, 0, 0.5) 92%, rgba(0, 0, 0, 0) 100%);
- .part-list {
- display: flex;
- >li {
- width: 90px;
- height: 40px;
- background: rgba(24, 24, 24, .5);
- line-height: 40px;
- margin: 0 6px;
- cursor: pointer;
- >span,
- >div>span {
- cursor: pointer;
- display: inline-block;
- color: rgba(255, 255, 255, 0.8);
- }
- &.loopspan {
- >span,
- >div>span {
- animation: 5s wordsLoop linear infinite normal;
- }
- }
- &.active {
- position: relative;
- .tourbar {
- position: absolute;
- width: 78px;
- left: 6px;
- right: 6px;
- bottom: 4px;
- height: 2px;
- border-radius: 2px;
- background: #000;
- overflow: hidden;
- .tourline {
- width: 50%;
- height: 100%;
- background: var(--colors-primary-base);
- }
- }
- }
- &:hover {
- opacity: 0.7;
- }
- }
- }
- }
- }
- .barshow {
- max-height: 62px;
- }
- @keyframes wordsLoop {
- 0% {
- transform: translateX(100%);
- -webkit-transform: translateX(100%);
- }
- 100% {
- transform: translateX(-100%);
- -webkit-transform: translateX(-100%);
- }
- }
- </style>
|