123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- <script setup lang="ts">
- import { onMounted, inject, ref } from 'vue'
- const __sdk: any = inject('__sdk')
- const tours = ref<Array<TourPart>>([])
- const playing = ref(false)
- const p_id = ref(-1)
- const f_id = ref(-1)
- // 片段进度
- const p_progress = ref(0)
- // 画面进度
- const f_progress = ref(0)
- // 获取用户资源地址
- const getURL = (file: string) => {
- if (file.indexOf('data:') === 0) {
- return file
- }
- return __sdk.resource.getUserResourceURL(file)
- }
- const onPlay = () => {
- if (playing.value) {
- __sdk.Plugins.TourPlayer.pause()
- } else {
- __sdk.Plugins.TourPlayer.play()
- }
- }
- const onSelect = (partId: number, frameId: number) => {
- if (playing.value) {
- __sdk.Plugins.TourPlayer.play(partId, frameId)
- } else {
- f_id.value = frameId
- f_progress.value = 0
- __sdk.Plugins.TourPlayer.selectFrame(frameId)
- document.querySelector(`[index="${frameId}"]`)?.scrollIntoView()
- }
- }
- const onAddPart = () => {}
- const onAddFrame = () => {
- __sdk.Plugins.TourRecorder.addFrame()
- }
- const onClear = () => {
- __sdk.Plugins.TourRecorder.clear()
- }
- onMounted(() => {
- __sdk.use('TourRecorder').then((recorder: any) => {
- recorder.on('change', (e: any) => {
- if (e.action == 'add') {
- if (e.type == 'frame') {
- e.data.time = 3000
- }
- }
- })
- })
- __sdk.use('TourPlayer').then((player: any) => {
- player.on('play', () => (playing.value = true))
- player.on('pause', () => (playing.value = false))
- player.on('end', () => {
- playing.value = false
- // 兼容最后一个画面没有进度的问题
- p_progress.value = 100
- f_progress.value = 100
- setTimeout(() => {
- p_progress.value = 0
- f_progress.value = 0
- }, 1000)
- })
- let currPartId = 0
- let currFrames = 0
- player.on('progress', ({ partId, frameId, progress }: any) => {
- if (frameId != f_id.value) {
- document.querySelector(`[index="${frameId}"]`)?.scrollIntoView()
- }
- // 画面进度
- p_id.value = partId
- f_id.value = frameId
- f_progress.value = Number(Number(progress * 100).toFixed(5))
- // 片段进度
- if (tours.value.length == 1) {
- p_progress.value = f_progress.value
- } else {
- if (currPartId != partId) {
- currPartId = partId
- currFrames = tours.value[partId].list.length
- p_progress.value = 0
- }
- p_progress.value += progress / currFrames
- }
- })
- })
- // 需要双向绑定时,重新设置数据
- __sdk.TourManager.on('loaded', (data: any) => {
- tours.value = data
- __sdk.TourManager.load(tours.value)
- })
- __sdk.Scene.on('loaded', () => {
- __sdk.core.get('Player').on('click', () => {
- if (playing.value) {
- __sdk.Plugins.TourPlayer.pause()
- }
- })
- })
- __sdk.mount('#scene').render()
- })
- </script>
- <template>
- <div id="tools">
- <button :disabled="playing" @click="onAddPart">添加片段</button>
- <button :disabled="playing" @click="onAddFrame">添加画面</button>
- <button :disabled="playing" @click="onClear">清空</button>
- <button @click="onPlay">{{ playing ? '暂停' : '播放' }}</button>
- </div>
- <div id="tours">
- <div class="list">
- <div v-for="(part, partId) in tours">
- <ul>
- <li
- v-for="(frame, frameId) in part.list"
- :index="frameId"
- :class="{ active: frameId == f_id }"
- :style="{ backgroundImage: `url(${getURL(frame.enter.cover)})` }"
- @click="onSelect(partId, frameId)"
- >
- <div class="progress" v-if="frameId == f_id">
- <div :style="{ width: f_progress + '%' }"></div>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div id="scene"></div>
- </template>
- <style scoped lang="scss">
- #tools {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- z-index: 1000;
- }
- #tours {
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- width: 100%;
- z-index: 1000;
- background-color: rgba(27, 27, 28, 0.6);
- .list {
- scroll-behavior: smooth;
- width: 100%;
- overflow: hidden;
- overflow-x: auto;
- transition: all ease-in 0.3s;
- > div {
- height: 120px;
- display: flex;
- align-items: center;
- }
- }
- ul {
- margin: 0;
- padding: 0;
- width: 100%;
- display: flex;
- align-items: center;
- list-style: none;
- }
- li {
- cursor: pointer;
- position: relative;
- display: flex;
- flex-shrink: 0;
- margin: 0;
- padding: 0;
- width: 120px;
- height: 80px;
- margin-right: 10px;
- background-color: rgba(27, 27, 28, 0.6);
- background-repeat: no-repeat;
- background-size: 100%;
- background-position: 50%;
- border: solid 1px transparent;
- .progress {
- position: absolute;
- left: 0;
- bottom: 0;
- width: 100%;
- height: 4px;
- div {
- height: 100%;
- background-color: aqua;
- transition: width ease-in 0.1s;
- }
- }
- &.active {
- border-color: aqua;
- }
- }
- }
- #scene {
- width: 100vw;
- height: 100vh;
- }
- #scene-front {
- position: absolute;
- left: 0;
- top: 0;
- z-index: 2;
- }
- </style>
|