I have been working on a 3D project where we show 3D object in the web browser using Three.js Library.
The problem is:
dom
element or when the browser window itself is small.dom
element is resized) the model become pixelatedFollowing are some screenshots:
Here is the part of code that is setting the the model dimensions (height and width), and this function gets called when the resize event if fired:
console.log("domChanged fired")
instance.domBoundingBox = instance.dom.getBoundingClientRect();
instance.domCenterPos.x = instance.domBoundingBox.width / 2 + instance.domBoundingBox.left;
instance.domCenterPos.y = instance.domBoundingBox.height / 2 + instance.domBoundingBox.top;
var width = instance.dom.clientWidth, height = instance.dom.clientHeight;
instance.domWidthHalf = width / 2, instance.domHeightHalf = height / 2;
// TODO: fire event to expose it to site developers
// here we should update several values regarding width,height,position
if(instance.cameraReal) {
instance.cameraReal.aspect = instance.dom.clientWidth / instance.dom.clientHeight;
instance.cameraReal.updateProjectionMatrix();
}
if(instance.renderer3D)
instance.renderer3D.setSize(instance.dom.clientWidth, instance.dom.clientHeight);
Can anybody give me a hint? I've been working on that a couple of days already but no clue so far
So the canvas element can be resized like every other element. What you want to do is tell the render and camera to resize the contents of your canvas as well.
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
Finally the problem were solved the actually problem was coming from because the application is using the THREE.EffectComposer
object, in the class constructor a composer object were created like following:
this.composer = new THREE.EffectComposer(this.renderer3D);
So as for the renderer, the composer needed to have the size updated after the event handler function like following:
if(instance.renderer3D)
instance.renderer3D.setSize(instance.dom.clientWidth, instance.dom.clientHeight);
if(instance.composer)
instance.composer.setSize(instance.dom.clientWidth, instance.dom.clientHeight);
And this fixed the issue perfectly :)
I applied Shawn Whinnery's answer to my needs with React JS:
Start listener onMount:
componentDidMount() {
window.addEventListener('resize', this.handleResize, false)
}
Remove listener onUnmount (because we like garbage collection):
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize, false)
}
Install handler function:
handleResize = () => {
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
this.renderer.setSize(window.innerWidth, window.innerHeight)
}
Fat arrow syntax is used to avoid binding this
. The code will not work if you have this: handleResize() { ... }
, but of course, it would work if you added this to your constructor:
this.handleResize = this.handleResize.bind(this)
Final note: confirm that your camera is this.camera
and your renderer is this.renderer
. Besides that, you should be able to paste it all in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With