123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- <template>
- <div class="controls-left-buttons">
- <!-- <div class="buttons tour">
- <div @click="onModeChange('panorama')">
- <i class="iconfont" :class="['icon-preview']"></i>
- </div>
- <div class="show-list">
- <i class="iconfont" :class="['icon-pull-down']"></i>
- </div>
- </div> -->
- <div class="buttons mode" :class="{ disabled: isPlay || flying }">
- <div v-if="controls.showPanorama" :class="{ active: viewmode == 'panorama' }" @click="onModeChange('panorama')">
- <ui-icon tipV="top" :type="viewmode == 'panorama' ? 'show_roaming_selected' : 'show_roaming_normal'"></ui-icon>
- </div>
- <div v-if="controls.showFloorplan" :class="{ active: viewmode == 'floorplan' }" @click="onModeChange('floorplan')">
- <ui-icon tipV="top" :type="viewmode == 'floorplan' ? 'show_plane_selected' : 'show_plane_normal'"></ui-icon>
- </div>
- <div v-if="controls.showDollhouse" :class="{ active: viewmode == 'dollhouse' }" @click="onModeChange('dollhouse')">
- <ui-icon tipV="top" :type="viewmode == 'dollhouse' ? 'show_3d_selected' : 'show_3d_normal'"></ui-icon>
- </div>
- </div>
- <!-- <div class="play-control" v-if="tours.length > 0" :class="{ disabled: flying || isSelect }"> -->
- <div class="play-control" v-if="tours.length > 0">
- <div class="play-btn tour-btn" @click="playTour">
- <ui-icon tipV="top" :type="isPlay ? 'pause' : 'preview'"></ui-icon>
- </div>
- <div class="tour-btn bor" @click="openTours">
- <ui-icon type="pull-down" :class="{ active: showTours }"></ui-icon>
- </div>
- <!-- <teleport :to="editorMain"> -->
- <div class="tour-list 111" :class="{ ban: flying || isSelect }" :style="`height:${showTours ? '120px' : '0px'};`">
- <div class="part-content" ref="tourScroll">
- <!-- 多个片段 -->
- <div class="part-list" v-if="tours.length > 1">
- <div
- @click="changeFrame(1, index)"
- :class="{ disabled: isPlay && partId != index }"
- class="part-item"
- :name="index"
- v-for="(i, index) in tours"
- :style="`background-image:url(${i.frameId ? common.changeUrl(i.list[i.frameId].enter.cover) : common.changeUrl(i.list[0].enter.cover)});`"
- >
- <div class="part-title">{{ i.name }}</div>
- <div v-if="partId == index && progressNum > 0" class="precent" :style="`width:${progressNum}%;`"></div>
- </div>
- </div>
- <!-- 只有一个片段 -->
- <div class="part-list frame-list" v-else>
- <div
- @click="changeFrame(2, index)"
- :class="{ disabled: isPlay && frameId != index }"
- class="part-item"
- v-for="(i, index) in tours[0].list"
- :name="index"
- :style="`background-image:url(${common.changeUrl(i.enter.cover)});`"
- >
- <div class="part-title"></div>
- <div v-if="frameId == index && progressNum > 0" class="precent" :style="`width:${progressNum}%;`"></div>
- </div>
- </div>
- </div>
- </div>
- <!-- </teleport> -->
- </div>
- </div>
- </template>
- <script setup>
- import { computed, defineProps, onMounted, 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 props = defineProps({
- isEdit: Boolean,
- })
- let timer = null
- const isSelect = ref(false)
- const store = useStore()
- const tourScroll = ref(null)
- const viewmode = computed(() => store.getters.mode)
- 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 => {
- // console.log(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}"]`)
- // let itemLeft = (item.offsetWidth + 10) * (id + 1)
- // let Scroll = document.querySelector('.part-content .x-scrollbar__container')
- // // let contentW = slideType == 1 ? document.querySelector('.part-content').offsetWidth : document.querySelector('.iframe-content').offsetWidth
- // let ScrollW = Scroll.offsetWidth
- // Scroll.scrollTo({ left: itemLeft - ScrollW + 10, behavior: 'smooth' })
- 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)
- // if (tours.value.length > 1) {
- // let time = getPartTime(data.partId)
- // console.log(time)
- // hanlderTourPartPlay(time)
- // }
- })
- 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 {
- // let time = getPartTime(data.partId)
- // hanlderTourPartPlay(time)
- 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 })
- })
- // nextTick(() => {
- // editorMain.value = document.querySelector('.ui-editor-main')
- // })
- }
- const getPartTime = partId => {
- cancelTimer()
- let time = 0
- // for (let i = 0; i < tours.value[partId].list.length - 1; i++) {
- // time += tours.value[partId].list[i].time - 0
- // }
- // if (tours.value[partId].list[tours.value[partId].list.length - 1]._end) {
- // if (tours.value[partId].list.length > 2) {
- // time += (tours.value[partId].list.length - 1) * 1000
- // }
- // } else {
- // time += (tours.value[partId].list.length - 1) * 1000
- // }
- // for (let i = 0; i < tours.value[partId].list.length; i++) {
- // time += tours.value[partId].list[i].time - 0 + 1000
- // }
- 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 })
- let bot = '20px'
- if (showTours.value) {
- bot = '140px'
- } else {
- bot = '20px'
- }
- store.commit('setControlsBottom', bot)
- 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()
- }
- }
- onMounted(() => {
- useApp().then(async sdk => {
- hanlderTour()
- })
- nextTick(() => {
- let player = document.querySelector('.player[name="main"]')
- player.addEventListener('click', onClickHandler)
- })
- })
- </script>
- <style lang="scss" scoped>
- .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 {
- width: 100%;
- position: fixed;
- bottom: 0;
- left: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- flex: 1;
- // height: var(--editor-toolbar-height);
- height: 120px;
- background-color: var(--editor-menu-back);
- pointer-events: all;
- left: var(--editor-toolbox-left);
- z-index: 1;
- transition: all 0.3s ease;
- &.ban {
- pointer-events: none;
- }
- .part-content {
- display: flex;
- flex-direction: row;
- overflow: hidden;
- width: 100%;
- height: 100%;
- .part-list {
- width: 100%;
- height: 120px;
- display: flex;
- align-items: center;
- justify-content: flex-start;
- padding: 0 10px;
- box-sizing: border-box;
- .part-item {
- width: 120px;
- height: 80px;
- position: relative;
- cursor: pointer;
- margin-right: 10px;
- background-repeat: no-repeat;
- background-size: 100%;
- background-position: center;
- &:last-of-type {
- margin-right: 0px;
- }
- &:hover {
- opacity: 0.6;
- }
- .precent {
- width: 0%;
- height: 24px;
- position: absolute;
- bottom: 0;
- left: 0;
- background: #00c8af;
- opacity: 0.4;
- z-index: 1;
- // transition: width 0.1s;
- }
- .part-title {
- width: 100%;
- height: 24px;
- background: linear-gradient(180deg, rgba(0, 0, 0, 0.25) 0%, rgba(0, 0, 0, 0.5) 100%);
- position: absolute;
- bottom: 0;
- left: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 14px;
- z-index: 10;
- }
- }
- }
- }
- }
- .play-control {
- pointer-events: all;
- display: flex;
- align-items: center;
- justify-content: center;
- height: 34px;
- border-radius: 17px;
- background-color: rgba(0, 0, 0, 0.3);
- min-width: 34px;
- border-radius: 17px;
- margin-left: 10px;
- .tour-btn {
- width: 34px;
- height: 22px;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- > .iconfont {
- font-size: 14px;
- }
- &.play-btn {
- // border-right: 1px solid rgba(255, 255, 255, 0.2);
- > .iconfont {
- font-size: 20px;
- transition: rotate 0.3s;
- }
- }
- &.bor {
- border-left: 1px solid rgba(255, 255, 255, 0.2);
- > .iconfont {
- transform: rotate(180deg);
- &.active {
- transform: rotate(0deg);
- }
- }
- }
- }
- }
- </style>
|