作者:桑榆
QQ:934440653
有問題,評論留言,或qq聯繫
案例效果
鼠標拾取
主要代碼
1.創建矩形
(1)6-8行限制隨機產生的矩形的長、寬、縱深不超過20;
(2)14-16行限制隨機產生的矩形在一個長、寬、縱深爲600的包圍盒內,以(0,0,0)爲分割點,所以減300;座標在x,y,z(-300,300)之間。
(3)20-22行讓創建的矩形有一定旋轉度
var BoundingBoxLength = 600; //規定隨機創建的矩形,在半徑爲300的包圍盒內
function initObject(){ //創建2000個矩形
for(var i = 0; i < 2000 ; i++){
//隨機產生不同大小的矩形
var cubeX = Math.random() * 20;
var cubeY = Math.random() * 20;
var cubeZ = Math.random() * 20;
var geometry = new THREE.CubeGeometry(cubeX,cubeY,cubeZ);
var material = new THREE.MeshLambertMaterial({color:Math.random() * 0xffffff}); //隨機產生一個顏色
var cube = new THREE.Mesh(geometry,material);
//隨機產生矩形的位置
var cubePositionX = Math.random() * 600 - 300;
var cubePositionY = Math.random() * 600 - 300;
var cubePositionZ = Math.random() * 600 - 300;
cube.position.set(cubePositionX,cubePositionY,cubePositionZ);
//隨機產生矩形的旋轉方式
cube.rotation.x = Math.random() * 2 * Math.PI;
cube.rotation.y = Math.random() * 2 * Math.PI;
cube.rotation.z = Math.random() * 2 * Math.PI;
scene.add(cube);
}
}
相機旋轉
(1)1行設置相機的半徑,以這個半徑旋轉
(2)2行爲相機的初始經緯座標(0,0);
(3)6-7經緯座標每次渲染遞增0.01°(遞增太大,旋轉太快);
(4)8-9行設置轉換後的相機座標
(5)10行始終相機看向場景的中心
(6)更新相機,相機的參數改變後一定更新,切記!!!!!
var cameraRadius = 400;//相機的旋轉半徑
var cameraLongitude = 0 ,cameraLatitude = 0; //相機的經緯度座標
function animate(){
requestAnimationFrame(animate);
cameraLongitude += 0.1;
cameraLatitude += 0.1;
var cameraPosition = getPosition(cameraLongitude,cameraLatitude,cameraRadius);
camera.position.set(cameraPosition.x ,cameraPosition.y,cameraPosition.z);
camera.lookAt(scene.position);
camera.updateProjectionMatrix();
renderer.render(scene,camera);
}
經緯度座標轉換爲三維座標
將標記地點經緯度座標與三維x,y,z座標轉換方法。
function getPosition (longitude, latitude, radius) {
// 經緯度轉換函數,longitude表示經度,latitude表示維度,radius表示球體半徑
// 將經度,緯度轉換爲rad座標
var lg = THREE.Math.degToRad(longitude);
var lt = THREE.Math.degToRad(latitude);
var temp = radius * Math.cos(lt);
// 獲取x,y,z座標
var x = temp * Math.sin(lg);
var y = radius * Math.sin(lt);
var z = temp * Math.cos(lg);
return {
x: x,
y: y,
z: z
}
}
鼠標拾取
//鼠標拾取
function mouseRaycaster(){
dom.addEventListener('click',clickEvent,false);
function clickEvent(event){
event.preventDefault();
// 聲明 raycaster 和 mouse 變量
var raycaster = new THREE.Raycaster(); // 光線投射用於進行鼠標拾取(在三維空間中計算出鼠標移過了什麼物體)。
var mouse = new THREE.Vector2(); //存放鼠標點擊座標
// 通過鼠標點擊位置,計算出 raycaster 所需點的位置,以屏幕爲中心點,範圍 -1 到 1
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
// 通過攝像機和鼠標位置更新射線 由相機照向鼠標(交點即爲鼠標點擊的點)
raycaster.setFromCamera( mouse, camera,0,1000);
var INTERSCTSColor = [];
// 計算物體和射線的焦點 在場景中找到相機和鼠標相交的對象放在intersects這個數組中 射線穿過的物體可能有多個
var intersects = raycaster.intersectObjects( scene.children );
for ( var i = 0; i < intersects.length; i++ ) {
INTERSCTSColor.push(intersects[ i ].object.material.color);
intersects[ i ].object.material.color.set( 0xff0000 ); //將射線穿過的物體全部改變顏色
}
}
}
完整代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>鼠標拾取</title>
<style>
*{
padding: 0;
margin: 0;
}
html,body{
height: 100%;
width: 100%;
}
#webGL{
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<script src="../buildJs/build/three105.js"></script>
<div id="webGL"></div>
<script>
var renderer,dom,domWidth,domHeight;
function initRender(){
dom = document.getElementById('webGL');
domWidth = dom.clientWidth;
domHeight = dom.clientHeight;
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(domWidth,domHeight);
renderer.setPixelRatio(window.devicePixelRatio);
dom.appendChild(renderer.domElement);
renderer.setClearColor(0xFFFFFF,1.0);
}
var scene;
function initScene(){
scene = new THREE.Scene();
scene.background = new THREE.Color(0xcfcfcf);
}
var ambientLight,directionalLight;
function initLight(){
ambientLight = new THREE.AmbientLight(0x404040,1.0);
scene.add(ambientLight);
directionalLight = new THREE.DirectionalLight(0xffffff,0.8);
directionalLight.lookAt(new THREE.Vector3(0,0,0));
directionalLight.position.set(-600,600,600);
scene.add(directionalLight);
}
var camera;
function initCamera(){
camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,1,1000);
camera.position.set(0,300,500);
camera.lookAt(scene.position);
scene.add(camera);
}
var cameraRadius = 400;//相機的旋轉半徑
var cameraLongitude = 0 ,cameraLatitude = 0; //相機的經緯度座標
function animate(){
requestAnimationFrame(animate);
cameraLongitude += 0.1;
cameraLatitude += 0.1;
var cameraPosition = getPosition(cameraLongitude,cameraLatitude,cameraRadius);
camera.position.set(cameraPosition.x ,cameraPosition.y,cameraPosition.z);
camera.lookAt(scene.position);
camera.updateProjectionMatrix();
mouseRaycaster();
renderer.render(scene,camera);
}
function listenWindow(){ //監聽屏幕寬高變化
window.addEventListener('resize',onWindowResize,false);
function onWindowResize(){
domWidth = window.innerWidth;
domHeight = window.innerHeight;
camera.aspect = domWidth / domHeight;
camera.updateProjectionMatrix();
renderer.setSize(domWidth, domHeight); //設置渲染器大小,即canvas畫布的大小
}
}
var BoundingBoxLength = 600; //規定隨機創建的矩形,在半徑爲300的包圍盒內
function initObject(){ //創建2000個矩形
for(var i = 0; i < 2000 ; i++){
//隨機產生不同大小的矩形
var cubeX = Math.random() * 20;
var cubeY = Math.random() * 20;
var cubeZ = Math.random() * 20;
var geometry = new THREE.CubeGeometry(cubeX,cubeY,cubeZ);
var material = new THREE.MeshLambertMaterial({color:Math.random() * 0xffffff}); //隨機產生一個顏色
var cube = new THREE.Mesh(geometry,material);
//隨機產生矩形的位置
var cubePositionX = Math.random() * 600 - 300;
var cubePositionY = Math.random() * 600 - 300;
var cubePositionZ = Math.random() * 600 - 300;
cube.position.set(cubePositionX,cubePositionY,cubePositionZ);
//隨機產生矩形的旋轉方式
cube.rotation.x = Math.random() * Math.PI;
cube.rotation.y = Math.random() * Math.PI;
cube.rotation.z = Math.random() * Math.PI;
scene.add(cube);
}
}
//將標記地點經緯度座標與三維x,y,z座標轉換方法。
function getPosition (longitude, latitude, radius) {
// 經緯度轉換函數,longitude表示經度,latitude表示維度,radius表示球體半徑
// 將經度,緯度轉換爲rad座標
var lg = THREE.Math.degToRad(longitude);
var lt = THREE.Math.degToRad(latitude);
var temp = radius * Math.cos(lt);
// 獲取x,y,z座標
var x = temp * Math.sin(lg);
var y = radius * Math.sin(lt);
var z = temp * Math.cos(lg);
return {
x: x,
y: y,
z: z
}
}
//鼠標拾取
function mouseRaycaster(){
dom.addEventListener('click',clickEvent,false);
function clickEvent(event){
event.preventDefault();
// 聲明 raycaster 和 mouse 變量
var raycaster = new THREE.Raycaster(); // 光線投射用於進行鼠標拾取(在三維空間中計算出鼠標移過了什麼物體)。
var mouse = new THREE.Vector2(); //存放鼠標點擊座標
// 通過鼠標點擊位置,計算出 raycaster 所需點的位置,以屏幕爲中心點,範圍 -1 到 1
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
// 通過攝像機和鼠標位置更新射線 由相機照向鼠標(交點即爲鼠標點擊的點)
raycaster.setFromCamera( mouse, camera,0,1000);
var INTERSCTSColor = [];
// 計算物體和射線的焦點 在場景中找到相機和鼠標相交的對象放在intersects這個數組中 射線穿過的物體可能有多個
var intersects = raycaster.intersectObjects( scene.children );
for ( var i = 0; i < intersects.length; i++ ) {
INTERSCTSColor.push(intersects[ i ].object.material.color);
intersects[ i ].object.material.color.set( 0xff0000 ); //將射線穿過的物體全部改變顏色
}
}
}
initRender();
initScene();
initCamera();
initLight();
listenWindow();
initObject();
animate();
</script>
</body>
</html>