首页 > 其他分享 >threejs_交互_鼠标点击_添加物体_删除物体

threejs_交互_鼠标点击_添加物体_删除物体

时间:2023-04-06 23:22:10浏览次数:40  
标签:threejs const 鼠标 物体 THREE scene window new 50

click点击添加物体,shirft+click点击删除物体

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="utf-8">
	<title>three.js webgl - interactive - voxel painter</title>
	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
	<link type="text/css" rel="stylesheet" href="main.css">
	<style>
		body {
			background-color: #f0f0f0;
			color: #444;
		}

		a {
			color: #08f;
		}
	</style>
</head>

<body>

	<div id="info">
		<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - voxel painter - webgl<br>
		<strong>click</strong>: add voxel, <strong>shift + click</strong>: remove voxel
	</div>

	<!-- Import maps polyfill -->
	<!-- Remove this when import maps will be widely supported -->
	<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>

	<script type="importmap">
			{
				"imports": {
					"three": "../build/three.module.js",
					"three/addons/": "./jsm/"
				}
			}
		</script>

	<script type="module">

		import * as THREE from 'three';

		let camera, scene, renderer;
		let plane;
		let pointer, raycaster, isShiftDown = false;

		let rollOverMesh, rollOverMaterial;
		let cubeGeo, cubeMaterial;

		// objects数组用来存放地平面和所有的小方块
		const objects = [];

		init();
		render();

		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);

			// roll-over helpers

			const rollOverGeo = new THREE.BoxGeometry(50, 50, 50);
			rollOverMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, opacity: 0.5, transparent: true });
			rollOverMesh = new THREE.Mesh(rollOverGeo, rollOverMaterial);
			scene.add(rollOverMesh);

			// cubes

			cubeGeo = new THREE.BoxGeometry(50, 50, 50);
			cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xfeb74c, map: new THREE.TextureLoader().load('textures/square-outline-textured.png') });

			// grid

			const gridHelper = new THREE.GridHelper(1000, 20);
			scene.add(gridHelper);

			//

			raycaster = new THREE.Raycaster();
			pointer = new THREE.Vector2();

			const geometry = new THREE.PlaneGeometry(1000, 1000);
			geometry.rotateX(- Math.PI / 2);

			plane = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ visible: false }));
			scene.add(plane);

			objects.push(plane);

			// lights

			const ambientLight = new THREE.AmbientLight(0x606060);
			scene.add(ambientLight);

			const directionalLight = new THREE.DirectionalLight(0xffffff);
			directionalLight.position.set(1, 0.75, 0.5).normalize();
			scene.add(directionalLight);

			renderer = new THREE.WebGLRenderer({ antialias: true });
			renderer.setPixelRatio(window.devicePixelRatio);
			renderer.setSize(window.innerWidth, window.innerHeight);
			document.body.appendChild(renderer.domElement);

			document.addEventListener('pointermove', onPointerMove);
			document.addEventListener('pointerdown', onPointerDown);
			document.addEventListener('keydown', onDocumentKeyDown);
			document.addEventListener('keyup', onDocumentKeyUp);

			//

			window.addEventListener('resize', onWindowResize);

		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize(window.innerWidth, window.innerHeight);

			render();

		}

		function onPointerMove(event) {

			pointer.set((event.clientX / window.innerWidth) * 2 - 1, - (event.clientY / window.innerHeight) * 2 + 1);

			raycaster.setFromCamera(pointer, camera);

			const intersects = raycaster.intersectObjects(objects, false);

			if (intersects.length > 0) {

				// eslint-disable-next-line computed-property-spacing
				const intersect = intersects[0];

				rollOverMesh.position.copy(intersect.point).add(intersect.face.normal);
				rollOverMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);

				render();

			}

		}

		function onPointerDown(event) {

			pointer.set((event.clientX / window.innerWidth) * 2 - 1, - (event.clientY / window.innerHeight) * 2 + 1);
			raycaster.setFromCamera(pointer, camera);
			const intersects = raycaster.intersectObjects(objects, false);

			if (intersects.length > 0) {

				const intersect = intersects[0];

				// delete cube
				if (isShiftDown) {

					if (intersect.object !== plane) {

						//除了从场景中删除小方块,还要从物体数组中删除小方块
						scene.remove(intersect.object);
						objects.splice(objects.indexOf(intersect.object), 1);

					}

					// create cube

				} else {

					const voxel = new THREE.Mesh(cubeGeo, cubeMaterial);
					voxel.position.copy(intersect.point).add(intersect.face.normal);
					voxel.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);
					scene.add(voxel);

					objects.push(voxel);

				}

				render();

			}

		}

		function onDocumentKeyDown(event) {

			switch (event.keyCode) {

				case 16: isShiftDown = true; break;

			}

		}

		function onDocumentKeyUp(event) {

			switch (event.keyCode) {

				case 16: isShiftDown = false; break;

			}

		}

		function render() {

			renderer.render(scene, camera);

		}

	</script>

