主要内容: 使用 threejs 创建 20x20 的网格,鼠标移动时,方块跟随移动,点击时在网格任意位置放置方块,按 shift 时,删除当前位置方块。

流程如下:

  • 创建网格
  • 创建一个与网格同样尺寸的平面
  • 创建一个方块 mesh_1 与网格同样的尺寸
  • 一个与网格同样的方块 geometry_2 , 不加入 scene 中
  • 三个事件:
    • 鼠标移动事件,随着鼠标移动,更改 mesh_1 位置,并重新渲染
    • 鼠标点击事件,在交点位置,创建新 mesh, 若是相交对象不为 平面,则删除当前对象
    • keydown, keyup, 更改是否删除的状态

详细代码如下:


import * as THREE from './build/three.module'
import { stat } from 'fs'; var camera, scene, renderer;
var moveMesh, staticGeo,staticMat, plane;
var objects = [];
var raycaster, mouse;
var isShiftDown = false; function init() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(500, 800, 1300);
camera.lookAt(0, 0, 0); scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0); // lights
var light = new THREE.AmbientLight(0x606060);
scene.add(light); // grids
var grid = new THREE.GridHelper(1000, 20);
scene.add(grid); // plane, 辅助碰撞检测
var planeGeo = new THREE.PlaneBufferGeometry(1000, 1000);
var planMat = new THREE.MeshBasicMaterial({color: 0xffff00, visible : true});
plane = new THREE.Mesh(planeGeo, planMat);
plane.rotateX(-Math.PI /2);
scene.add(plane);
objects.add(plane); // 射线 raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2(); // moveCube;
var moveGeo = new THREE.BoxBufferGeometry(50, 50, 50);
var moveMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, opacity: 0.5, transparent: true });
moveMesh = new THREE.Mesh(moveGeo, moveMaterial);
scene.add(moveMesh); // static cube
staticGeo = new THREE.BoxBufferGeometry(50, 50, 50);
staticMat = new THREE.MeshLambertMaterial({ color: 0xfeb74c, map: new THREE.TextureLoader().load('textures/square-outline-textured.png') }); renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);
document.body.addEventListener('mousemove', onDocuementMouseMove, false);
document.body.addEventListener('mousedown', onDocumentMouseDown, false);
document.body.addEventListener('keydown', onDocuementKeyDown, false);
document.body.addEventListener('keyup', onDocuementKeyUp, false); window.addEventListener('resize', onWindowResize, false);
} function onDocumentMouseDown(event) {
event.preventDefault(); // 鼠标位置归一化
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; // 通过摄像机与鼠标更新射线
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects);
if(intersects.length > 0) {
var intersect = intersects[0];
if (isShiftDown) {
if(intersect.object !== plane) {
scene.remove(intersect.object);
objects.splice(objects.indexOf(intersect.object), 1);
}
}
else
{
var staticMesh = new THREE.Mesh(staticGeo, staticMat);
staticMesh.position.copy(intersect.point).add(intersect.face.normal);
staticMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);
scene.add(staticMesh);
objects.push(staticMesh);
}
} } function onDocuementMouseMove(event) {
event.preventDefault();
// 鼠标位置归一化
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; // 通过摄像机与鼠标更新射线
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects); if(intersects.length > 0) {
intersect = intersects[0];
// 移动位置到目标点
moveMesh.position.copy(intersect.point).add(intersect.face.normal);
// 计算具体方格
moveMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);
}
render();
} function onDocuementKeyDown(event) {
switch (event.keyCode) {
case 16: isShiftDown = true; break;
}
} function onDocuementKeyUp(event) {
switch (event.keyCode) {
case 16: isShiftDown = false; break;
}
} function onWindowResize() {
camera.aspect = window.innerWidth/ window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight); } function render()
{
renderer.render(scene, camera);
}

