Search code examples
objectthree.jsscaleonmouseover

ThreeJS – smooth scaling object while mouseover


another ThreeJS question: How can I make a hovered (intersected) object scale smooth to a defined size? My current code is

INTERSECTED.scale.x *= 1.5; INTERSECTED.scale.y *= 1.5;

but this only works like on/off.

Edit: My Solution (with tweenJS)

While mouseOver I scale up the element to 200% :

function scaleUp(){
    new TWEEN.Tween( INTERSECTED.scale ).to( {
       x: 2,
       y: 2 
    }, 350 ).easing( TWEEN.Easing.Bounce.EaseOut).start();
}

While mouseOut I scale down the element to 100% :

function scaleDown(){
    new TWEEN.Tween( INTERSECTED.scale ).to( {
       x: 1,
       y: 1 
    }, 350 ).easing( TWEEN.Easing.Bounce.EaseOut).start();
}

Finally I call the functions in the mouse function.

if (intersects[0].object != INTERSECTED)
   scaleUp();
else
   scaleDown();

That's all. Very useful for UIs I think.


Solution

  • Using the tween library (found in three.js/examples/js/libs/tween.min.js) you can animate the scale like so:

    function setupObjectScaleAnimation( object, source, target, duration, delay, easing )
    {
        var l_delay = ( delay !== undefined ) ? delay : 0;
        var l_easing = ( easing !== undefined ) ? easing : TWEEN.Easing.Linear.None;
    
        new TWEEN.Tween( source )
            .to( target, duration )
            .delay( l_delay )
            .easing( l_easing )
            .onUpdate( function() { object.scale.copy( source ); } )
            .start();
    }
    
    and then call it like so:
    
    setupObjectScaleAnimation( INTERSECTED,
        { x: 1, y: 1, z: 1 }, { x: 2, y: 2, z: 2 },
        2000, 500, TWEEN.Easing.Linear.None );
    

    Or if you want to use the render loop:

    clock = new THREE.Clock();
    time = clock.getElapsedTime();
    
    INSPECTED.scale.x = time / 1000;
    INSPECTED.scale.y = time / 1000;
    

    You can change the divisor based on how fast or slow you want the animation to happen.