three.js实现拖拽生成模型场景 |
您所在的位置:网站首页 › 高德地图3d模型导出在哪里 › three.js实现拖拽生成模型场景 |
THREE.js 可以实现很多web 3D的效果,最近想实现一个拖拽生成场景的功能,主要用到拖拽API,draggable 的几个事件来实现,拖拽模型时记录模型属性,释放到画布时生成当前屏幕坐标对应的焦点上,最后生成模型。 Drag and Drop 3D Models body { margin: 0; padding: 0; overflow: hidden; } #tools { position: absolute; left: 0; top: 0; bottom: 0; width: 100px; background-color: #f2f2f2; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 1; } #scene { position: absolute; right: 0; top: 0; bottom: 0; left: 100px; background-color: #ddd; } #resetBtn { position: absolute; right: 20px; bottom: 20px; z-index: 2; padding: 8px; border: none; border-radius: 4px; background-color: #007bff; color: #fff; font-size: 16px; cursor: pointer; } img { width: 50px; height: 50px; cursor: pointer; } // 相机 var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 ); camera.near = 0.1; camera.far = 10000; camera.updateProjectionMatrix(); camera.position.set(0, 200, 500); camera.lookAt(scene.position); // 地面网格 // 地面网格 // 创建地面网格 //var geometry = new THREE.PlaneGeometry(10, 10); //var material = new THREE.MeshBasicMaterial({ color: 0x888888, wireframe: true }); //var ground = new THREE.Mesh(geometry, material); //ground.rotation.x = -Math.PI / 2; //.receiveShadow = true; // 让地面网格接收阴影 //scene.add(ground); var groundSize = 1000; var ground = createGround(groundSize); scene.add(ground); // 创建两个球体,一个在地面上方,另一个在地面下方 var sphereRadius = 50; var sphereTop = createSphere(sphereRadius); sphereTop.position.set(0, sphereRadius, 0); scene.add(sphereTop); var sphereBottom = createSphere(sphereRadius); sphereBottom.position.set(0, -sphereRadius, 0); scene.add(sphereBottom); // 创建环境光 var ambientLight = new THREE.AmbientLight(0xffffff, 0.4); scene.add(ambientLight); // 创建点光源 var pointLight = new THREE.PointLight(0xffffff, 1, 1000); pointLight.position.set(-100, 200, 100); scene.add(pointLight); function createGround(size) { var geometry = new THREE.PlaneGeometry(size, size, 10, 10); var material = new THREE.MeshLambertMaterial({ color: 0x888888 , wireframe: true}); var mesh = new THREE.Mesh(geometry, material); mesh.rotation.x = -Math.PI / 2; mesh.receiveShadow = true; return mesh; } function createSphere(radius) { var geometry = new THREE.SphereGeometry(radius, 32, 32); var material = new THREE.MeshPhongMaterial({ color: 0xff0000 }); var mesh = new THREE.Mesh(geometry, material); return mesh; } // 模型列表 var models = { box: new THREE.BoxGeometry(50, 50, 50), cylinder: new THREE.CylinderGeometry(25, 25, 50, 20), }; // 记录被选中的模型和交叉点 var selectedModel = null; var intersects = null; // 工具栏按钮被拖动时,将其ID存储在dataTransfer中方便后续使用 document.querySelectorAll("#tools img").forEach((img) => { img.addEventListener("dragstart", function (event) { selectedModel = models[this.id].clone(); var currentTarget = event.currentTarget; event.dataTransfer.setData("text", currentTarget.id); }); }); // 场景可拖放,将模型放置在与地面网格相交的位置 document .getElementById("scene") .addEventListener("dragover", function (event) { event.preventDefault(); }); document .getElementById("scene") .addEventListener("drop", function (event) { event.preventDefault(); var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); mouse.x = (event.offsetX / renderer.domElement.clientWidth) * 2 - 1; mouse.y = -(event.offsetY / renderer.domElement.clientHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); console.log(event.offsetX,event.offsetY); intersects = raycaster.intersectObject(ground); if (selectedModel && intersects) { var mesh = new THREE.Mesh( selectedModel, new THREE.MeshPhongMaterial({ color: "#" + ((Math.random() * 0xffffff) scene.remove(scene.children[1]); } }); // 渲染场景 function render() { renderer.render(scene, camera); } render(); // 监听窗口大小变化 window.addEventListener("resize", function () { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth - 100, window.innerHeight); render(); }); // 鼠标移动事件,稍后更新交叉点 document.addEventListener("mousemove", function (event) { }); // FPS控件 var controls = new THREE.OrbitControls(camera, renderer.domElement); controls.target.set(0, 50, 0); controls.update(); // 动画循环 function animate() { requestAnimationFrame(animate); render(); } animate(); |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |