三维空间中的点
上一章回顾: 状态录制
- 你了解了如何通过 State 完成操作的录制和还原。
- 熟悉地使用 State 相关的方法和事件。
本章你可以学习到
- 了解 Five SDK 的事件系统。
- 获取到点的三维位置。
准备工作
我们新建一个目录(src/4.points-in-3d
)以及对应的 html 文件 以及 jsx 或 tsx 文件。
携带着上一章的 State 代码,太过于繁琐,那我们从 展示三维空间 章的内容的基础开发。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="data:;base64,iVBORw0KGgo=" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>三维中的点 | Points in 3d</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css"
rel="stylesheet"
crossorigin="anonymous"
/>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"
rel="stylesheet"
/>
<style>
* {
margin: 0;
padding: 0;
}
html,
body,
#app {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index"></script>
</body>
</html>
- JavaScript
- TypeScript
import { ref, onBeforeUnmount } from "vue";
function useWindowDimensions() {
const width = ref(window.innerWidth);
const height = ref(window.innerHeight);
const listener = () => {
width.value = window.innerWidth;
height.value = window.innerHeight;
};
window.addEventListener("resize", listener, false);
onBeforeUnmount(() => {
window.removeEventListener("resize", listener, false);
});
return { width, height };
}
export { useWindowDimensions };
src/4.points-in-3d/ModeController.vue
<template>
<nav class="navbar fixed-bottom navbar-light bg-light">
<div class="container-fluid justify-content-center">
<div class="btn-group">
<button
:class="
state.mode == 'Panorama'
? 'btn btn-primary active'
: 'btn btn-primary'
"
@click="() => setState({ mode: Five.Mode.Panorama })"
>
全景漫游
</button>
<button
:class="
state.mode == 'Panorama'
? 'btn btn-primary'
: 'btn btn-primary active'
"
@click="() => setState({ mode: Five.Mode.Floorplan })"
>
空间总览
</button>
</div>
</div>
</nav>
</template>
<script setup>
import { useFiveCurrentState } from "@realsee/five/vue";
import { Five } from "@realsee/five";
const [state, setState] = useFiveCurrentState();
</script>
src/4.points-in-3d/App.vue
<template>
<FiveProvider :work="work">
<FiveCanvas :width="width" :height="height" />
<ModeController />
</FiveProvider>
</template>
<script setup>
import { FiveProvider, FiveCanvas } from "@realsee/five/vue";
import { parseWork } from "@realsee/five";
import { ref } from "vue";
import { useWindowDimensions } from "./useWindowDimensions";
import ModeController from "./ModeController.vue";
const work = ref();
const workURL =
"https://vr-public.realsee-cdn.cn/release/static/image/release/five/work-sample/07bdc58f413bc5494f05c7cbb5cbdce4/work.json";
fetch(workURL)
.then((response) => response.text())
.then((text) => (work.value = parseWork(text)));
const { width, height } = useWindowDimensions();
</script>
src/4.points-in-3d/index.js
import { createApp, h } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
import { ref, onBeforeUnmount } from "vue";
function useWindowDimensions() {
const width = ref<number>(window.innerWidth);
const height = ref<number>(window.innerHeight);
const listener = () => {
width.value = window.innerWidth;
height.value = window.innerHeight;
};
window.addEventListener("resize", listener, false);
onBeforeUnmount(() => {
window.removeEventListener("resize", listener, false);
});
return { width, height };
}
export { useWindowDimensions };
src/4.points-in-3d/ModeController.vue
<template>
<nav class="navbar fixed-bottom navbar-light bg-light">
<div class="container-fluid justify-content-center">
<div class="btn-group">
<button
:class="
state.mode == 'Panorama'
? 'btn btn-primary active'
: 'btn btn-primary'
"
@click="() => setState({ mode: Five.Mode.Panorama })"
>
全景漫游
</button>
<button
:class="
state.mode == 'Panorama'
? 'btn btn-primary'
: 'btn btn-primary active'
"
@click="() => setState({ mode: Five.Mode.Floorplan })"
>
空间总览
</button>
</div>
</div>
</nav>
</template>
<script setup lang="ts">
import { useFiveCurrentState } from "@realsee/five/vue";
import { Five } from "@realsee/five";
const [state, setState] = useFiveCurrentState();
</script>
src/4.points-in-3d/App.vue
<template>
<FiveProvider :work="work">
<FiveCanvas :width="width" :height="height" />
<ModeController />
</FiveProvider>
</template>
<script setup lang="ts">
import { FiveProvider, FiveCanvas } from "@realsee/five/vue";
import { parseWork } from "@realsee/five";
import { ref } from "vue";
import { useWindowDimensions } from "./useWindowDimensions";
import ModeController from "./ModeController.vue";
const work = ref();
const workURL =
"https://vr-public.realsee-cdn.cn/release/static/image/release/five/work-sample/07bdc58f413bc5494f05c7cbb5cbdce4/work.json";
fetch(workURL)
.then((response) => response.text())
.then((text) => (work.value = parseWork(text)));
const { width, height } = useWindowDimensions();
</script>
src/4.points-in-3d/index.ts
import { createApp, h } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
启动服务 npm run dev
。 并跳转到当前页面 "http://localhost:3000/src/4.points-in-3d/index.html"。
信息
请查看你的控制台,端口号会因为你的配置以及当前端口占用情况变更,请已控制台输出的为准。 如果你使用其他开发构建工具,请按照自己的开发构建工具的要求启动服务。
事件系统
在屏幕上点击时,five SDK 的默认行为是选择点击位置附近最合适的 观察点(observer) 移动过去。大部分用户的动作都是如此,就好比浏览器对于 A 标签 的处理逻辑大多都是链接跳转。上述就是 five SDK 的内建 tapGesture事件。