Skip to content
Advertisement

Zoom image without using scale

General Info
Working on creating my own carousel. The idea is that the image zooms in slowly at the start of each carousel “page”.

The Problem To achieve the result I’m looking for, all I have to do is change the scale of the background image using a transition. Simply wrap it in a container with overflow:hidden and it works. The problem is that the next carousel page needs to start its image “zoomed out”. So the scale needs to be set to 1 again. However, since the CSS class has the transition, zooming out isn’t instant.

The solution to that problem should be to simply remove the class from the element. Then change the scale and finally add the class back in. However, for some reason, that doesn’t seem to work.

Another issue is that scale seems to have a very bad browser support at the moment: https://caniuse.com/?search=scale

Example code

let scaled = false;

const test = document.getElementById("test");

window.addEventListener("click", function()
{
  
  if(scaled)
  {
    // Remove the class
    test.classList.remove("foo");
    
    scaled = false;
    
    // Reset the scale
    test.style.transform = "scale(1)";
    
    // Add class back in making sure the animation should be updated
    window.requestAnimationFrame(() => {
      test.classList.add("foo");
    });
  }
  else
  {
    // Leave the animation running
    scaled = true;
    test.style.transform = "scale(0.5)";
  }
  
  
})
.foo {
  width: 500px;
  height: 500px;
  background: blue;
  transition: transform 2s;
}
<div id="test" class="foo">
</div>

You’ll have to run the above snipped in Firefox or Safari as scale is not supported in other browsers at this time.

On the first click, the animation plays as it should. On the second click, the animation still plays while it shouldn’t as the class has been removed.

My questions
Is there an alternative way to achieve the same effect? (so don’t use scale at all) Why is it playing the animation anyway despite the class being removed?

Advertisement

Answer

The problem based on Event Loop. You can try this solution with width if you like, but actually not sure that cover you needs.

const test = document.getElementById("test");

window.addEventListener("click", function()
{
      test.style.transition = 'none'
      test.style.width = '100%';
      
      
      window.requestAnimationFrame(() => {
        test.style.width = "50%";
        test.style.transition = 'width 2s'
      });
})
.foo {
  width: 500px;
  height: auto;
  background: blue;
}
<img src="https://images.freeimages.com/images/large-previews/76e/abstract-1-1174741.jpg" class="foo" id="test"/>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement