如何使用three.js集成令人羡慕的局部坐标系
示例
官方源码
https://github.com/mrdoob/three.js/blob/dev/examples/webgl_geometry_spline_editor.html
- 使用源码的方法:
直接将源码copy到项目中的htmldoge,然后如果你用了react框架,你要把App.jsx文件恢复到原来的样子 - 项目的业务
你把鼠标悬停在上面,坐标系就出来了,
坐标系出来后,你才可以移动他,
他并不是靠鼠标点击来实现的
阅读源码
(假设你是第一次接触前端代码,没错,我也是一次,so,作为一个对前端一无所知的萌新,接下来让我们一起来剖析官方的源代码,如果我们可以搞懂这问题,那这对于前端版本的opengl来说,你对模型与鼠标交互的理解,将大幅度提升,而且我想这段代码应该也是可以复用的,俗话说:“知道如何写代码值1分钱”,“知道把别人的某一部分代码放到自己几万行的屎山代码中,值百万dollars”.[doge])
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometry - catmull spline editor</title>
<meta charset="utf-8">
<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="container"></div>
<div id="info">
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - geometry - catmull spline editor
</div>
<script type="importmap">
{
"imports": {
"three": "../build/three.module.js",
"three/addons/": "./jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import {
GUI } from 'three/addons/libs/lil-gui.module.min.js';
import {
OrbitControls } from 'three/addons/controls/OrbitControls.js';
import {
TransformControls } from 'three/addons/controls/TransformControls.js';
let container;
let camera, scene, renderer;
const splineHelperObjects = [];
let splinePointsLength = 4;
const positions = [];
const point = new THREE.Vector3();
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
const onUpPosition = new THREE.Vector2();
const onDownPosition = new THREE.Vector2();
const geometry = new THREE.BoxGeometry( 20, 20, 20 );
let transformControl;
const ARC_SEGMENTS = 200;
const splines = {
};
const params = {
uniform: true,
tension: 0.5,
centripetal: true,
chordal: true,
addPoint: addPoint,
removePoint: removePoint,
exportSpline: exportSpline
};
init();
function init() {
container = document.getElementById( 'container' );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xf0f0f0 );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 250, 1000 );
scene.add( camera );
scene.add( new THREE.AmbientLight( 0xf0f0f0, 3 ) );
const light = new THREE.SpotLight( 0xffffff, 4.5 );
light.position.set( 0, 1500, 200 );
light.angle = Math.PI * 0.2;
light.decay = 0;
light.castShadow = true;
light.shadow.camera.near = 200;
light.shadow.camera.far = 2000;
light.shadow.bias = - 0.000222;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
scene.add( light );
const planeGeometry = new THREE.PlaneGeometry( 2000, 2000 );
planeGeometry.rotateX( - Math.PI / 2 );
const planeMaterial = new THREE.ShadowMaterial( {
color: 0x000000, opacity: 0.2 } );
const plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.position.y = - 200;
plane.receiveShadow = true;
scene.add( plane );
const helper = new THREE.GridHelper( 2000, 100 );
helper.position.y = - 199;
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add( helper );
renderer = new THREE.WebGLRenderer( {
antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
container.appendChild( renderer.domElement );
const gui = new GUI();
gui.add( params, 'uniform' ).onChange( render );
gui.add( params, 'tension', 0, 1 ).step( 0.01 ).onChange( function ( value ) {
splines.uniform.tension = value;
updateSplineOutline();
render();
} );
gui.add( params, 'centripetal' ).onChange( render );
gui.add( params, 'chordal' ).onChange( render );
gui.add( params, 'addPoint' );
gui.add( params, 'removePoint' );
gui.add( params, 'exportSpline' );
gui.open();
// Controls
const controls = new OrbitControls( camera, renderer.domElement );
controls.damping = 0.2;
controls.addEventListener( 'change', render );
transformControl = new TransformControls( camera, renderer.domElement );
transformControl.addEventListener( 'change', render );
transformControl.addEventListener( 'dragging-changed', function ( event ) {
controls.enabled = ! event.value;
} );
scene.add( transformControl );
transformControl.addEventListener( 'objectChange', function () {
updateSplineOutline();
} );
document.addEventListener( 'pointerdown', onPointerDown );
document.addEventListener( 'pointerup', onPointerUp );
document.addEventListener( 'pointermove', onPointerMove );
window.addEventListener( 'resize', onWindowResize );
/*******
* Curves
*********/
for ( let i = 0; i < splinePointsLength; i ++ ) {
addSplineObject( positions[ i ] );
}
positions.length = 0;
for ( let i = 0; i < splinePointsLength; i ++ ) {
positions.push( splineHelperObjects[ i ].position );
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute(