J'ai travaillé sur un projet 3D où nous montrons des objets 3D dans le navigateur Web en utilisant la bibliothèque Three.js.
Le problème est:
Voici quelques captures d'écran:
Voici la partie du code qui définit les dimensions du modèle (hauteur et largeur), et cette fonction est appelée lorsque l'événement resize est déclenché:
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);
Quelqu'un peut-il me donner un indice? J'y travaille déjà depuis quelques jours mais aucun indice jusqu'à présent
Enfin, le problème a été résolu, le problème provenait en fait, car l'application utilise le THREE.EffectComposer
objet, dans le constructeur de classe un objet composer ont été créés comme suit:
this.composer = new THREE.EffectComposer(this.renderer3D);
Donc, comme pour le rendu, le composer devait avoir la taille mise à jour après la fonction du gestionnaire d'événements comme suit:
if(instance.renderer3D)
instance.renderer3D.setSize(instance.dom.clientWidth, instance.dom.clientHeight);
if(instance.composer)
instance.composer.setSize(instance.dom.clientWidth, instance.dom.clientHeight);
Et cela a parfaitement résolu le problème :)
Ainsi, l'élément canvas peut être redimensionné comme tous les autres éléments. Ce que vous voulez faire, c'est de dire au rendu et à la caméra de redimensionner également le contenu de votre toile.
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
J'ai appliqué la réponse de Shawn Whinnery à mes besoins avec React JS:
Démarrer l'écouteur surMount:
componentDidMount() {
window.addEventListener('resize', this.handleResize, false)
}
Supprimer l'écouteur onUnmount (parce que nous aimons la collecte des ordures):
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize, false)
}
Installer la fonction de gestionnaire:
handleResize = () => {
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
this.renderer.setSize(window.innerWidth, window.innerHeight)
}
La syntaxe des flèches grasses est utilisée pour éviter de lier this
. Le code ne fonctionnera pas si vous avez ceci: handleResize() { ... }
, mais bien sûr, cela fonctionnerait si vous ajoutiez ceci à votre constructeur:
this.handleResize = this.handleResize.bind(this)
Note finale: confirmez que votre caméra est this.camera
Et que votre rendu est this.renderer
. En plus de cela, vous devriez pouvoir tout coller.
Pour ceux qui recherchent sur Google, si vous voulez commencer rapidement avec un utilitaire d'aide qui fait le redimensionnement pour vous, consultez ce github: https://github.com/jeromeetienne/threex.windowresize
La seule chose que vous avez à faire est de l'installer via bower
et de l'initialiser:
new THREEx.WindowResize(renderer, camera)