title: Animated random image spinner
body: <p>Not the best title, I admit, but I'll try to compensate explaining.</p>
  
  <p>I would like to create a gallery, similar to a Carousel (but not quite), in which its images are quickly navigated automatically after clicking an element, like a spinner.</p>
  
  <p>All images are randomized by the server-side language and loaded in the DOM, inline, having only the first one visible and rest hidden. My idea was to use CSS animations to spin them to the left and it worked very nicely, even though I couldn't reproduce it in <a href="https://jsfiddle.net/ct9vvatv/" rel="nofollow noreferrer">the Fiddle</a>.</p>
  
  <p>Since I'm forced to duplicate the code, here it goes:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>$( document ).ready( function() {
  
    $( '#randomizer .wheel' ).on( 'click', function() {
  
        /**
         * @internal
         *
         * 70 is the upper bound of the range and 50 the lower bound
         *
         * @see https://stackoverflow.com/a/7228322/5613506
         */
        var time = Math.floor( Math.random() * ( 70 - 50 + 1 ) + 50 );
  
        var selector = $( '#randomizer .wheel div, #images &gt; div' );
  
        selector.addClass( 'spinning' )
                .css( '--spinner-animation-time', time + 'ms' )
                .on( 'animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd', function() {
                    selector.removeClass( 'spinning' )
                });
    });
  });</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>:root {
    --spinner-animation-time: 200ms;
  }
  
  .row {
      overflow: hidden;
      width: 33.333333%;
  }
  
  #randomizer {
      height: 12vh;
      margin-top: 0.1vh;
      position: relative;
      z-index: 4;
  }
  
      #randomizer .wheel {
          -webkit-border-top-left-radius: 0;
          -webkit-border-top-right-radius: 0;
          -moz-border-radius-topleft: 0;
          -moz-border-radius-topright: 0;
          border-top-left-radius: 0;
          border-top-right-radius: 0;
          border-top: none !important;
          padding: 2vh 0 1.5vh 0;
      }
  
      #randomizer .wheel &gt; div {
          height: 8.4vh;
          overflow: hidden;
          position: relative;
          -webkit-transform: translate3d( 0, 0, 0 );  /* Chrome, Opera 15+, Safari 3.1+ */
              -ms-transform: translate3d( 0, 0, 0 );  /* IE 9 */
                  transform: translate3d( 0, 0, 0 );  /* Firefox 16+, IE 10+, Opera */
          width: 95vw; /** 4 white blocks with their black borders visible */
      }
  
          #randomizer .wheel img {
              cursor: pointer;
              object-fit: cover;
              position: relative;
              top: 0.1vh;
              width: 55vw;
          }
  
              /*#randomizer .wheel img:hover {
                  animation: randomizer 100ms 10;
              }*/
              
  #images {
    align-items: center;
    border: 1px solid #000;
    display: inline-flex;
    justify-content: center;
    height: 300px;
    margin-top: 6vh;
    position: absolute;
    width: 450px;
    z-index: 3;
  }
  
  #images div {
    display: inline-flex;
    height: 100%;
    overflow: hidden;
    width: 100%;
  }
  
      #images img {
        /*clip-path: inset( 9.2vh 1.2vw 24.5vh 4.7vw );*/
        /*transform: scale( 0.8, 1 );*/
        height: 100%;
        width: 100%;
      }
  
      #images .spinning img {
        animation: randomizer var(--spinner-animation-time) 25;
      }
  
  #randomizer .wheel &gt; div.spinning img {
    animation: randomizer var(--spinner-animation-time) 25;
  }
  
  @keyframes randomizer {
    100% {
      -webkit-transform: translateX( -33.3333% );  /* Chrome, Opera 15+, Safari 3.1+ */
          -ms-transform: translateX( -33.3333% );  /* IE 9 */
              transform: translateX( -33.3333% );  /* Firefox 16+, IE 10+, Opera */
    }
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;div id="images"&gt;
      &lt;div&gt;
          &lt;img src="http://brightcove04.o.brightcove.com/1362235914001/1362235914001_4806146059001_video-still-for-video-4805957335001.jpg?pubId=1362235914001" /&gt;
          &lt;img src="https://oup.useremarkable.com/production/images/uploads/3315/original/email-symbol-thumbnail.jpg?1473424084" /&gt;
          &lt;img src="https://i.ytimg.com/vi/xYrRq5U5kcc/maxresdefault.jpg" /&gt;
          &lt;img src="https://oup.useremarkable.com/production/images/uploads/2998/original/plus-sign-thumbnail.jpg?1471959737" /&gt;
          &lt;img src="https://oup.useremarkable.com/production/images/uploads/2816/original/crossword-thumbnail.jpg?1471959676" /&gt;
      &lt;/div&gt;
  &lt;/div&gt;
    
  &lt;div class="row" id="randomizer"&gt;
  
      &lt;div class="wheel"&gt;
          &lt;div&gt;
              &lt;img src="https://i.imgur.com/ikch8mX.jpg" /&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Even though it's bugged <strong>only in this demo</strong> (let's emphasize that), probably because I couldn't extract everything I've done in my real code, I believe it should suffice for you to understand the concept.</p>
  
  <p>However, this is only a simple animation, it goes from 0% to 100% and it's done. Even though the images' list is shuffled, the animation will start showing the first image and end showing the first image.</p>
  
  <p>And I would like to really spin all images, stopping randomly at one of them. From the "chosen" image I could read some data attributes to use as AJAX parameters, but that's beside the point.</p>
  
  <p>I tried to generate a random animation speed value, with something I learned today (CSS variables) but in the end, all I've got was a way to simulate the strength a person would be tapping the spinner, harder or lighter, spinning for more or less time.</p>
  
  <p>How could I accomplish that?</p>