threejs 学习之
主要内容: 使用 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 学习之的更多相关文章
- ThreeJS学习6_几何体相关(BufferGeometry)
ThreeJS学习6_几何体相关(BufferGeometry) 使用 BufferGeometry 可以有效减少向 GPU 传输几何体相关数据所需的开销 可以自定义顶点位置, 面片索引, 法向量, ...
- # ThreeJS学习7_裁剪平面(clipping)
ThreeJS学习7_裁剪平面(clipping) 目录 ThreeJS学习7_裁剪平面(clipping) 1. 裁剪平面简介 2. 全局裁剪和局部裁剪 3. 被多个裁剪平面裁剪后 4. 被多个裁剪 ...
- WebGL和ThreeJs学习6--射线法确定3D空间中所选物体
一.在 threejs 中如何确定下图3D空间中鼠标点击位置的 object 对象? 二.射线法确定步骤及代码 //Three.js提供一个射线类Raycaster来拾取场景里面的物体.更方便的使用鼠 ...
- WebGL和ThreeJs学习5--ThreeJS基本功能控件
Threejs 2017年6月6日 15:06 Stats: new Stats();性能监视器,性能测试的方法,引入 Stats.js http://www.hewebgl.com ...
- threejs学习笔记(二)
THREE.WebGLRenderer THREE.Scene THREE.OrthographicCamera正交相机 THREE.PerspectiveCamera透视相机 renderer.se ...
- threejs学习笔记(一)
得到webgl的渲染管线
- threejs和3d各种效果的学习
写给即将开始threejs学习的自己,各种尝试,各种记忆.不要怕,灰色的年华终会过去. 一个技术学习的快慢,以及你的深刻程度,还有你的以后遇到这个东西的时候的反应速度,很大程度上,取决于你的博客的深刻 ...
- 初识webgl--我的webgl学习第一课(基于threeJs)
一,我为什么要学习webgl 一个偶然的机会,在和朋友的聊天过程中,听说了webgl,也许过去也看到过,但是没有特别在意过.原来,JavaScript也可以很好的渲染并在网页上显示三维动画,不用借助插 ...
- gis和threejs的学习资料
*********************************** 基础知识/名词 瓦片/矢量瓦片GeoJson - 绘制GeoJson看数据, geojson规范, 中文版 ********** ...
随机推荐
- 9.5 考试 第三题 奇袭题解(codeforce 526f)
问题 C: 奇袭 时间限制: 1 Sec 内存限制: 256 MB 题目描述 由于各种原因,桐人现在被困在Under World(以下简称UW)中,而UW马上 要迎来最终的压力测试——魔界入侵. 唯 ...
- 不调用free会内存泄露吗?
内存泄露的概念大家可以自行百度下,本文不做阐述.本文要讲的是在程序中分配了内存,但是最后没有使用free()函数来释放这块内存,会导致内存泄露吗?比如有如下代码: #include <stdio ...
- R语言矩阵
矩阵是元素布置成二维矩形布局的R对象. 它们包含相同原子类型的元素. R创建矩阵的语法: matrix(data, nrow, ncol, byrow, dimnames) 参数说明: data - ...
- vs项目依赖项黄色感叹号解决方案
右键项目解决方案,生成解决方案或重新生成解决方案,黄色感叹号消失,依赖项生效,亲测有效
- Lock和synchronized比较详解(转)
从Java5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock. 也许有朋友会问,既然都可以通过synchronized来实现同步访问了, ...
- python常见模块-collections-time-datetime-random-os-sys-序列化反序列化模块(json-pickle)-subprocess-03
collections模块-数据类型扩展模块 ''' 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque ...
- MySQL常用工具、日志及读写分离
MySQL常用工具.日志及读写分离 1.MySQL中常用工具 1.1 mysql 1.1.1连接选项 1.1.2 执行选项 1.2 mysqladmin 1.3 mysqlbinlog 1.4 mys ...
- 腾讯云centos7 从零搭建laravel项目
目标,访问网站出现: -----------------------分割线---------------------------------------- 一.Laravel Homestead 环境 ...
- JavaOOP 第二章继承
一 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具 ...
- 1.4.2python网站地图爬虫(每天一更)
# -*- coding: utf-8 -*- ''' Created on 2019年5月6日 @author: 薛卫卫 ''' import urllib.request import re de ...