Greetings, I have a question.
In my attempt to adjust the innerWidth and innerHeight of the div container which houses a canvas element, I am using the code snippet below. The crucial part is the loader.load function that gets executed upon completion of loading the plane on the page.
// This class manages the loading process and canvas for an nrrd file
// Utilizing prototype-based programming: https://javascript.info/class
InitCanvas = function (IdDiv, Filename) {
this.IdDiv = IdDiv;
this.Filename = Filename
}
InitCanvas.prototype = {
constructor: InitCanvas,
init: function () {
this.container = document.getElementById(this.IdDiv);
debugger;
this.container.innerHeight = 600;
this.container.innerWidth = 800;
// These lines should be modified to enhance 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);
this.scene = scene;
// Renderer
this.renderer = new THREE.WebGLRenderer({alpha: true});
this.renderer.setPixelRatio(this.container.devicePixelRatio);
debugger;
this.container.appendChild(this.renderer.domElement);
}.bind(this));
},
animate: function () {
this.renderer.render(this.scene, this.camera);
}
}
As you can observe from the code, I'm binding 'this' within the loader.load asynchronous call to access the 'container' property in the InitCanvas class.
After the completion of loading the plane, we retrieve the width and height with these lines:
this.container.innerWidth = sliceZ.iLength;
this.container.innerHeight = sliceZ.jLength;
I noticed through the web debugger that the width and height of the loaded plane are indeed reflected in the container inside the div:
https://i.sstatic.net/T27Yb.png
The values shown indicate that this.container.innerWidth has been updated to 3128 and this.container.innerHeight to 1760.
However, after rendering the plane, the container div displays dimensions of 300x150 as depicted here:
https://i.sstatic.net/UKu6u.png
How is this discrepancy possible?
Moreover, why does our web console throw this error:
Uncaught TypeError: Cannot read property 'render' of undefined
at InitCanvas.animate (InitCanvas.js:79)
at animate (logic.js:63)
I presume this error occurs because we don't have access to this.renderer within the loader.load function due to the bind(this) technique used. However, in the animate() function, the scope of the InitCanvas class is lost.
What could be done to rectify this issue?
Thank you for your assistance!
Here is additional relevant code:
logic.js
// Code logic goes here
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 necessary scripts -->
</head>
<body>
<div id="info">
<h1>Prototype: three.js without react.js</h1>
</div>
<!-- Two canvas elements -->
<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;
}