</body>

</html>

标签:threejs,const,鼠标,物体,THREE,scene,window,new,50
From: https://www.cnblogs.com/zhuoss/p/17294595.html

相关文章

  • Chrome浏览器插件:CrxMouse(鼠标手势控制浏览器)
    CrxMouse是一款谷歌浏览器插件,它可以通过手势来控制您的浏览器,在您的日常网络浏览中提高效率和速度。插件介绍CrxMouse是一个非常流行的谷歌浏览器插件,它允许您通过鼠标手势来控制您的浏览器。该插件集成了大量的手势功能,使您可以在不使用键盘或鼠标的情况下轻松地进行网页浏览......
  • JS轮播图定时播放,鼠标经过轮播图时不停,鼠标离开轮播图时播放速度越来越快
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=d......
  • 卡尔曼滤波物体轨迹预测趣味实战
       卡尔曼滤波实战最近刚好看到了一个有意思的卡尔曼滤波的视频,于是就学习了一下,现分享给大家......
  • js 鼠标事件的位置x,y
    1.clientX和clientY与x,yclientX和clientY与x,y一样的,都是客户当前显示的屏幕上(反之可能被卷去)可视区域坐标,指鼠标的坐标,以浏览器显示网页区域的左上角开始,x,y是新浏览器支持2.offsetX,offsetYoffsetX,offsetY针对目标元素(就是被点击的元素)offsetXoffsetY是相对于触发元素不......
  • DOM:让一个元素跟随鼠标移动而移动
    <!DOCTYPEhtml><htmllang="en"><head>  <metacharset="UTF-8">  <metahttp-equiv="X-UA-Compatible"content="IE=edge">  <metaname="viewport"content="width=......
  • threejs 拖拽 画矩形
    import*asTHREEfrom"three";import{OrbitControls}from"three/examples/jsm/controls/OrbitControls";exportfunctioninitThree(){THREE.Object3D.DefaultUp.set(0,0,1);varscene=newTHREE.Scene();varcamera=newTHR......
  • Python 自动化指南(繁琐工作自动化)第二版:二十、使用 GUI 自动化控制键盘和鼠标
    原文:https://automatetheboringstuff.com/2e/chapter20/了解用于编辑电子表格、下载文件和启动程序的各种Python模块是很有用的,但有时您需要使用的应用没有任何模块。在计算机上实现任务自动化的终极工具是你编写的直接控制键盘和鼠标的程序。这些程序可以通过发送虚拟击键......
  • FastAdmin 中table字段太长,显示省略号,鼠标停留显示文字
    {field:'question',title:__('Question'),operate:false,formatter:function(value,row,index,field){return"<spanstyle='display:block;overflow:hidden;text-overflow:ellipsis;white-space:......
  • Python基础之pyautogui模块(详细总结鼠标键盘操作)
    来源:https://zhuanlan.zhihu.com/p/471275277仅用于个人学习(以防自己忘记)1.GUI控制功能控制鼠标键盘使用的模块为:pyautogui,这个模块操作起鼠标键盘的时候,非常的迅速,而且如果该模块控制了鼠标后,程序比较难关闭,这时我们有两个方法专门针对以上的情况:1.1自动防故障功能 ......
  • Qt音视频开发33-vlc和mpv打开后鼠标打圈圈问题的解决
    一、前言如果采用的vlc句柄模式,如果鼠标停留在句柄控件中会发现在打开后鼠标打圈圈,mpv句柄模式是在关闭后鼠标打圈圈,这两者真是一前一后,这种给人的体验其实很不友好的,播放开始后或者播放完成后鼠标指针居然变成了繁忙,但是当你将鼠标位置从句柄控件中移到外面的时候,他又会自动恢复......