状态录制
本章你可以学习到
- 通过 State 记录用户操作。
- 通过 State 还原用户操作画面。
- 在 Vue 中管理定时器与事件清理。
Vue 示例:模式切换 + 环视
- JavaScript
- TypeScript
<template>
<div style="width: 100vw; height: 100vh">
<div ref="container" style="width: 100%; height: 100%; overflow: hidden" />
<div style="position: fixed; bottom: 16px; left: 0; right: 0; display: flex; gap: 8px; justify-content: center">
<button :class="mode==='Panorama'?'btn btn-primary':'btn btn-outline-primary'" @click="switchMode('Panorama')">全景漫游</button>
<button :class="mode==='Floorplan'?'btn btn-primary':'btn btn-outline-primary'" @click="switchMode('Floorplan')">空间总览</button>
</div>
<div style="position: fixed; top: 16px; right: 16px; display: flex; gap: 8px">
<button class="btn btn-light" @click="startLookAround">开始环视</button>
<button class="btn btn-light" @click="stopLookAround">停止环视</button>
</div>
</div>
</template>
<script setup>
import { onMounted, onUnmounted, ref } from 'vue'
import { Five, parseWork } from '@realsee/five'
const container = ref(null)
const mode = ref('Panorama')
let five = null
let timer = null
const workURL = 'https://vr-public.realsee-cdn.cn/release/static/image/release/five/work-sample/07bdc58f413bc5494f05c7cbb5cbdce4/work.json'
onMounted(()=>{
five = new Five()
if (container.value) five.appendTo(container.value)
fetch(workURL).then(r=>r.json()).then(json=>five.load(parseWork(json)))
const onResize = () => five.refresh()
const onState = (s) => { mode.value = s.mode }
window.addEventListener('resize', onResize, false)
five.on('stateChange', onState)
onUnmounted(()=>{
if (timer) window.clearInterval(timer)
window.removeEventListener('resize', onResize, false)
five.off('stateChange', onState)
five.dispose()
})
})
function switchMode(m){ five?.setState({ mode: m }) }
function startLookAround(){
if (timer) window.clearInterval(timer)
timer = window.setInterval(()=>{
if (!five) return
five.setState({ longitude: five.state.longitude + Math.PI / 360 })
}, 16)
}
function stopLookAround(){ if (timer) window.clearInterval(timer) }
</script>
<template>
<div style="width: 100vw; height: 100vh">
<div ref="container" style="width: 100%; height: 100%; overflow: hidden" />
<div style="position: fixed; bottom: 16px; left: 0; right: 0; display: flex; gap: 8px; justify-content: center">
<button :class="mode==='Panorama'?'btn btn-primary':'btn btn-outline-primary'" @click="switchMode('Panorama')">全景漫游</button>
<button :class="mode==='Floorplan'?'btn btn-primary':'btn btn-outline-primary'" @click="switchMode('Floorplan')">空间总览</button>
</div>
<div style="position: fixed; top: 16px; right: 16px; display: flex; gap: 8px">
<button class="btn btn-light" @click="startLookAround">开始环视</button>
<button class="btn btn-light" @click="stopLookAround">停止环视</button>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import { Five, Mode, parseWork } from '@realsee/five'
const container = ref<HTMLDivElement | null>(null)
const mode = ref<Mode>('Panorama')
let five: Five | null = null
let timer: number | null = null
const workURL = 'https://vr-public.realsee-cdn.cn/release/static/image/release/five/work-sample/07bdc58f413bc5494f05c7cbb5cbdce4/work.json'
onMounted(()=>{
five = new Five()
if (container.value) five.appendTo(container.value)
fetch(workURL).then(r=>r.json()).then(json=>five!.load(parseWork(json)))
const onResize = () => five!.refresh()
const onState = (s: { mode: Mode }) => { mode.value = s.mode }
window.addEventListener('resize', onResize, false)
five.on('stateChange', onState)
onUnmounted(()=>{
if (timer) window.clearInterval(timer)
window.removeEventListener('resize', onResize, false)
five!.off('stateChange', onState)
five!.dispose()
})
})
function switchMode(m: Mode){ five?.setState({ mode: m }) }
function startLookAround(){
if (timer) window.clearInterval(timer)
timer = window.setInterval(()=>{
if (!five) return
five!.setState({ longitude: five!.state.longitude + Math.PI / 360 })
}, 16) as unknown as number
}
function stopLookAround(){ if (timer) window.clearInterval(timer) }
</script>