threejs 学习之的更多相关文章

  1. ThreeJS学习6_几何体相关(BufferGeometry)

    ThreeJS学习6_几何体相关(BufferGeometry) 使用 BufferGeometry 可以有效减少向 GPU 传输几何体相关数据所需的开销 可以自定义顶点位置, 面片索引, 法向量, ...

  2. # ThreeJS学习7_裁剪平面(clipping)

    ThreeJS学习7_裁剪平面(clipping) 目录 ThreeJS学习7_裁剪平面(clipping) 1. 裁剪平面简介 2. 全局裁剪和局部裁剪 3. 被多个裁剪平面裁剪后 4. 被多个裁剪 ...

  3. WebGL和ThreeJs学习6--射线法确定3D空间中所选物体

    一.在 threejs 中如何确定下图3D空间中鼠标点击位置的 object 对象? 二.射线法确定步骤及代码 //Three.js提供一个射线类Raycaster来拾取场景里面的物体.更方便的使用鼠 ...

  4. WebGL和ThreeJs学习5--ThreeJS基本功能控件

      Threejs 2017年6月6日 15:06 Stats: new Stats();性能监视器,性能测试的方法,引入 Stats.js        http://www.hewebgl.com ...

  5. threejs学习笔记(二)

    THREE.WebGLRenderer THREE.Scene THREE.OrthographicCamera正交相机 THREE.PerspectiveCamera透视相机 renderer.se ...

  6. threejs学习笔记(一)

    得到webgl的渲染管线

  7. threejs和3d各种效果的学习

    写给即将开始threejs学习的自己,各种尝试,各种记忆.不要怕,灰色的年华终会过去. 一个技术学习的快慢,以及你的深刻程度,还有你的以后遇到这个东西的时候的反应速度,很大程度上,取决于你的博客的深刻 ...

  8. 初识webgl--我的webgl学习第一课(基于threeJs)

    一,我为什么要学习webgl 一个偶然的机会,在和朋友的聊天过程中,听说了webgl,也许过去也看到过,但是没有特别在意过.原来,JavaScript也可以很好的渲染并在网页上显示三维动画,不用借助插 ...

  9. gis和threejs的学习资料

    *********************************** 基础知识/名词 瓦片/矢量瓦片GeoJson - 绘制GeoJson看数据, geojson规范, 中文版 ********** ...

随机推荐

  1. (转)代码结构中Dao,Service,Controller,Util,Model是什么意思?

    作者:技能树IT修真院链接:https://www.zhihu.com/question/58410621/answer/623496434来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商 ...

  2. Spring Boot日志使用

    前言: 这是我第一次仔细研究Spring Boot相关的知识,就拿日志下手了,欢迎大家指点 Spring Boot日志关系 这个是Spring Boot的启动器,我们点击spring-boot-sta ...

  3. bzoj1584 9.20考试 cleaning up 打扫卫生

    1584: [Usaco2009 Mar]Cleaning Up 打扫卫生 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 549  Solved: 38 ...

  4. 马蜂窝 IM 系统架构的演化和升级

    今天,越来越多的用户被马蜂窝持续积累的笔记.攻略.嗡嗡等优质的分享内容所吸引,在这里激发了去旅行的热情,同时也拉动了马蜂窝交易的增长.在帮助用户做出旅行决策.完成交易的过程中,IM 系统起到了重要的作 ...

  5. 在dotnet core实现类似crontab的定时任务

    前段需要在业务中实现某些时间段的简单定时任务,类似crontab的调度,因为业务会放在docker中,所以不想用直接用crontab,在网上搜了一下,发现一个开源的实现 Pomelo.AspNetCo ...

  6. sql注入篇2

    一.前言 上一篇:sql注入篇1 二.基于回显的注入类型判断 1.有结果的注入 例如下图: (sqlllab less-1)可以看到有正常结果返回,对于的利用方式就是老套路了,先order by查询出 ...

  7. 代码中批量执行Oracle SQL语句

    今天在写一个工具(winform),作用是批量的INSERT OR  UPDATE ORACLE数据库中的一个表. 执行的时候老是报错“[911] ORA-00911: invalid charact ...

  8. Linux mysql开启远程访问

    默认情况下远程访问会出现 Can't connect to MySQL server on '192.168.10.18′ (10061) 错误是因为,mysql的默认配置为了增强安全性,禁止了非本机 ...

  9. vue系列---vue项目(已安装vuex)中引入jquery

    vue项目中引入jquery有很多方法,这只是其中一种. 步骤如下: 1,安装jquery依赖 npm install jquery --save 如果是使用淘宝镜像则将npm改为cnpm 2,修改配 ...

  10. java oop 单列 双列 集合, 迭代器 的使用和说明

    一.集合(Collection) (1)集合的由来? 我们学习的是Java -- 面向对象 -- 操作很多对象 -- 存储 -- 容器(数组和StringBuffer) -- 数组 而数组的长度固定, ...