编程语言
首页 > 编程语言> > javascript-根据鼠标指针放大到对象

javascript-根据鼠标指针放大到对象

作者:互联网

在这里,我尝试根据鼠标指针的位置放大对象(例如立方体).在这里,我搜索了一个想法,认为它可以在D3 JS中实现,也可以通过捕获鼠标指针3D点并将其传递到鼠标滚轮功能中来实现.

这是小提琴https://jsfiddle.net/fpt9hswo/

var scene, renderer, camera;
var cube;
var controls;
var containerWidth = window.innerWidth,
  containerHeight = window.innerHeight;

init();
animate();

function init() {
  configureRenderer();

  scene = new THREE.Scene();

  configureCube();

  configureCamera();

  configureLight();

  configureControls();

  fitAll();
}

function configureRenderer() {
  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });
  renderer.setSize(containerWidth, containerHeight);
  document.body.appendChild(renderer.domElement);
}

function configureCube() {
  var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
  var cubeMaterial = new THREE.MeshLambertMaterial({
    color: 0xff0000
  });
  cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.position.set(50, 0, 0);
  scene.add(cube);
}

function configureCamera() {
  camera = new THREE.PerspectiveCamera(45, containerWidth / containerHeight, 1, 1000);
  camera.position.set(0, 160, 400);
  camera.lookAt(scene);
}

function configureLight() {
  pointLight = new THREE.PointLight(0xffffff, 1.0, 100000);
  pointLight.position.set(0, 300, 200);
  scene.add(pointLight);
}

function configureControls() {
  controls = new THREE.TrackballControls(camera, renderer.domElement);
   // configuration of controls
  controls.rotateSpeed = 5.0;
  controls.zoomSpeed = 5.0;
  controls.panSpeed = 2.0;
  controls.staticMoving = true;
  controls.dynamicDampingFactor = 0;
}

function fitAll() {
  // Calculate bounding box of the whole scene
  var boundingBoxOfNode = new THREE.Box3().setFromObject(scene),
    centerOfGravity = boundingBoxOfNode.getCenter();

 /************* CAMERA *************************/
  camera.position.addVectors(camera.position, centerOfGravity);
  camera.lookAt(centerOfGravity);
  //new camera positions will be set here
  //Eg: camera.position.set(newCamera.x,newCamera.y,newCamera.z);
  //Similarly new camera rotation and quaternion coordinates will be set
  //Eg: camera.rotation.set(newCamera.rotatex,newCamera.rotatey,newCamera.rotatez);
  //Eg: camera.quaternion.set(newCamera.qw,newCamera.qx,newCamera.qy,newCamera.qz);

  /*************    CONTROLS *************************/
  controls.target.set(centerOfGravity.x, centerOfGravity.y, centerOfGravity.z);
  //new controls.target values will be set here
  //Eg: controls.target.set(newCamera.targetx,newCamera.targety,newCamera.targetz);
}

function animate() {
  controls.update();
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

提前致谢

解决方法:

要执行您想要的操作,您必须实现自己的鼠标滚轮事件,并且必须禁用THREE.TrackballControls的默认缩放:

controls = new THREE.TrackballControls(camera, renderer.domElement);
//...
controls.zoomSpeed = 0.0;

添加车轮事件:

例如

renderer.domElement.addEventListener("wheel", event => {
    const delta = event.deltaY;

    // [...]
}

通过将相机位置移动到世界的深处,可以实现放大透视投影.
如果要缩放到一个点,可以通过沿光线移动相机(从相机位置到光标(鼠标)位置)并平行移动目标位置来实现.

在归一化设备空间中,可以轻松找到从相机到光标的光线点.在规范化的设备空间中,所有坐标都在[-1,1]范围内,并且所有具有相同x和y坐标的点都位于同一条射线中.如果z坐标为-1,则该点在近平面上,如果z为1,则该点在远平面上.

例如NDC点在远平面上并在通过光标的射线上:

let x = 2 * event.clientX / window.innerWidth - 1; 
let y = 1 - 2 * event.clientY / window.innerHeight;
let cursorpos = new THREE.Vector3(x, y, 1);

可以通过THREE.Vector3.unproject()将规范化设备空间中的该点转换为世界空间中的一个点.该函数的参数必须为THREE.Camera,用于定义视图和投影:

cursorpos.unproject(camera);

摄像机的移动方向是从摄像机位置到世界空间中光标位置的归一化方向:

let dir = new THREE.Vector3().copy(cursorpos).sub(camera.position).normalize();

根据方向和鼠标滚轮增量计算运动,并更新相机和THREE.TrackballControls:

let shift = new THREE.Vector3().copy(dir).multiplyScalar(delta * 0.1);

camera.position.add(shift);
controls.position0.add(shift);
controls.target.add(shift);

请参见示例,其中我将建议应用于问题的代码:

var scene, renderer, camera;
var cube;
var controls;
var containerWidth = window.innerWidth,
  containerHeight = window.innerHeight;

init();

animate();

function init() {
  configureRenderer();

  scene = new THREE.Scene();
  configureCube();
  configureCamera();
  configureLight();
  configureControls();
}

function configureRenderer() {
  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });
  renderer.setSize(containerWidth, containerHeight);
  document.body.appendChild(renderer.domElement);

  window.onresize = function() {
      renderer.setSize(window.innerWidth, window.innerHeight);
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      if (controls)
          controls.handleResize();
  }

  renderer.domElement.addEventListener("wheel", event => {
      const delta = event.deltaY;

      let x = 2 * event.clientX / window.innerWidth - 1; 
      let y = 1 - 2 * event.clientY / window.innerHeight;
      let cursorpos = new THREE.Vector3(x, y, 1);

      cursorpos.unproject(camera); 

      let dir = new THREE.Vector3().copy(cursorpos).sub(camera.position).normalize();
      let shift = new THREE.Vector3().copy(dir).multiplyScalar(delta * 0.1);

      camera.position.add(shift);
      controls.position0.add(shift);
      controls.target.add(shift);
  });
}

function configureCube() {
  var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
  var cubeMaterial = new THREE.MeshLambertMaterial({
    color: 0xff0000
  });
  cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.position.set(50, 0, 0);
  scene.add(cube);
}

function configureCamera() {
  camera = new THREE.PerspectiveCamera(45, containerWidth / containerHeight, 1, 1000);
  camera.position.set(0, 160, 400);
  camera.lookAt(scene);
}

function configureLight() {
  pointLight = new THREE.PointLight(0xffffff, 1.0, 100000);
  pointLight.position.set(0, 300, 200);
  scene.add(pointLight);
}

function configureControls() {
  controls = new THREE.TrackballControls(camera, renderer.domElement);
  // configuration of controls
  controls.rotateSpeed = 5.0;
  controls.zoomSpeed = 0.0;
  controls.panSpeed = 2.0;
  controls.staticMoving = true;
  controls.dynamicDampingFactor = 0;
}

function animate() {
  controls.update();
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>

标签:d3-js,three-js,javascript
来源: https://codeday.me/bug/20191210/2104861.html