Three.js: OrbitControls: How to zoom smoothly

Created on 10 Jan 2018  ·  26Comments  ·  Source: mrdoob/three.js

Description of the problem

I use OrbitControlsto control camera, and I set

    controls.enableZoom = true;
    controls.zoomSpeed = 1.2;

but when the camera zooming , it can't zooming like sketchfab's model , it is not so smooth. how to fix it?

Three.js version
  • [x ] r89

    Browser
  • [ ] All of them

  • [x] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [ ] All of them
  • [x] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Hardware Requirements (graphics card, VR Device, ...)
Question

Most helpful comment

TrackballControls supports smooth zooming, so my solution was to use a combination of both.

For OrbitControls disable zooming but enable panning/rotating. For TrackballControls, do the opposite (enable zooming, disable panning, rotating)

    // https://threejs.org/docs/#examples/en/controls/OrbitControls
    this._controls = new OrbitControls(this._camera, this._renderer.domElement);
    this._controls.enableDamping = true;
    this._controls.dampingFactor = 0.1;
    this._controls.screenSpacePanning = true;

    this._controls.enableZoom = false;

    this._controls.rotateSpeed = 0.5;

    this._controls.minDistance = 100;
    this._controls.maxDistance = 500;



    this._controls2 = new TrackballControls(this._camera, this._renderer.domElement);
    this._controls2.noRotate = true;
    this._controls2.noPan = true;
    this._controls2.noZoom = false;
    this._controls2.zoomSpeed = 1.5;
    this._controls2.dynamicDampingFactor = 0.2; // set dampening factor
    this._controls2 = controls;

Then whenever you call controls.update(), you need to sync the TrackballControl's target with the OrbitControls target

    let target = this._controls.target;
        this._controls.update();
    this._controls2.target.set(target.x, target.y, target.z);
    this._controls2.update();

All 26 comments

This kind of damping behavior is not supported by OrbitControls right now.

@Mugen87 Why do you say damping is not supported?

I refer to the smooth slow down of movements in Sketchfab's controls. I thought the PR #12179 tries to add this feature. Please enlighten me if i've misunderstood something 😇

I want to understand what you are saying... Is it that you agree that damping is supported, it is just different from Sketchfab's damping?

// Set to true to enable damping (inertia)
// If damping is enabled, you must call controls.update() in your animation loop
this.enableDamping = false;
this.dampingFactor = 0.25;

Also, on a Mac, mouse scroll has built-in inertia, so different hardware will have different behavior.

Is it that you agree that damping is supported, it is just different from Sketchfab's damping?

Yes. Sry for being unclear in this case. I just want to say that @StoneMa needs to modify OrbitControls if he wants the "Sketchfab" behavior.

On my Mac, I see no significant difference between Sketchfab behavior and OrbitControls behavior when zooming with a mouse. I did not test touch -- nor have I tested other hardware.

So... it is not clear to me what the issue is.

It's hard to describe...but it feels different. At least on my iMac.

I don't wanna say it's better. Just different...

@StoneMa Can you please provide a live example to demonstrate the issue? Please also specify your hardware and operating system.

sorry guys, come late, code in this link:
https://codepen.io/anon/pen/QamPrY
if you can't zoom use your mouse wheel
you may have to add

    controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.rotateSpeed = 0.25;
    controls.enableZoom = true;

to the init() function in JavaScript.


hardware:
CPU : i5-6500
RAM : 16G
GPU : GTX950
Mouse : sry maybe @Logitech?
OS: windows10
Chrome version 62 (32bit)


@WestLangley I means the behavior when zooming with a mouse,it's about scope.object.zoom, there is no damping behavior, and it's not

this.enableDamping = false;
this.dampingFactor = 0.25;

@StoneMa

  1. Why are you are instantiating _two_ orbit controls in your codepen?
  2. Why are you not setting controls.enableDamping = true?

@WestLangley I just optimize my website's User experience,and I find sketchfab has Rotational damping & Zoom damping, so I want to kown could Three.js support it.

@StoneMa what @WestLangley says is that there are copy-paste errors in your codepen. Once you fix them, it will work.

@WestLangley @makc @Mugen87 Thx guys, it works.

I may be missing something with my damping requests but I can't have zoom damping anywhere even in that example (Windows + Linux + Android). @StoneMa do you have the zoom damping you were looking for on your Windows computer in your codepen demo ?

I'm late,Sorry for my Spring Festival holiday, I'll give demo later. @Astrak

@StoneMa In case you're still wondering, the zoom difference between Sketchfab and OrbitControls, is that Sketchfab has damping for zoom as well, and you can add that quite easily.

As of r100, OrbitControls reset scale back to 1 in each update, if you just 'damping' it instead when enableDamping is set to true, it should give you the feel of Sketchfab.

I was able to get a similar result as sketchfab with a dolly damping factor of 0.12.

@xinghul Could you please share your reference ?

@xinghul did you check if the zoom speed is identical between a Mac desktop and other devices? With built-in inertia Mac should be far too fast if some discrimination is not implemented.

http://jsfiddle.net/5u4wst30/
Probably this is an example of smooth zoom
Here it works like in Sketchfab

@unilimes what did you change?

@unilimes what did you change?

@mrdoob A .smoothZoomUpdate() method was added to the local copy of OrbitControls. Calling controls.update() is also required in the render loop.

On macOS, the mouse has built-in inertia, so this change is not required.

@unilimes your code works. However, because of dampening the rotation and zoom does not work at the same time.

FWIW, model viewer also uses its own implementation of the orbit controls: https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/three-components/SmoothControls.ts

http://jsfiddle.net/5u4wst30/
Probably this is an example of smooth zoom
Here it works like in Sketchfab

@unilimes This works great, however there is one undesirable effect. If you try to zoom while the rotating is dampening, the zoom waits till the rotation is finished and then it zooms in. Any way to allow a zoom while it is currently rotating?

@unilimes Here is a forked link of the Fiddle you sent which has a slower dampingFactor, that shows the issue more clear.

http://jsfiddle.net/9r7jbow0/

Thanks! :)

TrackballControls supports smooth zooming, so my solution was to use a combination of both.

For OrbitControls disable zooming but enable panning/rotating. For TrackballControls, do the opposite (enable zooming, disable panning, rotating)

    // https://threejs.org/docs/#examples/en/controls/OrbitControls
    this._controls = new OrbitControls(this._camera, this._renderer.domElement);
    this._controls.enableDamping = true;
    this._controls.dampingFactor = 0.1;
    this._controls.screenSpacePanning = true;

    this._controls.enableZoom = false;

    this._controls.rotateSpeed = 0.5;

    this._controls.minDistance = 100;
    this._controls.maxDistance = 500;



    this._controls2 = new TrackballControls(this._camera, this._renderer.domElement);
    this._controls2.noRotate = true;
    this._controls2.noPan = true;
    this._controls2.noZoom = false;
    this._controls2.zoomSpeed = 1.5;
    this._controls2.dynamicDampingFactor = 0.2; // set dampening factor
    this._controls2 = controls;

Then whenever you call controls.update(), you need to sync the TrackballControl's target with the OrbitControls target

    let target = this._controls.target;
        this._controls.update();
    this._controls2.target.set(target.x, target.y, target.z);
    this._controls2.update();
Was this page helpful?
0 / 5 - 0 ratings