three.js实现拖拽生成模型场景

您所在的位置:网站首页 高德地图3d模型导出在哪里 three.js实现拖拽生成模型场景

three.js实现拖拽生成模型场景

2023-06-07 05:01| 来源: 网络整理| 查看: 265

 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;       }                                     Reset           // 场景       var scene = new THREE.Scene(); scene.background = new THREE.Color(0x002244);       // 渲染器       var renderer = new THREE.WebGLRenderer({ antialias: true });       renderer.setSize(window.innerWidth - 100, window.innerHeight);       document.getElementById("scene").appendChild(renderer.domElement);

      // 相机       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