0

I want shrink poster width size, because i want to create illusion of depth before new element is shown above.

<!DOCTYPE html>
<html>
 <head>
<style type="text/css">

body{
    margin: 0 0 10% 0;
    padding: 0;
    background-color: #191919;
}

.movie{
  position: relative;
  margin: 10% auto 0 auto;
  width: 80%;
  border-radius: 10px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.66);
  transition: .5s linear;
}

.poster{
  display: block;
  width: 100%;
  border-radius: 10px;
}

</style>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(document).ready(function(){

  $(".movie").click(function(){
    $(".movie").animate({width: "70%"});
  });

})

</script>
 </head>
 <body>
  <div class="main_page">
   <div class="movie" id="602147">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/l13mt3oHErSkkqJbN1bjzgtK0Vq.jpg"/>
   </div>
   <div class="movie" id="576156">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/5jdLnvALCpK1NkeQU1z4YvOe2dZ.jpg"/>
   </div>
   <div class="movie" id="385103">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/zG2l9Svw4PTldWJAzC171Y3d6G8.jpg"/>
   </div>
   <div class="movie" id="686245">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/niyXFhGIk4W2WTcX2Eod8vx2Mfe.jpg"/>
   </div>
   <div class="movie" id="582596">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/A2YlIrzypvhS3vTFMcDkG3xLvac.jpg"/>
   </div>
   <div class="movie" id="618344">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/c01Y4suApJ1Wic2xLmaq1QYcfoZ.jpg"/>
   </div>
   <div class="movie" id="536517">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/6btICrn3RsbtxZCthtb0MsR9lcq.jpg"/>
   </div>
  </div>
 </body>
</html>

Here is my demo on jsfiddle

When i click on 1st poster i get nice image shrink. Problem is when i click on posters that are far from the top of the page, all posters then are moved to the top on click and shrink animation is not the same like with first poster. How can i achieve shrink animation of first poster on all posters?

imvain2
  • 15,480
  • 1
  • 16
  • 21
  • you should use transform:scale(x) ; here is some tips to make it: https://stackoverflow.com/questions/5462275/animate-element-transform-rotate / https://stackoverflow.com/questions/51248926/transform-doesnt-animate-when-added-class-with-transform-scale1-via-jquery – G-Cyrillus May 22 '20 at 21:40

2 Answers2

1

I would suggest changing some things up. jQuery animate can do animations, but CSS can do it better in terms of performance. So create an animation based on a CSS transition by adding and removing a class.

If you animate the .main_page container, then all the .movie elements will animate as well, creating a simultaneous animation.

In the example below I've used the CSS perspective() function to create artificial depth in your .main_page container. This enables you to move elements over the Z axis (towards and from you) and will give you actual depth as the elements move into the background.

But there is a slight quirk as the animation will move from a fixed point on the page. To counter it I've added an event listener on the window that listens for the scroll event and updates the transform-origin based on the scroll position. Now the animation will always move from your current position on the screen.

To further improve the rendering of the constantly changing transform-origin use the will-change property. This property tells the browser to watch a property's value that will change in the future and should optimize the performance on that property when it changes.

The requestAnimationFrame function will prevent the scroll event to be fired more than 60 times per second so that the scrolling performance will remain the best as it can.

$(document).ready(function() {

  var $mainPage = $('.main_page');

  $('.movie').click(function() {
    $mainPage.toggleClass('animated');
  });
  
  function setTransformOrigin() {
    requestAnimationFrame(function() {
      var scrollHeight = document.scrollingElement.scrollHeight;
      var scrollOffset = document.scrollingElement.scrollTop + (window.innerHeight / 2);
      var origin = (scrollOffset / scrollHeight) * 100;
      $mainPage.css('transform-origin', 'center ' + origin + '%');
    });
  }
  
  $(window).on('scroll', setTransformOrigin);
  
  // Call it immediately to set the first value correctly.
  setTransformOrigin(); 

})
body {
  margin: 0 0 10% 0;
  padding: 0;
  background-color: #191919;
}

