React-360 源码阅读【3】
React-360 源码阅读【3】
上一篇简单说了下 scripts
目录究竟用来做什么,今天我们开始进入到正题,我们看下Libraries 下究竟做了什么;
其实和 react-native 下的目录一致,罗列我们可用的组件和模块文件;比如:
- Pano
- Camera
- Sound
- ...
我们看下入口文件 react-360.js
const React360 = {
// React Native overrides
get View() {
return require('View');
},
get Image() {
return require('Image');
},
get Text() {
return require('Text');
},
// VR Components and modules
get AmbientLight() {
return require('AmbientLight');
},
get Box() {
return require('Box');
},
get LiveEnvCamera() {
return require('LiveEnvCamera');
},
get Cylinder() {
return require('Cylinder');
},
get CylindricalPanel() {
return require('CylindricalPanel');
},
get QuadPanel() {
return require('QuadPanel');
},
get Plane() {
return require('Plane');
},
get Sphere() {
return require('Sphere');
},
get DirectionalLight() {
return require('DirectionalLight');
},
get PointLight() {
return require('PointLight');
},
get SpotLight() {
return require('SpotLight');
},
get Model() {
return require('Model');
},
get Pano() {
return require('Pano');
},
get Prefetch() {
return require('Prefetch');
},
get Scene() {
return require('Scene');
},
get Sound() {
return require('Sound');
},
get Video() {
return require('Video');
},
get VideoPano() {
return require('VideoPano');
},
get VideoControl() {
return require('VideoControl');
},
get MediaPlayerState() {
return require('MediaPlayerState');
},
get VrAnimated() {
return require('VrAnimated');
},
get VrButton() {
return require('VrButton');
},
get VrHeadModel() {
return require('VrHeadModel');
},
get VrSoundEffects() {
return require('VrSoundEffects');
},
get Environment() {
return require('Environment');
},
// React VR-specific utilities
get asset() {
return require('asset');
},
get staticAssetURL() {
return require('staticAssetURL').default;
},
get texture() {
return require('texture');
},
// Direct access to RN properties
get Animated() {
return require('Animated');
},
get AppRegistry() {
return require('AppRegistry');
},
get AsyncStorage() {
return require('AsyncStorage');
},
get NativeModules() {
return require('NativeModules');
},
get StyleSheet() {
return require('StyleSheet');
},
};
module.exports = React360;
初一看,文件很明显,就是调用 React-360 模块,然后调用对应模块的代码;
比如我会在代码里面这么用:
import {View, Image} from 'react-360'
大家一看代码就知道了。这里其实关于 require
可能会有歧义;
似乎应该是
require('./View')
其实这里的 require
和 我们平常在 Node 当中用到的模块有些不一样;你可以在 Facebook 最新的项目 metro 里找到实现,当然这个我后面补一篇文章说下 metro 。
回到正题,我们可以把 Libraries 里面的模块和组件理解为整个 React-360 对外暴露的可以用到的部分。我们先从 最常用的组件 Components/View/View.vr.js 里面去看;
const EdgeInsetsPropType = require('EdgeInsetsPropType');
// 详见 https://github.com/facebook/react-native/blob/master/Libraries/Renderer/shims/NativeMethodsMixin.js
const NativeMethodsMixin = require('NativeMethodsMixin');
const PropTypes = require('prop-types');
const React = require('React');
const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const StyleSheetPropType = require('StyleSheetPropType');
const UIManager = require('UIManager');
const ViewStylePropTypes = require('ViewStylePropTypes');
const createReactClass = require('create-react-class');
// https://github.com/facebook/react-native/blob/master/Libraries/ReactNative/requireNativeComponent.js
// 需要阅读 https://github.com/facebook/react-native/blob/master/Libraries/Renderer/shims/createReactNativeComponentClass.js
const requireNativeComponent = require('requireNativeComponent');
const stylePropType = StyleSheetPropType(ViewStylePropTypes);
const AccessibilityTraits = [
'none',
'button',
'link',
'header',
'search',
'image',
'selected',
'plays',
'key',
'text',
'summary',
'disabled',
'frequentUpdates',
'startsMedia',
'adjustable',
'allowsDirectInteraction',
'pageTurn',
];
const AccessibilityComponentType = [
'none',
'button',
'radiobutton_checked',
'radiobutton_unchecked',
];
...
我们从代码里看到了很多模块,而且很多模块是 React-Native 中所以这里面重点说几个文件;
requireNativeComponent.js
其实代码很简单, 在这之前需要先了解 createReactNativeComponentClass.js。
import type {ViewConfigGetter} from './ReactNativeTypes';
// https://github.com/facebook/react-native/blob/master/Libraries/Renderer/shims/createReactNativeComponentClass.js
// 你可以将当前组件名称注册到某个地方,当加载 view 的配置时候则会出发你设置的回调
const {register} = require('ReactNativeViewConfigRegistry');
// 函数就是接受一个字符串也就是 component 的名称,然后可以接受 配置的回调函数
const createReactNativeComponentClass = function(
name: string,
callback: ViewConfigGetter,
): string {
return register(name, callback);
};
module.exports = createReactNativeComponentClass;
接下来我们再来看 requireNativeComponent.js 就比较好理解了。
const createReactNativeComponentClass = require('createReactNativeComponentClass');
const getNativeComponentAttributes = require('getNativeComponentAttributes');
/**
其实我们是通过一种映射,类似将 react-360 里面的组件 view 映射到本地运行时的 RTCView ,然后我们会将这些模块进行创建然后存储起来。
*
*/
const requireNativeComponent = (uiViewClassName: string): string =>
createReactNativeComponentClass(uiViewClassName, () =>
getNativeComponentAttributes(uiViewClassName),
);
module.exports = requireNativeComponent;
下一篇我们在继续讲 view 的代码吧。