簡體   English   中英

threejs/typesript - 查看器 object 在渲染一次后被銷毀

[英]threejs/typesript - viewer object gets destroyed after rendering once

我正在嘗試使用threejs和typescript編寫一個object查看器。 它嵌入在反應服務中。

調用初始化查看器 object 時,場景一切正常。 但是,在渲染場景一次(一次執行 animate 函數)后,查看器 object 被破壞,並且我收到一個錯誤,即this is undefined in requestAnimationFrame(this.animate)cannot read property animate of undefined )。 這是我的代碼:

import * as THREE from 'three'

export default class ObjectViewer{
    scene : THREE.Scene;
    camera : THREE.PerspectiveCamera;
    renderer : THREE.WebGLRenderer;

    mesh : THREE.Mesh;

    public constructor(public node : any,
        public width : number = 1100,
        public height: number = 600) {

            this.init();
        }

    protected init() {
        //.. initializing renderer, scene and camera here and adding camera to scene

        this.node.appendChild(this.renderer.domElement);       

        this.camera.position.z = 5;

        this.initTestScene();
    }

    private initTestScene() {
        var geometry = new THREE.BoxGeometry( 1, 1, 1 );
        var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
        this.mesh = new THREE.Mesh( geometry, material );
        this.scene.add( this.mesh );
    }

    private animate() {
        requestAnimationFrame(this.animate);
        this.mesh.rotation.x += 0.1;
        this.renderer.render( this.scene, this.camera );
    }

    public render() {
        this.animate();
    }
}

我從沒有照明的threejs的實時示例中初始化了綠色旋轉立方體。 如果我在動畫塊周圍添加一個if(this)的結果是綠色立方體旋轉一次: 渲染立方體

動畫中的代碼:

if(this){
    requestAnimationFrame(this.animate);
    this.mesh.rotation.x += 0.1;
    this.renderer.render( this.scene, this.camera );
}

我在渲染器中做錯了什么還是似乎是更高級別的問題(例如 object 被包裝它的反應代碼破壞)?

提供更多背景信息:我有一個管理實際查看器並使其可用於周圍反應環境的包裝器:

type Props = {
    width?: number,
    height?: number,
};

export default class ObjectViewerWrapper extends React.Component<Props, {}> {
    node : HTMLDivElement | null;
    viewer : ObjectViewer;

    constructor(props : Props) {
        super(props);

        this.node = null;
    }

    componentDidMount() {
        this.viewer = new ObjectViewer(this.node, this.props.width, this.props.height);
        this.forceUpdate();
    }

    componentDidUpdate(){
        if(this.viewer) {
            this.viewer.render();
        }
    }

    render() {
        return(
            <div style={{"height": "100%", "width": "100%", "position": "relative"}} ref={ inst => { this.node = inst } }/>
        );
    }
}

我收到一個錯誤,這是在 requestAnimationFrame(this.animate) 中未定義

你必須綁定 function this.animate = this.animate.bind(this);

工作示例

 const { useState, useEffect, Component, createRef } = React class ObjectViewer { constructor(node, width = 1100, height = 600) { this.node = node; this.width = width; this.height = height; this.requestAnimationFrameHandle = null; this.animate = this.animate.bind(this); this.init(); } init() { this.scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera( 45, this.width / this.height, 1, 1000 ) this.renderer = new THREE.WebGLRenderer(); const element = this.node.current; element.appendChild(this.renderer.domElement); this.renderer.setSize(this.width, this.height); this.camera.position.z = 5; this.initTestScene(); this.render(); } destroy() { if(this.requestAnimationFrameHandle) { cancelAnimationFrame(this.requestAnimationFrameHandle) } this.node = null; this.camera = null; this.scene = null; this.mesh = null; } initTestScene() { var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); this.mesh = new THREE.Mesh( geometry, material ); this.scene.add( this.mesh ); } animate() { this.requestAnimationFrameHandle = requestAnimationFrame(this.animate); this.mesh.rotation.x += 0.1; this.renderer.render( this.scene, this.camera ); } render() { this.animate(); } } class ObjectViewerWrapper extends Component { constructor(props) { super(props); this.node = createRef(); } componentDidMount() { const { width, height } = this.props; this.viewer = new ObjectViewer(this.node, width, height); this.forceUpdate(); } componentWillUnmount() { this.viewer.destroy(); } componentDidUpdate() { if(this.viewer) { this.viewer.render(); } } render() { const style = { "height": "100%", "width": "100%", "position": "relative" } return(<div style={style} ref={this.node}/>); } } const App = () => { const [dimension, setDimension] = useState(null); useEffect(() => { setDimension({ width: window.innerWidth, height: window.innerHeight }) }, []) if(.dimension) { return <span>Loading..,</span> } const { width; height } = dimension. return <ObjectViewerWrapper width={width} height={height}/> } ReactDOM,render( <App />. document;getElementById('root') );
 html, body { margin: 0; height: 100%; } #root { height: 100%; }
 <script src="https://unpkg.com/react/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r99/three.js"></script> <div id="root"></div>

找到了問題並解決了問題,即使我不知道為什么它沒有更早地工作。 我必須在渲染 function 中定義動畫 function:

public render() {
    let viewer = this;
    function animate() {
        requestAnimationFrame(animate);
        // animation stuff
        viewer.renderer.render( viewer.scene, viewer.camera );
    }
    animate();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM