Search code examples
javascriptjquerycssfrontendgsap

Scale image relative to mouse position from its center


Hello my dear fellows,

I've been trying to recreate the effect: image scales up as the mouse get closer to the center of the image found on https://www.davidwilliambaum.com/

I have been very unsuccessfull so far, as I am not sure how to approach the problem.

I started a codepen with some ideas : https://codepen.io/dindon-studio/pen/RwLwRKM

As you can see I first get the center coordinate of the image, and then i try some dirty formula to scales it up with the mouse distance. But it is very buggy and not convincing at all.

Does anyone got a better approach? Deep thanks for you help!

var mX, mY, distance, element
element = $('.project')

function calculateDistance(elem, mouseX, mouseY) {
return Math.floor(Math.sqrt(Math.pow(mouseX - (elem.offset().left+(elem.width()/2)), 2) + Math.pow(mouseY - (elem.offset().top+(elem.height()/2)), 2))); }

$(document).mousemove(function(e) {  
mX = e.pageX;
mY = e.pageY;
distance = calculateDistance(element, mX, mY);
if (distance< 500 && distance >50){
   var scaling = 1 + (1/distance) *100

  gsap.to(".project", {duration: 0.01, scale: scaling,ease: "power2.in",});

  }
 });

Solution

  • I build off from your codepen and made some adjustments: https://codepen.io/Mookiie/pen/qBPBmNe

    The higher the scalingFactor the closer the mouse needs to be for a size change.

    function calculateCenter(image) {
      var rect1 = image.getBoundingClientRect();
      var x = rect1.left + rect1.width * 0.5;
      var y = rect1.top + rect1.height * 0.5;
      return { x: x, y: y }
    }
    
    function getDistance(x1, y1, x2, y2){
      let y = x2 - x1;
      let x = y2 - y1;
    
      return Math.sqrt(x * x + y * y);
    }
    
    function distanceFromCenter(image, mouseX, mouseY) {
      var imageCenter = calculateCenter(image);
      return getDistance(imageCenter.x, imageCenter.y, mouseX, mouseY)
    }
    
    function adjustImage(image, mX, mY) {
        var distance = distanceFromCenter(image, mX, mY);
    
        const baseScale = 1
        const maxScaling = 1.5;
        const scalingFactor = 1;
        
        const adjustedScaling = maxScaling - ((distance / 1000) * scalingFactor)
        const scaling = adjustedScaling >= baseScale ? adjustedScaling : baseScale
     
        gsap.to(image, {duration: 0.01, scale: scaling, ease: "power2.in",});
    }
    
    
      $(document).mousemove(function(e) {  
        const mX = e.pageX;
        const mY = e.pageY;
        const images = $("img")
        
        images.each(function() {
          adjustImage(this, mX, mY)
        })
    });