我正在尝试使用Google的模型查看器来加载3D模型。它有一个按钮。但我希望该按钮在模型完全加载后可见。所以,我过去常常使用这个普通的JavaScript代码
<script>
const modelViewer = document.querySelector("model-viewer");
const button = document.getElementById("my_ar_button");
modelViewer.addEventListener("load", function() {
button.style.display = "block";
});
</script>现在我计划在ReactJS中使用它,如下所示
const modelViewer = document.querySelector("model-viewer");
const button = document.getElementById("my_ar_button");
modelViewer.addEventListener("load", function() {
button.style.display = "block";
});
<model-viewer
src="https://modelviewer.dev/shared-assets/models/reflective-sphere.gltf"
alt="A 3D model of an astronaut"
ar ar-modes="webxr scene-viewer quick-look"
ar-scale="auto"
quick-look-browsers="safari chrome"
ios-src="https://modelviewer.dev/shared-assets/models/Astronaut.usdz"
loading="eager"
poster="https://modelviewer.dev/assets/poster-astronaut.png"
autoplay
camera-controls
>
<button id="my_ar_button" class="my_ar_button" slot="ar-button">Show AR</button>
</model-viewer>我的CSS
.my_ar_button {
display: none;
}我已经使用脚本标记添加了模型查看器
<Helmet>
<script
type="module"
src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"
async
>
</script>
</Helmet>但是它给了我这个错误
TypeError: Cannot read property 'addEventListener' of null发布于 2021-04-16 06:57:22
您需要在React包装器中控制<model-viewer>元素。看react-model-viewer,这是他们的包装器
const useModelLoader = (type, src): ModelData => {
const loader = useMemo(() => getLoader(type), [type]);
const [model, setModel] = useState(undefined);
const [modelCenter, setModelCenter] = useState<THREE.Vector3>(undefined);
const [error, setError] = useState(undefined);
const [progress, setProgress] = useState(0);
useEffect(() => {
loader.load(
// resource URL
src,
// called when the resource is loaded
model => setModel(model),
// called while loading is progressing
({ loaded, total }) => setProgress((loaded / total) * 100),
// called when loading has errors
error => setError(error)
);
}, [loader, src]);
// get the center of the model
useEffect(() => {
if (!model) {
return;
}
const box = new THREE.Box3();
box.setFromObject(model.scene);
const center = new THREE.Vector3();
box.getCenter(center);
setModelCenter(center);
}, [model]);
return { model, modelCenter, progress, error };
};第二个useEffect()依赖于model,因此您可以使用该按钮执行相同的操作。这将是modelViewer.addEventListener("load", function() {的React等效项。
const [showButton, setShowButton] = useState(false);
useEffect(() => {
if (model) { // when model has a value, the loader has completed
setShowButton(true); // now show the button
}
}, [model]);
const Button = showButton ? <button...> : null; // use this to wrap <button>https://stackoverflow.com/questions/67107461
复制相似问题