.main_page {
  transform: perspective(150px);
  transform-origin: center 5%;
  transition: transform .5s ease-in-out;
  will-change: transform-origin;
}

.main_page.animated {
  transform: perspective(150px) translate3d(0, 0, -150px);
}

.movie {
  position: relative;
  margin: 10vh auto 0 auto;
  height: 90vh;
  width: fit-content;
  border-radius: 10px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.66);
  cursor: pointer;
}

.poster {
  display: block;
  height: 100%;
  border-radius: 10px;
}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>


<div class="main_page">
  <div class="movie" id="602147">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/l13mt3oHErSkkqJbN1bjzgtK0Vq.jpg" />
  </div>
  <div class="movie" id="576156">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/5jdLnvALCpK1NkeQU1z4YvOe2dZ.jpg" />
  </div>
  <div class="movie" id="385103">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/zG2l9Svw4PTldWJAzC171Y3d6G8.jpg" />
  </div>
  <div class="movie" id="686245">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/niyXFhGIk4W2WTcX2Eod8vx2Mfe.jpg" />
  </div>
  <div class="movie" id="582596">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/A2YlIrzypvhS3vTFMcDkG3xLvac.jpg" />
  </div>
  <div class="movie" id="618344">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/c01Y4suApJ1Wic2xLmaq1QYcfoZ.jpg" />
  </div>
  <div class="movie" id="536517">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/6btICrn3RsbtxZCthtb0MsR9lcq.jpg" />
  </div>
</div>
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
  • Thank you, this is exactly what i wanted. Just one question, why can't i update transform-origin value when i click on poster, why is needed to be updated on scroll? I want to have minimum amount of fuctions on web page. Thanks – user10783243 May 22 '20 at 23:36
  • Happy to help! A click will cause a jump in the `transform-origin` position and ruin the illusion. By updating the value constantly you move the `.main_page` layer with the screen, like a parallax effect. Though I would prefer not to use the `scroll` event, but I can't think of a better way to do it than this. – Emiel Zuurbier May 23 '20 at 07:24
0

By changing .movie to this in your animate call, it will ONLY target the poster clicked on NOT all of them.

<!DOCTYPE html>
<html>
 <head>
<style type="text/css">

body{
    margin: 0 0 10% 0;
    padding: 0;
    background-color: #191919;
}

.movie{
  position: relative;
  margin: 10% auto 0 auto;
  width: 80%;
  border-radius: 10px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.66);
  transition: .5s linear;
}

.poster{
  display: block;
  width: 100%;
  border-radius: 10px;
}

</style>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(document).ready(function(){

  $(".movie").click(function(){
    $(this).animate({width: "70%"});
  });

})

</script>
 </head>
 <body>
  <div class="main_page">
   <div class="movie" id="602147">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/l13mt3oHErSkkqJbN1bjzgtK0Vq.jpg"/>
   </div>
   <div class="movie" id="576156">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/5jdLnvALCpK1NkeQU1z4YvOe2dZ.jpg"/>
   </div>
   <div class="movie" id="385103">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/zG2l9Svw4PTldWJAzC171Y3d6G8.jpg"/>
   </div>
   <div class="movie" id="686245">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/niyXFhGIk4W2WTcX2Eod8vx2Mfe.jpg"/>
   </div>
   <div class="movie" id="582596">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/A2YlIrzypvhS3vTFMcDkG3xLvac.jpg"/>
   </div>
   <div class="movie" id="618344">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/c01Y4suApJ1Wic2xLmaq1QYcfoZ.jpg"/>
   </div>
   <div class="movie" id="536517">
    <img class="poster" src="https://image.tmdb.org/t/p/w780/6btICrn3RsbtxZCthtb0MsR9lcq.jpg"/>
   </div>
  </div>
 </body>
</html>
imvain2
  • 15,480
  • 1
  • 16
  • 21
  • Yes i tried that. But sometimes two more partial posters are visible (one above and one bellow of clicked poster) and illusion is not present when only one poster is shrinking – user10783243 May 22 '20 at 21:35