Three.js提供一个射线类Raycasting来拾取场景里面的物体。更方便的使用鼠标来操作3D场景。
function Module(wrapId) {
var _this = this;
this.scene = null;
this.camera = null;
this.renderer = null;
this.geometry = null;
this.material = null;
this.cube = null;
this.gridHelper = null;
this.light = null;
this.controls = null;
this.transControl = null;
this.objsarr = [];
this.container = document.getElementById(wrapId); //容器
this.container.onclick = function() {
_this.getSize(event, _this)
}
}
Module.prototype = {
// 场景
initScene: function() {
this.scene = new THREE.Scene();
},
// 相机
initCamera: function() {
// 透视相机
this.camera = new THREE.PerspectiveCamera( 45, this.container.offsetWidth / this.container.offsetHeight, 1, 10000 );
// 设置相机的坐标
// this.camera.position.y = 5;
// this.camera.position.z = 5;
this.camera.position.set(0, 5, 5)
},
// 渲染器
initRenderer: function() {
this.renderer = new THREE.WebGLRenderer({antialias : true});
this.renderer.setSize( this.container.offsetWidth, this.container.offsetHeight );
this.renderer.setClearColor(0xffffff, 1); //(原色,透明度)
this.container.appendChild( this.renderer.domElement );
},
// 网格
initGrid: function() {
this.gridHelper = new THREE.GridHelper(2, 50, 0xff00ff, 0x808080);
this.scene.add(this.gridHelper);
},
// 光线
initLight: function() {
this.light = new THREE.AmbientLight(0xffffff);
this.light.position.set(0, 0, 1);
this.scene.add(this.light);
},
// 控制器
initCtr: function() {
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.controls.dampingFactor = 0.25;
//移动 缩放 旋转控制器
this.transControl = new THREE.TransformControls( this.camera, this.renderer.domElement );
this.transControl.size = 0.5; //尺寸
this.scene.add(this.transControl);
},
// 射线
radial: function() {
this.raycaster = new THREE.Raycaster();
this.mouse = new THREE.Vector2();
},
getSize: function(event, module) {
event.preventDefault();
var clientX = event.clientX - module.container.offsetLeft
var clientY = event.clientY - module.container.offsetTop + document.body.scrollTop
// module.mouse.x = (clientX / module.container.offsetWidth) * 2 - 1;
module.mouse.x = (clientX / module.renderer.domElement.clientWidth) * 2 - 1;
module.mouse.y = -(clientY / module.renderer.domElement.clientHeight) * 2 + 1;
module.raycaster.setFromCamera(module.mouse, module.camera);
var intersects = module.raycaster.intersectObjects(module.objsarr);
if(intersects.length > 0) {
var INTERSECTED = intersects[0].object
module.transControl.attach(INTERSECTED)
} else {
module.transControl.detach(INTERSECTED)
}
},
// 物体
initCube: function() {
for(var i = 0; i < 10; i++) {
this.geometry = new THREE.BoxGeometry( 0.5, 0.5, 0.5, 2, 2, 2 ); //(width, height, dept, widthSegments, heightSegments, depthSegments)
var crateTexture = new THREE.TextureLoader().load("../../images/demo/jingtian2.jpg");
this.material = new THREE.MeshBasicMaterial({ //基本材质
map: crateTexture,
wireframe : false //wireframe线模式渲染
});
// this.material = new THREE.MeshNormalMaterial({ //此材质根据物体表面法向量计算颜色
// wireframe: false //wireframe线模式渲染
// });
this.cube = new THREE.Mesh( this.geometry, this.material );
this.cube.position.x = Math.random() *4 - 2
this.cube.position.y = Math.random() *1.5
this.cube.position.z = Math.random() *4 - 2
this.scene.add( this.cube );
this.objsarr.push(this.cube)
}
},
start: function() {
this.initScene();
this.initCamera();
this.initRenderer();
this.initCube();
// initModel()
this.initLight();
this.initCtr();
this.initGrid();
this.radial();
}
}
var models = new Module("model")
models.start()
// 动画
function animation () {
requestAnimationFrame( animation );
models.renderer.render(models.scene, models.camera);
};
animation ()
评论区