【问题标题】:Threejs, why render setSize function is being executed before the code which is before it?Threejs,为什么渲染 setSize 函数在它之前的代码之前执行?
【发布时间】:2018-09-01 09:04:24
【问题描述】:

您好,我有一个疑问:

今天我尝试动态更改画布的大小。我想加载平面的大小并将其大小放入画布的大小中,以使画布适应任何平面的大小。

首先调试程序我看到正在创建第一个画布800x600,这是正确的:

其次,我认为它是线性的并转到加载函数以从本地存储中获取模型,但是它转到了 renderer.setSize()

然后对第二个画布执行相同的两个步骤:

然后,在第五步和第六步中,我们将模型加载到画布中:

这里我向您展示完整的代码,首先是正在讨论的文件,然后是其他重要文件:

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);
    }

}

逻辑.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;
}

除了使用的其他外部资源还有 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

你能帮帮我吗?

【问题讨论】:

  • 我猜是因为 loader.load 是异步的。调用 loader.load 后的代码会继续运行,即使 loader 还没有完成加载并触发了回调。

标签: javascript html css canvas three.js


【解决方案1】:

这是因为当加载器完成加载文件时加载监听器会触发,如果代码放在前面并不重要,因为你将回调函数作为参数传递。

这可能有助于您了解发生了什么:

假设你有 3 个朋友要下订单。

  • 你告诉一号朋友去远处捡球,当它 完成后,它将把球交给你,并在地板上画一个红点。
  • 你告诉朋友 2 号去开始绕它自己的轴 2 旋转 次并在地板上画一个蓝点
  • 你告诉3号朋友跳2次,在地板上画一个绿点。

在朋友 1 回来之前,两个朋友都已经完成了他们的任务,最后最后一个点画将是红色的,但你可能希望它是绿色的,因为这是你给出的最后一条指令。

This link 将帮助您更好地了解事件循环的工作原理,this will help you to understand closures and callbacks.

【讨论】:

    猜你喜欢
    • 2016-11-18
    • 2017-06-30
    • 2020-11-14
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 2012-06-20
    • 2021-10-16
    • 2020-10-05
    相关资源
    最近更新 更多