Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <script src='https://cdn.jsdelivr.net/npm/scarletsframe@0.34.0/dist/scarletsframe.min.js'></script>
  <script type="text/javascript">
    // Polyfill the PointerEvent
    (function(){function z(a){document.write('<script src="'+a+'"><\/script>')}
      if(window.PointerEvent === void 0)
        z('https://code.jquery.com/pep/0.4.3/pep.js');
    })();
  </script>
</head>
<body>
  <sf-m name="cards" id="root">
    <div sf-each="x in list" style="transform: translate3d({{x.x}}px, {{x.y}}px, {{x.z}}px);">
      <div
        @mousedown="mouseDown"
        style="
          pointer-events: {{ x.throwed ? 'none' : 'all' }};
          background-image: url({{ x.background }});
          transform: perspective({{ x.perspective }}px) 
                     rotateX({{ x.rotateX }}deg)
                     rotateY({{ x.rotateY }}deg)
                     rotateZ({{ x.rotateZ }}deg)
                     scale({{ x.scale }});">
      </div>
    </div>
  </sf-m>
</body>
</html>
<!-- Inspired by: https://codesandbox.io/embed/j0y0vpz59 -->
 
* {
  box-sizing: border-box;
}
html,
body {
  overscroll-behavior-y: contain;
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  user-select: none;
  font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial,
    sans-serif;
  position: fixed;
  overflow: hidden;
}
sf-m{
  display: block;
}
#root {
  background: lightblue;
  position: fixed;
  overflow: hidden;
  width: 100%;
  height: 100%;
}
#root > div {
  position: absolute;
  width: 100vw;
  height: 100vh;
  will-change: transform;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: 0.7s transform ease-out;
}
#root > div > div {
  background-color: white;
  background-size: auto 85%;
  background-repeat: no-repeat;
  background-position: center center;
  width: 45vh;
  max-width: 300px;
  height: 85vh;
  max-height: 570px;
  will-change: transform;
  transition: 0.2s transform ease-in-out;
  border-radius: 10px;
  box-shadow: 0 12.5px 100px -10px rgba(50, 50, 73, 0.4), 0 10px 10px -10px rgba(50, 50, 73, 0.3);
}
#root > div.dragging {
  transition: 50ms transform linear;
}
 
var $ = sf.$;
var test;
sf.model('cards', function(My){
  // For you to play around on the console :)
  test = My;
  My.list = [
    'https://upload.wikimedia.org/wikipedia/en/f/f5/RWS_Tarot_08_Strength.jpg',
    'https://upload.wikimedia.org/wikipedia/en/5/53/RWS_Tarot_16_Tower.jpg',
    'https://upload.wikimedia.org/wikipedia/en/9/9b/RWS_Tarot_07_Chariot.jpg',
    'https://upload.wikimedia.org/wikipedia/en/d/db/RWS_Tarot_06_Lovers.jpg',
    'https://upload.wikimedia.org/wikipedia/en/thumb/8/88/RWS_Tarot_02_High_Priestess.jpg/690px-RWS_Tarot_02_High_Priestess.jpg',
    'https://upload.wikimedia.org/wikipedia/en/d/de/RWS_Tarot_01_Magician.jpg'
  ];
  
  // Lets convert above list into array of object
  for(var i=0; i < My.list.length; i++){
    My.list[i] = {
      background:My.list[i],
      perspective: 1500,
      rotateX:30,
      rotateY:0,
      rotateZ:Math.ceil(Math.random()*20) - 10,
      scale:1,
      x:0,
      y:i * -4,
      z:0,
      throwed:false // true = disable interaction on card
    };
  }
  
  // Mouse click start
  My.mouseDown = function(ev, item){
    item.scale = 1.15;
    item.rotateZ = 0;
    
    // Save reference of clicked item
    clicked = item;
    
    // Add event listener after user clicking the card
    $(document)
      .on('mousemove', My.mouseMove)
      .once('mouseup', My.mouseUp);
    
    // Add dragging class into the clicked item
    $(My.list.getElement(item)).addClass('dragging');
  }
  
  // Return every card back after some delay
  function collectCard(){
    for(let i=0; i < My.list.length; i++){
      setTimeout(function(){
        var item = My.list[i];
        item.x = 0;
        item.throwed = false;
        item.rotateZ = Math.ceil(Math.random()*20) - 10;
      }, i * 200);
    }
  }
  
  // Throw current clicked card on a direction
  function throwCard(isLeft){
    clicked.x = isLeft ? -750 : 750;
    clicked.throwed = true;
    
    // Collect cards back if this the last card
    if(clicked === My.list[0])
      setTimeout(collectCard, 1000);
  }
  
  // Mouse click ended
  My.mouseUp = function(ev){
    clicked.scale = 1;
    // Throw if user move little fast
    if(Math.abs(speedX) >= 3)
      throwCard(speedX < 0 ? true : false);
    
    // Reset card position if not throwed
    else clicked.x = 0;
    // Remove event listener and the dragging class
    $(document).off('mousemove', My.mouseMove);
    $(My.list.getElement(clicked)).removeClass('dragging');
    // Reset mouse speed detection and remove reference of clicked item
    speedX = 0;
    clicked = null;
  }
  
  var speedX = 0;
  My.mouseMove = function(ev){
    // Move card with this
    clicked.x += ev.movementX;
    speedX = ev.movementX;
  }
});
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
StefansAryapro
0viewers