reactjs 将Google 's< model-viewer>与React/Reagent集成

dm7nw8vv  于 2023-03-12  发布在  React
关注(0)|答案(2)|浏览(214)

Google的提供了我需要的所有关键特性,而不必通过react-three-fiber或直接在three.js中编写自定义解决方案。
我正在努力解决如何将它正确地集成到一个试剂(和React)结构中。
为了让它更容易和vanilla JS一起使用,它被构建成一个web组件,并且很大程度上是通过它的html元素的属性来控制的。通常这不会是一个大问题,但是由于3D的开销和加载大型模型重新渲染,这是昂贵的,并且在许多情况下会破坏功能。
我试着在一个组件中简单地使用它,并试图消除重新呈现的可能性。使用一个ref直接改变它。
我还尝试将其设置为从试剂/React控制应用程序手动创建的html元素,并通过其dom元素在各种事件中引用它。
这两个选项都引入了许多问题,在单页面应用程序中并不理想。

我想知道是否有人有关于如何在React/Reagent shell中最好地 Package 它,同时仍然可以访问核心元素以使用其底层JS API的提示。

答案不一定要在ClojureScript中。
下面是他们页面上的用法示例:

<model-viewer 
  alt="Neil Armstrong's Spacesuit from the Smithsonian Digitization Programs Office and National Air and Space Museum" 
  src="shared-assets/models/NeilArmstrong.glb" 
  ar ar-modes="webxr scene-viewer quick-look" environment-image="shared-assets/environments/moon_1k.hdr" 
  poster="shared-assets/models/NeilArmstrong.webp" 
  seamless-poster 
  shadow-intensity="1" 
  camera-controls>
</model-viewer>

谢谢你的建议。
关于Clojurians Slack的其他讨论(链接需要访问Slack)
关于Clojureverse的其他讨论

n3schb8v

n3schb8v1#

1.将其作为module类型的脚本包含在index.html中。

<!DOCTYPE html>
<html lang="en">
  <head>
....
    <script
      type="module"
      src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"
    ></script>
...

  </head>

  ...
</html>

1.将其用作react组件中的元素

import "./styles.css";
    import React, { useState } from "react";
    
    export default function App() {
      const modelRef = React.useRef();
    
      return (
        <model-viewer
          // className="model-viewer"
          src="./M08.glb"
          alt="A rock"
          exposure="0.008"
          camera-controls
          ar
          ar-modes="webxr"
          ref={(ref) => {
            modelRef.current = ref;
          }}
        >
        </model-viewer>
      );
    }

1.与之互动
这是一个交互,其中onclick事件使用模型提供的函数将屏幕坐标转换为模型坐标。2它存储这些注解并将它们呈现为模型的子对象。3这在文档中提供

import "./styles.css";
import React, { useState } from "react";

export default function App() {
  const modelRef = React.useRef();
  const [annots, setAnnots] = useState([]);

  const handleClick = (event) => {
    const { clientX, clientY } = event;

    if (modelRef.current) {
      let hit = modelRef.current.positionAndNormalFromPoint(clientX, clientY);
      if (hit) {
        setAnnots((annots) => {
          return [...annots, hit];
        });
      }
    }
  };

  const getDataPosition = (annot) => {
    return `${annot.position.x} ${annot.position.y} ${annot.position.z}`;
  };

  const getDataNormal = (annot) => {
    return `${annot.normal.x} ${annot.normal.y} ${annot.normal.z}`;
  };

  return (
    <model-viewer
      // className="model-viewer"
      src="./M08.glb"
      alt="A rock"
      exposure="0.008"
      camera-controls
      ar
      ar-modes="webxr"
      onClick={handleClick}
      ref={(ref) => {
        modelRef.current = ref;
      }}
    >
      {annots.map((annot, idx) => (
        <button
          key={`hotspot-${idx}`}
          className="view-button"
          slot={`hotspot-${idx}`}
          data-position={getDataPosition(annot)}
          data-normal={getDataNormal(annot)}
        ></button>
      ))}
    </model-viewer>
  );
}

代码沙盒:https://codesandbox.io/s/lingering-tree-d41cr?file=/src/App.js:0-1287

dvtswwa3

dvtswwa32#

要在React中使用<model-viewer>元素,可以使用react-model-viewer库,它提供了一个围绕<model-viewer>元素的React组件 Package 器。
首先,需要通过在项目目录中运行以下命令来安装react-model-viewer

npm install react-model-viewer

然后,在React组件文件中,可以从react-model-viewer导入ModelViewer组件:

import React from 'react';
import { ModelViewer } from 'react-model-viewer';

const MyComponent = () => {
  return (
    <ModelViewer
      alt="Neil Armstrong's Spacesuit from the Smithsonian Digitization Programs Office and National Air and Space Museum"
      src="shared-assets/models/NeilArmstrong.glb"
      environmentImage="shared-assets/environments/moon_1k.hdr"
      poster="shared-assets/models/NeilArmstrong.webp"
      shadowIntensity={1}
      cameraControls
      touchAction="pan-y"
    />
  );
}

export default MyComponent;

注意,ModelViewer组件props是用camelCase而不是kebab-case编写的,因此在您提供的示例中environment-image变为environmentImage

相关问题