如何在React Native中展示360度图片

4

如何在Android应用程序中显示360度图像或视频。我的React Native版本是51


1
你能试试 https://github.com/tiero/react-native-360 吗? - Ajay S
我在使用这个软件包时遇到了问题,请点击此链接。 - Mohammadsgh
你是指这个链接“https://github.com/tiero/react-native-360”吗?对我来说它运行良好。 - Ajay S
你找到答案了吗?如果你只是用WebViews来显示图片,那么在React Native中使用它们会很糟糕。另一方面,所有声称使用Google VR的现有库似乎都已经过时/损坏。 - Cristiano Coelho
我基于 @elquimista 在 Expo 上的代码片段实现了一个小食品。这个问题很久了,但我会把它留在这里。https://snack.expo.io/@gaboelnuevo/360-viewer - gabosl
4个回答

4
你可以使用React Native 360。这是一个 React Native 包装器,用于在 React Native 中使用谷歌 VR Cardboard SDK来处理360度图片。 全景示例
import { PanoramaView } from 'react-native-360';
<PanoramaView 
    style={{height:200,width:width}}
    image={require('./andes.jpg')}
    displayMode={'embedded'}
    enableFullscreenButton
    enableCardboardButton
    enableTouchTracking
    hidesTransitionView
    enableInfoButton={false}              
/>

Android封装程序仍在开发中,请关注更新。


我在这个包中遇到了问题。请点击此链接link - Mohammadsgh
你确定已经安装、链接了 react-native-360 并重新安装了应用程序吗? - Pir Shukarullah Shah
是的。我已经安装了react-native-360,请查看我的package.json文件。 - Mohammadsgh
"dependencies": { "axios": "^0.17.1", "native-base": "^2.3.6", "react": "16.0.0", "react-native": "0.51.0", "react-native-360": "^1.0.9", "react-native-app-intro-slider": "^0.2.2", "react-native-maps": "^0.19.0", "react-native-router-flux": "^4.0.0-beta.25", "react-native-vector-icons": "^4.4.3" }, "devDependencies": { "babel-jest": "22.0.4", "babel-preset-react-native": "4.0.0", "jest": "22.0.4", "react-test-renderer": "16.0.0" } - Mohammadsgh

2
如果您正在使用Expo,可以将expo-three与GLView结合使用,模拟全景视图(不完全与本机360照片查看器应用程序相同,但类似)。您可以在此处找到全景等距投影照片示例的原始three.js源代码 - https://github.com/mrdoob/three.js/blob/master/examples/webgl_panorama_equirectangular.html
我尝试了这种方法,并使以下代码起作用。
import React from 'react';
import NativeTachyons from 'react-native-style-tachyons';
import { GLView } from 'expo';
import ExpoTHREE, { THREE } from 'expo-three';
import PinchZoomResponder from 'react-native-pinch-zoom-responder';

THREE.suppressExpoWarnings(true);

@NativeTachyons.wrap
export default class PhotoView360 extends React.Component {
  constructor(props) {
    super(props);
    this.lat = 0;
    this.lon = 0;
    this.latOnTap = 0;
    this.lonOnTap = 0;
    this.locationXStart = null;

    this._panResponder = new PinchZoomResponder({
      onPinchZoomStart: e => {
        this.cameraFov = this.camera.fov;
      },
      onResponderMove: (e, gestureState) => {
        if (gestureState) {
          const { scaleX, scaleY } = gestureState;
          const scale = Math.sqrt(scaleX * scaleX + scaleY * scaleY);
          const fov = this.cameraFov / Math.max(0, scale - 0.4);
          this.camera.fov = THREE.Math.clamp(fov, 10, 75);
          this.camera.updateProjectionMatrix();
        }
      }
    });
    const { onResponderGrant, onResponderMove, onResponderRelease } = this._panResponder.handlers;
    this._panResponder.handlers.onResponderGrant = e => {
      if (e.nativeEvent.touches.length === 1) {
        this.latOnTap = this.lat;
        this.lonOnTap = this.lon;
        this.locationXStart = e.nativeEvent.touches[0].locationX;
        this.locationYStart = e.nativeEvent.touches[0].locationY;
      } else {
        onResponderGrant(e);
      }
    };
    this._panResponder.handlers.onResponderMove = e => {
      if (e.nativeEvent.touches.length === 1) {
        if (this.locationXStart !== null) {
          const factor = this.camera.fov / 75 * 0.1;
          this.lon = this.lonOnTap - (e.nativeEvent.touches[0].locationX - this.locationXStart) * factor;
          this.lat = this.latOnTap + (e.nativeEvent.touches[0].locationY - this.locationYStart) * factor;
        }
      } else {
        onResponderMove(e);
      }
    };
    this._panResponder.handlers.onResponderRelease = e => {
      this.locationXStart = null;
      onResponderRelease(e);
    };
  }

  render() {
    return pug`
      GLView.flx-i(
        ...this._panResponder.handlers
        onContextCreate=${async gl => {
          const scene = new THREE.Scene();
          const renderer = new ExpoTHREE.Renderer({ gl });
          const geometry = new THREE.SphereBufferGeometry(500, 60, 40);
          const material = new THREE.MeshBasicMaterial({
            map: await ExpoTHREE.loadTextureAsync({ asset: this.props.assetUri })
          });
          const mesh = new THREE.Mesh(geometry, material);
          renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);
          geometry.scale(1, 1, -1);
          scene.add(mesh);
          this.camera = new THREE.PerspectiveCamera(
            75,
            gl.drawingBufferWidth / gl.drawingBufferHeight,
            1,
            1100
          );
          this.camera.target = new THREE.Vector3(0, 0, 0);
          let phi = 0;
          let theta = 0;
          const animate = () => {
            requestAnimationFrame(animate);
            this.lat = Math.max(-85, Math.min(85, this.lat));
            phi = THREE.Math.degToRad(90 - this.lat);
            theta = THREE.Math.degToRad(this.lon);
            this.camera.target.x = 500 * Math.sin(phi) * Math.cos(theta);
            this.camera.target.y = 500 * Math.cos(phi);
            this.camera.target.z = 500 * Math.sin(phi) * Math.sin(theta);
            this.camera.lookAt(this.camera.target);
            renderer.render(scene, this.camera);
            gl.endFrameEXP();
          }
          animate();
        }}
      )
    `;
  }
}

请随意在评论区提问。

这段代码对我来说不起作用。你能分享一个可行的样例吗? - Niroshan Ranapathi
你能否再详细解释一下如何运行这个程序? - udaybhaskar

1
使用 react-native-gvr 适用于 iOS 平台,使用 react-native-gvr-video-android 适用于 Android 平台。

-1
请阅读以下内容:

https://facebook.github.io/react-vr/docs/pano.html

Panos是全景照片,它们被投射在完全环绕着观众的球体上。这是VR应用程序的核心图像格式。您可以使用特殊的360摄像机硬件创建360度照片。通常情况下,它们采用全景图像格式(Equirectangular),覆盖完整的360°水平和180°垂直角度。


这个 Pano 组件是为 react-vr 而不是为 react-native 设计的。你确定它能在 react-native 中使用吗? - Pir Shukarullah Shah
https://github.com/facebook/react-vr/issues/225 - Seyha
1
目前除非使用“webview”,否则无法实现。它永远不会具有本地性能。 - Pir Shukarullah Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接