threejs创建多个立方体,并支持鼠标点击选中
2017-12-20 15:58
2306 查看
threejs创建多个立方体,并支持鼠标点击选中
threejs创建多个立方体并支持鼠标点击选中引入所需的插件
创建渲染器Renderer
创建相机Camera
创建视图控制器OrbitControls
创建场景Scene
创建辅助坐标轴AxisHelper
添加地面网格GirdHelper
添加空间正方体BoxGeometry Mesh
添加光投射器Raycaster
执行渲染
效果图
完整代码
引入所需的插件
<script src="https://cdn.bootcss.com/three.js/r83/three.min.js"></script> <!--该插件主要用于完成鼠标拖动改变相机视角--> <script src="libs/OrbitControls.js"></script>
创建渲染器Renderer
把三维的场景渲染到显示屏上
renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth,window.innerHeight); //container:浏览器画图区域对应的dom元素 container.appendChild(renderer.domElement);
创建相机Camera
相当于人的眼睛,看到物体的大小远近与相机的位置和设置有关
/* 创建相机【远景相机,与人眼观察类似,近大远小】 param1:视角【视角越大 物体渲染到屏幕时则看着越小,反之越大】 param2:相机拍摄面的长宽比 param3:近裁剪面,相机与物体的距离小于该值后将不在屏幕上显示 param4:远裁剪面,相机与物体的距离大于该值后将不在屏幕上显示 */ camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,2000); camera.position.set(10,10,800);
创建视图控制器OrbitControls
通过鼠标拖动和滑轮移动自动改变相机的位置,调整视角,重新渲染页面
controls = new THREE.OrbitControls( camera, renderer.domElement ); controls.addEventListener( 'change', render );
创建场景Scene
用于添加空间范围内需要显示的物体
scene = new THREE.Scene(); scene.background = new THREE.Color(0xf0f0f0);
创建辅助坐标轴AxisHelper
通过 X(屏幕右边) 、 Y(屏幕上边) 、 Z(屏幕由内到外) 三条轴线帮助你了解物体空间位置坐标
var axes = new THREE.AxisHelper(800);//参数设置了三条轴线的长度 scene.add(axes);
添加地面网格GirdHelper
在指定位置条件指定长度、数量的网格图形
/** * size 网格总边长 * step 网格个数 * colorCenterLine 网格中心线颜色 * colorGrid 网格其他线颜色 */ var gridHelper = new THREE.GridHelper( 300, 10, 'red', 'gray' ); gridHelper.position.y = -100; gridHelper.position.x = 0; scene.add( gridHelper );
添加空间正方体BoxGeometry Mesh
var geometry = new THREE.BoxGeometry(20,20,20);//盒子模型 for ( var i = 0; i < 100; i ++ ) { var material = new THREE.MeshBasicMaterial({color:"gray"});//材料 var mesh = new THREE.Mesh( geometry, material ); mesh.position.x = ( Math.random() - 0.5 ) * 1000; mesh.position.y = ( Math.random() - 0.5 ) * 1000; mesh.position.z = ( Math.random() - 0.5 ) * 1000; scene.add( mesh ); }
添加光投射器Raycaster
通过光投射器结合鼠标位置坐标,判断鼠标是否经过物体
raycaster = new THREE.Raycaster();//光线投射器 mouse = new THREE.Vector2();//二维向量 document.addEventListener('mousemove', function(){ event.preventDefault(); mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 4000 + 1; }, false); var projectiveObj;//定义上次投射到的对象 /** * 根据光投射器判断鼠标所在向量方向是否穿过物体 * @param {*} raycaster 光投射器 * @param {*} scene 场景 * @param {*} camera 相机 * @param {*} mouse 鼠标位置对应的二维向量 */ function renderRaycasterObj(raycaster,scene,camera,mouse) { raycaster.setFromCamera(mouse, camera); var intersects = raycaster.intersectObjects(scene.children); if (intersects.length > 0) { var currentProjectiveObjT = intersects[0].object; if (projectiveObj != currentProjectiveObjT) { if((currentProjectiveObjT instanceof THREE.AxisHelper) || (currentProjectiveObjT instanceof THREE.GridHelper)){ //穿过的是坐标轴线和网格线 return; } projectiveObj = intersects[0].object; } } else { projectiveObj = null; } }
执行渲染
function render() { requestAnimationFrame(render); renderRaycasterObj(raycaster,scene,camera,mouse);//渲染光投射器投射到的对象 renderer.render( scene, camera); }
效果图
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<title>创建threejs场景-旋转的立方体</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body{margin: 0}
canvas{width: 100% ; height: 100%}
div#drawArea{
position: fixed;
}
</style>
</head>
<body>
<div id="drawArea"></div>
<script src="https://cdn.bootcss.com/three.js/r83/three.min.js"></script>
<script src="libs/OrbitControls.js"></script>
<script>
var scene,camera,renderer,light,controls;//场景,相机,渲染器,光源
var raycaster,mouse;//光投射器,鼠标位置对应的二维向量
init();
function init() {
var container = document.getElementById("drawArea");
/*
1、初始化渲染器
*/
renderer = new THREE.WebGLRenderer();
// renderer.setClearColor('white');//设置渲染出来的背景色
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth,window.innerHeight);
container.appendChild(renderer.domElement);
/*
2、初始化相机
创建相机【远景相机,与人眼观察类似,近大远小】
param1:视角【视角越大 物体渲染到屏幕时则看着越小,反之越大】
param2:相机拍摄面的长宽比
param3:近裁剪面
param4:远裁剪面
*/
camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,2000);
camera.position.set(10,10,800);
/*
添加视图控制器
*/
controls = new THREE.OrbitControls( camera, renderer.domElement ); controls.addEventListener( 'change', render );
/*
3、初始化场景
*/
scene = new THREE.Scene(); scene.background = new THREE.Color(0xf0f0f0);
//initLight();
//scene.add( new THREE.PointLightHelper( light, 15 ) );
/*
4、添加辅助坐标轴
*/
var axes = new THREE.AxisHelper(800);
scene.add(axes);
/*
5、添加地面网格
*/
/** * size 网格总边长 * step 网格个数 * colorCenterLine 网格中心线颜色 * colorGrid 网格其他线颜色 */ var gridHelper = new THREE.GridHelper( 300, 10, 'red', 'gray' ); gridHelper.position.y = -100; gridHelper.position.x = 0; scene.add( gridHelper );
/*
6、添加正方体
*/
var geometry = new THREE.BoxGeometry(20,20,20);//盒子模型
for ( var i = 0; i < 100; i ++ ) {
var material = new THREE.MeshBasicMaterial({color:"gray"});//材料
var mesh = new THREE.Mesh( geometry, material );
mesh.position.x = ( Math.random() - 0.5 ) * 1000;
mesh.position.y = ( Math.random() - 0.5 ) * 1000;
mesh.position.z = ( Math.random() - 0.5 ) * 1000;
scene.add( mesh );
}
/*
7、添加光投射器 及 鼠标二维向量 用于捕获鼠标移入物体
下次渲染时,通过mouse对于的二维向量判断是否经过指定物体
*/
raycaster = new THREE.Raycaster();//光线投射器
mouse = new THREE.Vector2();//二维向量
document.addEventListener('mousemove', function(){
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}, false);
/**
* 浏览器窗口大小调整
*/
window.addEventListener( 'resize', function(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}, false );
/**
* 添加鼠标点击事件,捕获点击时当前选中的物体
*/
window.addEventListener( 'click', function(){
if(projectiveObj){
console.log(projectiveObj);
if(projectiveObj.hasChecked){
projectiveObj.hasChecked = false;
projectiveObj.material.color.set("gray");
}else{
projectiveObj.hasChecked = true;
projectiveObj.material.color.set("#dd830d");
}
}
}, false );
render();
}
function render() { requestAnimationFrame(render); renderRaycasterObj(raycaster,scene,camera,mouse);//渲染光投射器投射到的对象 renderer.render( scene, camera); }
var projectiveObj;//定义上次投射到的对象
/**
* 根据光投射器判断鼠标所在向量方向是否穿过物体,穿过则改变物体材质
* @param {*} raycaster 光投射器
* @param {*} scene 场景
* @param {*} camera 相机
* @param {*} mouse 鼠标位置对应的二维向量
*/
function renderRaycasterObj(raycaster,scene,camera,mouse) {
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
var currentProjectiveObjT = intersects[0].object;
if (projectiveObj != currentProjectiveObjT) {
if((currentProjectiveObjT instanceof THREE.AxisHelper) || (currentProjectiveObjT instanceof THREE.GridHelper)){
//穿过的是坐标轴线和网格线
return;
}
projectiveObj.material.color.setHex(projectiveObj.currentHex);
projectiveObj = intersects[0].
8ada
object;
}
} else {
projectiveObj = null;
}
}
</script>
</body>
</html>
相关文章推荐
- 场景中创建N(两个以上)个物体,鼠标可以选中任何物体,当鼠标选中为非地面时,选中的物体变为红色,之前选中的物体恢复为之前的颜色,鼠标点击到地面时,让之前选中的那个物体移动的当前点击的位置
- 禁止鼠标多次点击选中div中的文字
- Jquery实现对a标签改变选中的背景色 支持多选 再次点击背景色消失
- C#中DataGridView控件鼠标点击选中行的问题
- 鼠标点击不选中文字
- 鼠标移到隔行变色的表格上,有背景变化,并且点击的时候选中复选框和背景色
- [PyQt] 自定义QSlider支持鼠标点击和滚轮事件
- 禁止鼠标多次点击选中div中的文字
- 鼠标点击文字选中复选框
- 用wx.CheckBox创建复选框控件并响应鼠标点击事件
- 禁止鼠标多次点击选中div中的文字
- Unity3D 2D游戏鼠标点击选中对象如何实现
- C# checkedListBox控件 鼠标点击一下选中
- 同级元素,鼠标经过高亮,鼠标离开还原(除选中已高亮元素时),点击确定高亮
- 用javascript css实现GridView行背景色交替、鼠标划过行变色,点击行变色选中
- 浏览器环境下用javascript创建鼠标点击事件,事件模拟
- ASP.NET2005 gridview中点击某行的任意位置选中某行 交替效果 变换鼠标手势
- QTreeView控件判断鼠标点击是否选中叶子节点
- html代码一小段-------鼠标放上选中,鼠标点击,文字消失,鼠标离开文字又有了
- 禁止鼠标多次点击选中div中的文字