-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
linyisonger
committed
Sep 12, 2024
1 parent
911db72
commit 9502361
Showing
3 changed files
with
148 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<link rel="stylesheet" href="./assets/global.css"> | ||
</head> | ||
|
||
<body> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"three": "https://unpkg.com/three/build/three.module.js", | ||
"three/addons/": "https://unpkg.com/three/examples/jsm/" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
import * as THREE from 'three'; | ||
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | ||
|
||
const scene = new THREE.Scene(); | ||
scene.background = new THREE.Color(0x88ccee); | ||
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | ||
camera.position.set(-5.5, 5, -5.5); | ||
|
||
const renderer = new THREE.WebGLRenderer(); | ||
renderer.shadowMap.enabled = true; | ||
renderer.setSize(window.innerWidth, window.innerHeight); | ||
|
||
document.body.appendChild(renderer.domElement); | ||
|
||
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.3); | ||
directionalLight.position.set(4, 4, -4) | ||
directionalLight.castShadow = true; | ||
scene.add(directionalLight); | ||
|
||
// 创建环境光源 | ||
const ambientLight = new THREE.AmbientLight(0x404040); // 灰色的环境光 | ||
scene.add(ambientLight); | ||
|
||
let cubeMaterial = null | ||
|
||
let loader = new THREE.TextureLoader(); | ||
loader.load("./assets/cubeTexture.jpg", texture => { | ||
cubeMaterial = new THREE.MeshLambertMaterial({ | ||
map: texture //材质的贴图为加载的图片 | ||
}); | ||
}) | ||
|
||
// 新建底座 | ||
// 4 x 4 | ||
const MaximumSize = 4; | ||
|
||
for (let x = 0; x < MaximumSize; x++) { | ||
for (let z = 0; z < MaximumSize; z++) { | ||
console.log(x, z); | ||
const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x999999, side: THREE.DoubleSide }); | ||
const plane = new THREE.Mesh(new THREE.BoxGeometry(1, .01, 1), planeMaterial); | ||
plane.position.x = x - MaximumSize / 2; | ||
plane.position.z = z - MaximumSize / 2; | ||
plane.name = `plane(${x},${z})` | ||
plane.receiveShadow = true; | ||
|
||
scene.add(plane); | ||
} | ||
} | ||
|
||
// 控制器 | ||
let controls = new OrbitControls(camera, renderer.domElement); | ||
controls.screenSpacePanning = true; | ||
controls.minDistance = 5; | ||
controls.maxDistance = 40; | ||
controls.target.set(0, 0, 0); | ||
controls.update(); | ||
|
||
//获取鼠标坐标 处理点击某个模型的事件 | ||
let mouse = new THREE.Vector2(); | ||
let raycaster = new THREE.Raycaster(); | ||
|
||
function onmodelclick(event) { | ||
mouse.x = (event.clientX / window.innerWidth) * 2 - 1; | ||
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; | ||
|
||
raycaster.setFromCamera(mouse, camera); | ||
const intersects = raycaster.intersectObjects(scene.children); | ||
console.log(intersects); | ||
const lastObject = intersects.find(o => | ||
o.object.name.startsWith('plane') || | ||
o.object.name.startsWith('cube') | ||
) // 点击的物体是平面或者是立方体 | ||
|
||
if (lastObject) { // 存在 | ||
let lastObjectNormal = lastObject.normal // 点击的方向 | ||
let lastObjectPosition = lastObject.object.position // 物体的位置 | ||
console.log(lastObjectNormal, lastObjectPosition); | ||
let x = lastObjectNormal.x + lastObjectPosition.x | ||
let y = lastObjectNormal.y + lastObjectPosition.y | ||
let z = lastObjectNormal.z + lastObjectPosition.z | ||
let isPlane = lastObject.object.name.startsWith('plane'); | ||
let cube = createCube(); | ||
cube.position.x = x | ||
cube.position.y = y - (isPlane ? .5 : 0) | ||
cube.position.z = z | ||
cube.name = `cube(${x, y, z})` | ||
scene.add(cube) | ||
} | ||
|
||
} | ||
window.addEventListener("click", onmodelclick); | ||
|
||
// 是否在范围内 | ||
function isRange(x, y, z) { | ||
let maxX = MaximumSize / 2; | ||
let minX = -MaximumSize / 2; | ||
let maxZ = MaximumSize / 2; | ||
let minZ = -MaximumSize / 2; | ||
let maxY = MaximumSize; | ||
let minY = 0; | ||
} | ||
// 创建方块 | ||
function createCube() { | ||
const geometry = new THREE.BoxGeometry(1, 1, 1); | ||
const material = cubeMaterial || new THREE.MeshStandardMaterial({ color: 0x00ff00 }); | ||
const cube = new THREE.Mesh(geometry, material); | ||
cube.castShadow = true; | ||
return cube | ||
} | ||
|
||
|
||
function animate() { | ||
renderer.render(scene, camera); | ||
requestAnimationFrame(animate); | ||
|
||
// cube.rotation.x += 0.01; | ||
// cube.rotation.y += 0.01; | ||
|
||
} | ||
animate(); | ||
</script> | ||
</body> | ||
|
||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,4 +72,5 @@ | |
072.Grid 布局练习.html | ||
073.Svg 半圆.html | ||
074.echart 常见饼图.html | ||
075.Three.js 观察物体.html | ||
index.html |