Javascript 基于鼠标指针放大到对象

Javascript 基于鼠标指针放大到对象,javascript,d3.js,three.js,Javascript,D3.js,Three.js,在这里,我试图根据鼠标指针的位置放大对象(比如立方体)。在这里,我通过谷歌搜索得到了一个想法,它可以在D3JS中实现,也可以通过捕获鼠标指针的3D点并将其传递到鼠标滚轮功能中来实现 这是小提琴 提前感谢要执行您想要的操作,您必须实现自己的鼠标滚轮事件,并且必须禁用默认的三次缩放。轨迹球控件: controls=新的三个.trackball控件(摄影机、渲染器.doElement); //... controls.zoomSpeed=0.0; 添加控制盘事件: e、 g renderer.doE

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

这是小提琴


提前感谢

要执行您想要的操作,您必须实现自己的鼠标滚轮事件,并且必须禁用默认的三次缩放。轨迹球控件:

controls=新的三个.trackball控件(摄影机、渲染器.doElement);
//...
controls.zoomSpeed=0.0;
添加控制盘事件:

e、 g

renderer.doElement.addEventListener(“轮子”,事件=>{
const delta=event.deltaY;
// [...]
}
通过在世界深处移动相机位置,可以实现透视投影的放大。
如果要缩放到某个点,可以通过沿光线移动摄影机,从摄影机位置移动到光标(鼠标)位置,并平行移动目标位置来实现

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

e、 g.远平面上的NDC点和穿过光标的光线上的NDC点:

让x=2*event.clientX/window.innerWidth-1;
设y=1-2*event.clientY/window.innerHeight;
设cursorpos=new-THREE.Vector3(x,y,1);
标准化设备空间中的该点可以通过转换为世界空间中的点。函数的参数必须是定义视图和投影的:

cursorpos.unproject(摄像机);
摄影机的移动方向是从摄影机位置到世界空间中光标位置的标准化方向:

let dir=new THREE.Vector3().copy(cursorpos).sub(camera.position).normalize();
根据方向和鼠标滚轮增量计算移动,并更新相机和
三个。轨迹球控制

let shift=new THREE.Vector3().copy(dir).multiplyScalar(delta*0.1);
摄像机。位置。添加(移位);
控制。位置0。添加(班次);
控件。目标。添加(班次);
请参见示例,其中我将建议应用于问题代码:

var场景、渲染器、摄影机;
var立方;
风险值控制;
var containerWidth=window.innerWidth,
containerHeight=窗内高度;
init();
制作动画();
函数init(){
配置渲染器();
场景=新的三个。场景();
configureCube();
配置摄像头();
configureLight();
配置控件();
}
函数configureRenderer(){
renderer=new THREE.WebGLRenderer({
反别名:是的,
阿尔法:是的
});
setSize(containerWidth,containerHeight);
document.body.appendChild(renderer.doElement);
window.onresize=函数(){
renderer.setSize(window.innerWidth、window.innerHeight);
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectMatrix();
如果(控制)
controls.handleResize();
}
renderer.doElement.addEventListener(“轮子”,事件=>{
const delta=event.deltaY;
设x=2*event.clientX/window.innerWidth-1;
设y=1-2*event.clientY/window.innerHeight;
设cursorpos=new-THREE.Vector3(x,y,1);
未投影光标(相机);
让dir=new THREE.Vector3().copy(cursorpos).sub(camera.position).normalize();
设shift=new THREE.Vector3().copy(dir).multiplyScalar(delta*0.1);
摄像机。位置。添加(移位);
控制。位置0。添加(班次);
控件。目标。添加(班次);
});
}
函数configureCube(){
var cubeGeometry=新的三箱几何体(20,20,20);
var cubeMaterial=新的3.0网格LambertMaterial({
颜色:0xff0000
});
立方体=新的三网格(立方计量法、立方材料);
立方体位置集(50,0,0);
场景.添加(立方体);
}
函数配置摄像头(){
摄像机=新的三个透视摄像机(45,集装箱宽度/集装箱高度,11000);
摄像机位置设置(0、160、400);
摄影机。看(场景);
}
函数configureLight(){
点光源=新的三点光源(0xffffff,1.010000);
点光源位置设置(0,300,200);
场景。添加(点光源);
}
函数配置控件(){
控件=新的三个.trackball控件(摄影机、渲染器.doElement);
//控件的配置
controls.rotateSpeed=5.0;
controls.zoomSpeed=0.0;
controls.panSpeed=2.0;
controls.staticMoving=true;
controls.dynamicDampingFactor=0;
}
函数animate(){
控件更新();
请求动画帧(动画);
渲染器。渲染(场景、摄影机);
}

如果您在向后拉鼠标的同时按下鼠标滚轮按钮,相机会变焦..这就是您所说的吗?
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);
}