构建react组件库
React VR是FacebookJavaScript库,可减少创建WebVR应用程序的工作量。 您可以将Mozilla的 React VR与A-Frame进行比较,但不是编写HTML,而是通过JavaScript使用JavaScript创建WebVR场景。
React VR建立在WebGL库three.js和React Native框架上。 这意味着我们能够使用JSX标签,React Native组件(如<View>
或<Text>
)或React Native概念(如flexbox布局)。 为了简化创建WebVR场景的过程,React VR内置了对3D网格,灯光,视频,3D形状或球形图像的支持。
在本文中,我们想使用React VR为球形图像构建查看器。 为此,我们将使用四张等矩形的照片,这些照片是我用Theta S相机在React Conf 2017上拍摄的 。 画廊将有四个按钮来交换图像,这些按钮可与鼠标和/或VR耳机配合使用。 您可以在此处下载等矩形图像以及按钮图形。 最后但并非最不重要的一点,我们将通过添加简单的按钮过渡来了解动画如何与React VR配合使用。
为了进行开发,我们在桌面上使用Chrome之类的浏览器。 为了检查VR设备的立体渲染是否正常,我们使用了带有Gear VR的三星手机。 从理论上讲,任何支持WebVR的移动浏览器都应该能够以立体的方式呈现我们的应用程序,以用于GearVR,Google Cardboard甚至Google Daydream。 但是该库以及API仍在开发中,因此支持可能并不可靠。 以下是当前支持WebVR功能的浏览器的摘要 。
开发设置和项目结构
让我们从安装React VR CLI工具开始。 然后在一个名为GDVR_REACTVR_SITEPOINT_GALLERY
的新文件夹中创建一个具有所有依赖项的新React VR项目:
npm install -g react-vr-cli
react-vr init GDVR_REACTVR_SITEPOINT_GALLERY
cd GDVR_REACTVR_SITEPOINT_GALLERY
要启动本地开发服务器,我们将运行npm脚本并在Chrome中浏览至http://localhost:8081/vr/
。
npm start
如果您看到一个黑色的和白色的房间,上面有楼梯,Struts和“ hello”文字平面,那么一切都正确。
React VR CLI支持的最重要的文件和文件夹是:
-
index.vr.js
。 这是应用程序的入口。 目前,该文件包含React VR默认场景的全部源代码,正如我们在浏览器中已经看到的那样。 -
static_assets
。 此文件夹应包含应用程序中使用的所有资产。 我们将等矩形图像和按钮图形放在此文件夹中。
我们希望我们的项目包含三个组成部分:
- 一个Canvas组件,其中包含全球形图像的代码
- 一个Button组件,它创建一个VR按钮来交换图像
- 一个UI组件,它从四个Button组件中构建一个UI。
这三个组件将各自具有自己的文件,因此让我们创建一个components
文件夹来包含这些文件。 然后,在开始创建Canvas组件之前,让我们从index.vr.js
文件中删除脚手架示例代码,如下所示:
/* index.vr.js */
import React from 'react';
import {
AppRegistry,
View,
} from 'react-vr';
export default class GDVR_REACTVR_SITEPOINT_GALLERY extends React.Component {
render() {
return (
<View>
</View>
);
}
};
AppRegistry.registerComponent('GDVR_REACTVR_SITEPOINT_GALLERY', () => GDVR_REACTVR_SITEPOINT_GALLERY);
向场景添加球面图像
要将球形图像添加到场景中,我们将在components
文件夹中创建一个新文件Canvas.js
:
/* Canvas.js */
import React from 'react';
import {
asset,
Pano,
} from 'react-vr';
class Canvas extends React.Component {
constructor(props) {
super(props);
this.state = {
src: this.props.src,
}
}
render() {
return (
<Pano source={asset(this.state.src)}/>
);
}
};
export default Canvas;
在代码的前六行中,我们导入依赖项。 然后,我们声明Canvas组件,并使用JSX语法定义其呈现方式。
如果您想了解有关JSX的更多信息,建议您阅读“ React和JSX入门” 。
看一下JSX代码,可以发现Canvas组件仅返回一个组件,即React VR <Pano>
组件。 它有一个参数, source
prop,它使用asset
函数从static_assets
文件夹加载图像。 该参数引用一个状态,我们在构造函数中对其进行了初始化。
在我们的例子中,我们不想在Canvas组件本身中定义路径,而是使用index.vr.js
文件定义所有图像路径。 这就是为什么state.src
对象引用组件的props
对象的原因。
![](https://img-blog.csdnimg.cn/2022010617150160030.png)
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
检查出的ReactJS文档React.Component如果您想了解更多关于状态和道具。
让我们继续修改index.vr.js
文件以使用Canvas组件并将其渲染到场景中:
/* index.vr.js */
import React from 'react';
import {
AppRegistry,
View,
} from 'react-vr';
import Canvas from './components/Canvas';
export default class GDVR_REACTVR_SITEPOINT_GALLERY extends React.Component {
constructor() {
super();
this.state = {
src: 'reactconf_00.jpg',
};
}
render() {
return (
<View>
<Canvas
src={this.state.src}
/>
</View>
);
}
};
AppRegistry.registerComponent('GDVR_REACTVR_SITEPOINT_GALLERY', () => GDVR_REACTVR_SITEPOINT_GALLERY);
除了已经使用的React VR依赖项,我们还需要导入自定义的Canvas组件。 接下来,我们在第六行中声明应用程序类:
/* index.vr.js */
import Canvas from './components/Canvas';
然后,将<Canvas>
组件添加为<View>
组件的子组件。 我们使用src
作为组件的prop,因为我们在Canvas组件中引用了它。 现在,浏览器中的外观应该可以显示全景图像,并且我们已经能够与其进行交互。
创建一个UI组件以容纳四个按钮
我们现在要做的是创建四个按钮,用户可以触发这些按钮来交换图像。 因此,我们将添加两个新组件:UI组件及其子组件Button组件。 让我们从Button组件开始:
/* Button.js */
import React from 'react';
import {
asset,
Image,
View,
VrButton,
} from 'react-vr';
class Button extends React.Component {
onButtonClick = () => {
this.props.onClick();
}
render () {
return (
<View
style={{
alignItems: 'center',
flexDirection: 'row',
margin: 0.0125,
width: 0.7,
}}
>
<VrButton
onClick={this.onButtonClick}
>
<Image
style={{
width: 0.7,
height: 0.7,
}}
source={asset(this.props.src)}
>
</Image>
</VrButton>
</View>
);
}
};
export default Button;
为了构建按钮,我们使用React VR的<VrButton>
组件,该组件在第六行中导入。 另外,由于<VrButton>
组件本身没有外观,因此我们正在使用图像组件将资产图像添加到每个按钮。 和以前一样,我们使用道具来定义图像源。 我们在此组件中使用过两次的另一个功能是style
道具,可以为每个按钮及其图像添加布局值。 <VrButton>
也使用事件侦听器onClick
。
要将四个Button组件添加到场景中,我们将使用UI父组件,然后将其作为子代添加到index.vr.js
。 在编写UI组件之前,让我们创建一个配置对象,定义等角图像,按钮图像和按钮本身之间的关系。 为此,我们在index.vr.js
文件中的import语句之后声明一个常量:
/* index.vr.js */
const Config = [
{
key: 0,
imageSrc: 'reactconf_00.jpg',
buttonImageSrc: 'button-00.png',
},
{
key: 1,
imageSrc: 'reactconf_01.jpg',
buttonImageSrc: 'button-01.png',
},
{
key: 2,
imageSrc: 'reactconf_02.jpg',
buttonImageSrc: 'button-02.png',
},
{
key: 3,
imageSrc: 'reactconf_03.jpg',
buttonImageSrc: 'button-03.png',
}
];
UI组件将使用配置中定义的值来处理凝视和单击事件:
/* UI.js */
import React from 'react';
import {
View,
} from 'react-vr';
import Button from './Button';
class UI extends React.Component {
constructor(props) {
super(props);
this.buttons = this.props.buttonConfig;
}
render () {
const buttons = this.buttons.map((button) =>
<Button
key={button.key}
onClick={()=>{
this.props.onClick(button.key);
}}
src={button.buttonImageSrc}
/>
);
return (
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
transform: [
{rotateX: -12},
{translate: [-1.5, 0, -3]},
],
width: 3,
}}
>
{buttons}
</View>
);
}
};
export default UI;
为了设置图像的来源,我们使用已经添加到index.vr.js
文件中的配置值。 我们还将使用道具onClick
来处理click事件,还将在稍后将其添加到index.vr.js
文件中。 然后,我们创建与按钮配置对象中定义的一样多的按钮,以稍后将它们添加到将呈现到场景中的JSX代码中:
/* UI.js */
const buttons = this.buttons.map((button) =>
<Button
key={button.key}
onClick={()=>{
this.props.onClick(button.key);
}}
src={button.buttonImageSrc}
/>
);
现在,我们要做的就是将UI组件添加到index.vr.js
文件中定义的场景中。 因此,我们在导入Canvas组件之后立即导入UI组件:
/* index.vr.js */
import UI from './components/UI';
接下来,我们将<Canvas>
组件添加到场景中:
/* index.vr.js */
<View>
<Canvas
src={this.state.src}
/>
<UI
buttonConfig={Config}
onClick={(key)=>{
this.setState({src: Config[key].imageSrc});
}}
/>
</View>
在浏览器中检查此代码时,您会注意到单击当前不会触发图像源交换。 要收听更新的道具,我们必须在构造函数之后立即向Canvas组件添加另一个函数。
如果您对React组件的生命周期感兴趣,则可能需要阅读React docs中的React.Component 。
/* Canvas.js */
componentWillReceiveProps(nextProps) {
this.setState({src: nextProps.src});
}
现在,在浏览器中进行的测试应该会成功,并且单击按钮图像应会更改球形图像。
为按钮状态转换添加动画
为了使按钮对用户交互更加敏感,我们希望添加一些悬停状态以及默认的空闲状态和悬停状态之间的过渡。 为此,我们将使用Animated库和Easing函数 ,然后为每个过渡写入函数: animateIn
和animateOut
:
/* Button.js */
import React from 'react';
import {
Animated,
asset,
Image,
View,
VrButton,
} from 'react-vr';
const Easing = require('Easing');
class Button extends React.Component {
constructor(props) {
super();
this.state = {
animatedTranslation: new Animated.Value(0),
};
}
animateIn = () => {
Animated.timing(
this.state.animatedTranslation,
{
toValue: 0.125,
duration: 100,
easing: Easing.in,
}
).start();
}
animateOut = () => {
Animated.timing(
this.state.animatedTranslation,
{
toValue: 0,
duration: 100,
easing: Easing.in,
}
).start();
}
onButtonClick = () => {
this.props.onClick();
}
render () {
return (
<Animated.View
style={{
alignItems: 'center',
flexDirection: 'row',
margin: 0.0125,
transform: [
{translateZ: this.state.animatedTranslation},
],
width: 0.7,
}}
>
<VrButton
onClick={this.onButtonClick}
onEnter={this.animateIn}
onExit={this.animateOut}
>
<Image
style={{
width: 0.7,
height: 0.7,
}}
source={asset(this.props.src)}
>
</Image>
</VrButton>
</Animated.View>
);
}
};
export default Button;
添加依赖项后,我们定义一个新状态来保存我们要设置动画的转换值:
/* Button js */
constructor(props) {
super();
this.state = {
animatedTranslation: new Animated.Value(0),
};
}
接下来,我们定义两个动画,每个动画都在一个单独的函数中,分别描述当光标进入按钮和退出按钮时播放的动画:
/* Button.js */
animateIn = () => {
Animated.timing(
this.state.animatedTranslation,
{
toValue: 0.125,
duration: 100,
easing: Easing.in,
}
).start();
}
animateOut = () => {
Animated.timing(
this.state.animatedTranslation,
{
toValue: 0,
duration: 100,
easing: Easing.in,
}
).start();
}
要在JSX代码中使用state.animatedTranslation
值,我们必须通过添加<Animated.view>
使<View>
组件具有动画效果:
/* Button.js */
<Animated.View
style={{
alignItems: 'center',
flexDirection: 'row',
margin: 0.0125,
transform: [
{translateZ: this.state.animatedTranslation},
],
width: 0.7,
}}
>
当事件监听器onButtonEnter
和onButtonExit
触发时,我们将调用该函数:
/* Button.js */
<VrButton
onClick={this.onButtonClick}
onEnter={this.animateIn}
onExit={this.animateOut}
>
在浏览器中测试我们的代码应显示每个按钮在z轴上的位置之间的转换:
构建和测试应用程序
在不支持http://localhost:8081/vr/index.html
的浏览器中,在支持WebVR的浏览器中打开您的应用程序并导航至开发服务器,而不要使用IP地址(例如, http://192.168.1.100:8081/vr/index.html
http://localhost:8081/vr/index.html
http://192.168.1.100:8081/vr/index.html
。 然后,点击View in VR
按钮,这将打开全屏视图并开始立体渲染。
要将应用程序上载到服务器,可以运行npm脚本npm run bundle
,它将在vr
目录中使用编译的文件创建一个新的build
文件夹。 在您的Web服务器上,您应该具有以下目录结构:
Web Server
├─ static_assets/
│
├─ index.html
├─ index.bundle.js
└─ client.bundle.js
更多资源
这就是我们用React VR创建一个小型WebVR应用程序所要做的。 您可以在GitHub上找到整个项目代码 。
React VR还有一些我们在本教程中没有讨论的组件:
- 有一个用于渲染文本的
Text
组件。 - 可以使用四种不同的灯光组件向场景添加灯光:
AmbientLight
,DirectionalLight
,PointLight
和Spotlight
。 -
Sound
组件将空间声音添加到3D场景中的位置。 - 要添加视频,可以使用
Video
组件或VideoPano
组件。 特殊的VideoControl
组件添加了用于视频播放和音量的控件。 - 使用“
Model
组件,我们可以将obj
格式的3D模型添加到应用程序中。 -
CylindricalPanel
组件可用于将子元素与圆柱体的内表面对齐-例如,用于对齐用户界面元素。 - 创建3D基本
sphere
组件有三个:sphere
组件,plane
组件和box
组件。
另外,React VR仍在开发中,这也是其仅在Carmel Developer Preview浏览器中运行的原因。 如果您有兴趣了解有关React VR的更多信息,那么这里有一些有趣的资源:
- ReactVR文档
- 在GitHub上ReactVR
- 很棒的React VR ,这是React VR资源的集合。
而且,如果您想进一步深入了解WebVR,这些文章可能适合您:
您是否已经使用React VR? 您是否为此做了一些很棒的项目? 我希望知道您在评论中的看法和经验!
如果您喜欢本文,并想从头开始学习React,请查看我们的React ES6 Way课程。
这篇文章是由同行评审莫里茨克罗格和蒂姆Severien 。 感谢所有SitePoint的同行评审员使SitePoint内容达到最佳状态!
翻译自: https://www.sitepoint.com/building-a-full-sphere-3d-image-gallery-with-react-vr/
构建react组件库