简体   繁体   中英

Threejs, why render setSize function is being executed before the code which is before it?

Hello I have one doubt:

Today I tryed to change canvas' size dinamically. I would like to get the size of the Plane loaded and put its size into the canvas's size, to adapt canvas to whatever plane's size is.

First, debugging the program I see that the first canvas 800x600 is being created, which is correct:

在此处输入图片说明

Second I thougt it would be linear and go to the load function to get the model from local sotrage, however it went to the renderer.setSize()

在此处输入图片说明

Then the same two steps are done for the second canvas:

在此处输入图片说明

在此处输入图片说明

Then, in the fifth and sixth steps we load the model into the canvas:

在此处输入图片说明

在此处输入图片说明

Here I show you the full code, first the file being discussed, then other important files:

InitCanvas.js

// this class handles the load and the canva for a nrrd
// Using programming based on prototype: https://javascript.info/class
// This class should be improved:
//   - Canvas Width and height

InitCanvas = function (IdDiv, Filename) {


    this.IdDiv = IdDiv;
    this.Filename = Filename
}

InitCanvas.prototype = {

    constructor: InitCanvas,

    init: function () {

        this.container = document.getElementById(this.IdDiv);

        // this should be changed.
        debugger;
        this.container.innerHeight = 600;
        this.container.innerWidth = 800;

        //These statenments should be changed to improve the image position
        this.camera = new THREE.PerspectiveCamera(60, this.container.innerWidth / this.container.innerHeight, 0.01, 1e10);
        this.camera.position.z = 300;

        let scene = new THREE.Scene();
        scene.add(this.camera);

        // light

        let dirLight = new THREE.DirectionalLight(0xffffff);
        dirLight.position.set(200, 200, 1000).normalize();

        this.camera.add(dirLight);
        this.camera.add(dirLight.target);


        // read file

        let loader = new THREE.NRRDLoader();
        loader.load(this.Filename, function (volume) {

            //z plane
            let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));

            debugger;
            this.container.innerWidth = sliceZ.iLength;
            this.container.innerHeight = sliceZ.jLength;

            sliceZ.mesh.material.color.setRGB(0,1,1);


            console.log('Our slice is: ', sliceZ);

            scene.add(sliceZ.mesh);
        }.bind(this));


        this.scene = scene;

        // renderer

        this.renderer = new THREE.WebGLRenderer({alpha: true});
        this.renderer.setPixelRatio(this.container.devicePixelRatio);
        debugger;
        this.renderer.setSize(this.container.innerWidth, this.container.innerHeight);

        // add canvas in container
        this.container.appendChild(this.renderer.domElement);

    },

    animate: function () {

        this.renderer.render(this.scene, this.camera);
    }

}

logic.js

if (!Detector.webgl) Detector.addGetWebGLMessage();

// global variables for this scripts
let OriginalImg,
    SegmentImg;

var mouse = new THREE.Vector2();
var raycaster = new THREE.Raycaster();
var mousePressed = false;
var clickCount = 0;


init();
animate();


// initilize the page
function init() {
    let filename = "models/nrrd/columna01.nrrd"; // change your nrrd file
    let idDiv = 'original';
    OriginalImg = new InitCanvas(idDiv, filename);
    OriginalImg.init();
    console.log(OriginalImg);

    filename = "models/nrrd/columnasegmentado01.nrrd"; // change your nrrd file
    idDiv = 'segment';
    SegmentImg = new InitCanvas(idDiv, filename);
    SegmentImg.init();
}

let originalCanvas = document.getElementById('original');
originalCanvas.addEventListener('mousedown', onDocumentMouseDown, false);
originalCanvas.addEventListener('mouseup', onDocumentMouseUp, false);


function onDocumentMouseDown(event) {
    mousePressed = true;

    clickCount++;

    mouse.x = ( ( event.clientX - OriginalImg.renderer.domElement.offsetLeft ) / OriginalImg.renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = - ( ( event.clientY - OriginalImg.renderer.domElement.offsetTop ) / OriginalImg.renderer.domElement.clientHeight ) * 2 + 1

    console.log('Mouse x position is: ', mouse.x, 'the click number was: ', clickCount);
    console.log('Mouse Y position is: ', mouse.y);

    raycaster.setFromCamera(mouse.clone(), OriginalImg.camera);
    var objects = raycaster.intersectObjects(OriginalImg.scene.children);

    console.log(objects);
}

function onDocumentMouseUp(event) {
    mousePressed = false
}


function animate() {


    requestAnimationFrame(animate);
    OriginalImg.animate();
    SegmentImg.animate();


}   

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Prototype: three.js without react.js</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link rel="stylesheet" href="css/styles.css">

        <!-- load the libraries and js -->
        <script src="js/libs/three.js"></script>

        <script src="js/Volume.js"></script>
        <script src="js/VolumeSlice.js"></script>
        <script src="js/loaders/NRRDLoader.js"></script>

        <script src="js/Detector.js"></script>
        <script src="js/libs/stats.min.js"></script>
        <script src="js/libs/gunzip.min.js"></script>
        <script src="js/libs/dat.gui.min.js"></script>

        <script src="js/InitCanvas.js"></script>


    </head>

    <body>
        <div id="info">
            <h1>Prototype: three.js without react.js</h1> 
        </div>

        <!-- two canvas -->
        <div class="row">
            <div class="column" id="original">
            </div>

            <div class="column" id="segment">

            </div>
          </div> 

        <script src="js/logic.js"></script>

    </body>
</html>

styles.css

body {
    font-family: Monospace;
    margin: 0px;
    overflow: hidden;
}

#info {
    color: rgb(137, 145, 192);
    position: absolute;
    top: 10px;
    width: 100%;
    text-align: center;
    z-index: 5;
    display:block;
}

.column {
    float: left;
    width: 50%;
}

/* Clear floats after the columns */
.row:after {
    content: "";
    display: table;
    clear: both;
}

canvas {
    width: 200px;
    height: 200px;
    margin: 100px;
    padding: 0px;
    position: static; /* fixed or static */
    top: 100px;
    left: 100px;
}

In addition other external resources being used are, NRRDLoader:

https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/NRRDLoader.js

Volume.js

https://github.com/mrdoob/three.js/blob/dev/examples/js/Volume.js

VolumeSlice.js

https://github.com/mrdoob/three.js/blob/dev/examples/js/VolumeSlice.js

Could you help me please?

This is because the load listener will fire when the loader finishes loading the file, i doesn't matter if the code is put before because you are passing a callback function as a parameter.

This might help you to understand what is going on:

Let says that you have 3 friends that you will give orders.

  • You tell friend No. 1 to go and fetch a ball in the distance, when it finishes it will hand you over the ball and paint a red dot on the floor.
  • You tell friend No. 2 to go and start spining around it's own axis 2 times and paint a blue dot on the floor
  • You tell friend No. 3 to jump 2 times and paint a green dot on the floor.

Before Friend 1 comes back both friends had already finished their tasks and in the end the last dot paint will be red, but you probably were expecting it to be green, since it is the last instruction you gave.

This link will help you to better understand how the Event Loop works, and this will help you to understand closures and callbacks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM