如何在 react-VR 中将某些元素固定在屏幕上
How do I keep some element fixed on the screen in react-VR
我想在 react-vr 应用程序中始终显示分数或健康栏。
我可以使用 VrHeadModel - 旋转、yawPitchRoll 和位置,但必须计算它才能保持固定...好像我遗漏了什么。
我该怎么做?
已更新要点,订阅 HM 后延迟更少:
https://gist.github.com/cidicles/b4e978d3f3e2de8b359bdc51b5fb3261
这就是我目前的做法。它有视觉滞后并在循环中设置状态但实现了目标。
为 VrheadModel.rotation() 数组创建一个状态
constructor(props) {
super(props);
this.state = {
hmRot: VrHeadModel.rotation()
}
}
启动计时器
componentDidMount(){
this.timer = setInterval(()=>{this.tick()}, 50);
}
componentWillUnmount(){
clearInterval(this.timer);
}
tick(){
this.setState({
hmRot: VrHeadModel.rotation()
});
}
在 0/0/0 处创建一个视图,并像往常一样在场景中定位固定对象。在主视图上设置旋转以匹配相机的旋转。
render(){
let {hmRot} = this.state;
return (
<View
style={{
position: 'absolute',
layoutOrigin: [0.5, 0.5],
transform: [
{translate: [0, 0, 0]},
{rotateX: hmRot[0]},
{rotateY: hmRot[1]},
{rotateZ: hmRot[2]}
]
}}>
<Text
style={{
position: 'absolute',
layoutOrigin: [0.5, 0.5],
backgroundColor: '#f00',
transform: [
{translate: [0, 0, -2]},
]
}}>
Fixed
</Text>
</View>
);
}
这里有来自 React VR 团队的关于此问题的相关 post:
https://github.com/facebook/react-vr/issues/261
答案是使用多个表面:一个不锁头,另一个锁头。
请参阅此处 "Using Multiple Surfaces":Surfaces - React 360
要让您的工作正常,请将示例中缺少的代码分别粘贴到您的 client.js 和 index.js 文件中:
这是一个 link 的工作示例(部分粘贴在下方):Headlocked Surfaces
import { Math as VRMath, ReactInstance, Surface } from "react-360-web";
function init(bundle, parent, options = {}) {
const horizontalPanel = new Surface(300, 300, Surface.SurfaceShape.Flat);
const hvPanel = new Surface(300, 300, Surface.SurfaceShape.Flat);
horizontalPanel.setAngle(0, -0.5);
const cameraDirection = [0, 0, -1];
const r360 = new ReactInstance(bundle, parent, {
fullScreen: true,
frame: () => {
const cameraQuat = r360.getCameraQuaternion();
cameraDirection[0] = 0;
cameraDirection[1] = 0;
cameraDirection[2] = -1;
// cameraDirection will point out from the view of the camera,
// we can use it to compute surface angles
VRMath.rotateByQuaternion(cameraDirection, cameraQuat);
const cx = cameraDirection[0];
const cy = cameraDirection[1];
const cz = cameraDirection[2];
const horizAngle = Math.atan2(cx, -cz);
const vertAngle = Math.asin(cy / Math.sqrt(cx * cx + cy * cy + cz * cz));
horizontalPanel.setAngle(horizAngle, -0.5);
hvPanel.setAngle(horizAngle, vertAngle);
},
...options
});
r360.renderToSurface(r360.createRoot("HorizontalPanel"), horizontalPanel);
r360.renderToSurface(r360.createRoot("HVPanel"), hvPanel);
}
window.React360 = { init };
在你的client.js中:
在 ReactInstance
构造函数的 frame
属性 中,设置表面角度以匹配相机:水平,或水平和垂直。
在你的index.js中:
记得将 React 组件注册到新的 headlocked surface。
我想在 react-vr 应用程序中始终显示分数或健康栏。
我可以使用 VrHeadModel - 旋转、yawPitchRoll 和位置,但必须计算它才能保持固定...好像我遗漏了什么。
我该怎么做?
已更新要点,订阅 HM 后延迟更少:
https://gist.github.com/cidicles/b4e978d3f3e2de8b359bdc51b5fb3261
这就是我目前的做法。它有视觉滞后并在循环中设置状态但实现了目标。
为 VrheadModel.rotation() 数组创建一个状态
constructor(props) {
super(props);
this.state = {
hmRot: VrHeadModel.rotation()
}
}
启动计时器
componentDidMount(){
this.timer = setInterval(()=>{this.tick()}, 50);
}
componentWillUnmount(){
clearInterval(this.timer);
}
tick(){
this.setState({
hmRot: VrHeadModel.rotation()
});
}
在 0/0/0 处创建一个视图,并像往常一样在场景中定位固定对象。在主视图上设置旋转以匹配相机的旋转。
render(){
let {hmRot} = this.state;
return (
<View
style={{
position: 'absolute',
layoutOrigin: [0.5, 0.5],
transform: [
{translate: [0, 0, 0]},
{rotateX: hmRot[0]},
{rotateY: hmRot[1]},
{rotateZ: hmRot[2]}
]
}}>
<Text
style={{
position: 'absolute',
layoutOrigin: [0.5, 0.5],
backgroundColor: '#f00',
transform: [
{translate: [0, 0, -2]},
]
}}>
Fixed
</Text>
</View>
);
}
这里有来自 React VR 团队的关于此问题的相关 post: https://github.com/facebook/react-vr/issues/261
答案是使用多个表面:一个不锁头,另一个锁头。
请参阅此处 "Using Multiple Surfaces":Surfaces - React 360
要让您的工作正常,请将示例中缺少的代码分别粘贴到您的 client.js 和 index.js 文件中:
这是一个 link 的工作示例(部分粘贴在下方):Headlocked Surfaces
import { Math as VRMath, ReactInstance, Surface } from "react-360-web";
function init(bundle, parent, options = {}) {
const horizontalPanel = new Surface(300, 300, Surface.SurfaceShape.Flat);
const hvPanel = new Surface(300, 300, Surface.SurfaceShape.Flat);
horizontalPanel.setAngle(0, -0.5);
const cameraDirection = [0, 0, -1];
const r360 = new ReactInstance(bundle, parent, {
fullScreen: true,
frame: () => {
const cameraQuat = r360.getCameraQuaternion();
cameraDirection[0] = 0;
cameraDirection[1] = 0;
cameraDirection[2] = -1;
// cameraDirection will point out from the view of the camera,
// we can use it to compute surface angles
VRMath.rotateByQuaternion(cameraDirection, cameraQuat);
const cx = cameraDirection[0];
const cy = cameraDirection[1];
const cz = cameraDirection[2];
const horizAngle = Math.atan2(cx, -cz);
const vertAngle = Math.asin(cy / Math.sqrt(cx * cx + cy * cy + cz * cz));
horizontalPanel.setAngle(horizAngle, -0.5);
hvPanel.setAngle(horizAngle, vertAngle);
},
...options
});
r360.renderToSurface(r360.createRoot("HorizontalPanel"), horizontalPanel);
r360.renderToSurface(r360.createRoot("HVPanel"), hvPanel);
}
window.React360 = { init };
在你的client.js中:
在 ReactInstance
构造函数的 frame
属性 中,设置表面角度以匹配相机:水平,或水平和垂直。
在你的index.js中:
记得将 React 组件注册到新的 headlocked surface。