64 lines
2.1 KiB
Vue
64 lines
2.1 KiB
Vue
<template>
|
||
<div class="min-h-screen bg-gray-900 text-white p-4">
|
||
<div class="flex items-center justify-between mb-4">
|
||
<h2 class="text-xl font-bold text-blue-400">V5: 3D Space-Time Cube</h2>
|
||
<button @click="goBack" class="text-sm bg-gray-700 hover:bg-gray-600 px-3 py-1 rounded">← 返回</button>
|
||
</div>
|
||
<div class="text-xs text-gray-500 mb-3 flex gap-4">
|
||
<span>X = 畫面水平位置(紅軸)</span>
|
||
<span>Y = 畫面垂直位置(綠軸)</span>
|
||
<span>Z = 深度 - bbox 面積(藍軸)</span>
|
||
<span>T = 時間 - 顏色漸層藍→紅</span>
|
||
</div>
|
||
<div class="h-[calc(100vh-140px)]">
|
||
<SpaceTimeCube
|
||
:file-uuid="fileUuid"
|
||
:traces="allTraces"
|
||
:frame-width="1920"
|
||
:frame-height="1080"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue'
|
||
import { useRoute, useRouter } from 'vue-router'
|
||
import { getCurrentConfig } from '@/api/client'
|
||
import SpaceTimeCube from '@/components/SpaceTimeCube.vue'
|
||
|
||
const route = useRoute()
|
||
const router = useRouter()
|
||
const fileUuid = route.params.file_uuid as string
|
||
const allTraces = ref<any[]>([])
|
||
|
||
// Auto-configure from query params (for demo)
|
||
const keyParam = route.query.key as string
|
||
const baseParam = route.query.base as string
|
||
if (keyParam && baseParam) {
|
||
const existing = JSON.parse(localStorage.getItem('portal_config') || '{}')
|
||
existing.api_key = keyParam
|
||
existing.api_base_url = baseParam
|
||
localStorage.setItem('portal_config', JSON.stringify(existing))
|
||
}
|
||
|
||
const goBack = () => router.back()
|
||
|
||
onMounted(async () => {
|
||
const config = getCurrentConfig()
|
||
try {
|
||
const resp = await fetch(`${config.api_base_url}/api/v1/file/${fileUuid}/face_trace/sortby`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
...(config.api_key ? { 'X-API-Key': config.api_key } : {})
|
||
},
|
||
body: JSON.stringify({ sort_by: 'face_count', limit: 200, min_faces: 1 })
|
||
})
|
||
const data = await resp.json()
|
||
allTraces.value = data.traces || []
|
||
} catch (e) {
|
||
console.error('Failed to load traces:', e)
|
||
}
|
||
})
|
||
</script> |