<link href='//fonts.googleapis.com/css?family=Signika+Negative:300,400,700' rel='stylesheet' type='text/css'>

<div id="demo">
  
  <div id="field">
    <p>Notice that scale, rotation, and position can be animated independently using different eases and partially overlapping start/end times (impossible with CSS animations).</p>
    <div id="box">Independent transforms</div>
    
    <div id="controls">
      <button id="rotation">Spin rotation</button>
      <button id="rotationX">Spin rotationX</button>
      <button id="rotationY">Spin rotationY</button>
      <button id="move">wander (position)</button>
    </div>
  </div>
</div>
body {
  background-color:black;
  margin: 0;
  padding: 0;
  font-family: Signika Negative, sans-serif;
  font-weight: 300;
}
html, body {
  height: 100%;
}
#demo {
  display:table;
  width:100%;
  height:100%;
}
#field {
  position:relative;
  display:table-cell;
  height: 100%;
  	overflow:hidden;
  text-align: center;
  vertical-align: middle;
}
#box {
  color: black;
  font-size:24px;
  padding: 10px 16px;
  border: 2px solid black;
  background: #9af600;
  background: linear-gradient(to bottom, #9af600 0%,#71B200 100%);
  display:inline-block;
  border-radius: 10px;
}
#field p {
  position: absolute;
  color: #999;
  top: 0px;
  padding: 0px 20px;
  text-align: left;
  z-index: -1000;
}
#controls {
  position:absolute;
  color: #999;
  width: 100%;
  bottom: 20px;
  text-align: center;
}
button {
  margin: 2px;
}
var $box = $("#box"),
    $field = $("#field"),
    rotation = 0,
    rotationX = 0, 
    rotationY = 0,
    wanderTween, ignoreRollovers;

//set a perspective on the container so we can see the 3D-ness
gsap.set($field, {perspective: 500});
//offset the origin on the z-axis to make the spins more interesting.
gsap.set($box, {transformOrigin:"center center -150px"});
//pulsate the box using scaleX and scaleY
gsap.to($box, {duration: 1.2, scaleX:0.8, scaleY:0.8, force3D:true, yoyo:true, repeat:-1, ease: "power1.inOut"});

//on rollover, rotate the box but to avoid excessive spinning, we'll desensitize rollovers during the first second of animation.
$box.hover(function() {
  if (!ignoreRollovers) {
    rotation += 360;
    ignoreRollovers = true;
    TweenLite.to($box, 2, {rotation:rotation, ease:Elastic.easeOut});
    TweenLite.delayedCall(1, function() {
      ignoreRollovers = false;
    });
  }
}, function() {});

$("#rotation").click(function() {
  rotation += 360;
  gsap.to($box, {duration:2, rotation:rotation, ease:"elastic"});
});

$("#rotationX").click(function() {
  rotationX += 360;
  gsap.to($box, {duration:2, rotationX:rotationX, ease:"power2"});
});

$("#rotationY").click(function() {
  rotationY += 360;
  gsap.to($box, {duration: 1, rotationY:rotationY, ease:"power1.inOut"});
});

$("#move").click(function() {
  if (wanderTween) {
    wanderTween.kill();
    wanderTween = null;
    gsap.to($box, {duration:0.5, x:0, y:0});
  } else {
    wander();
  }
});

//randomly choose a place on the screen and animate there, then do it again, and again.
function wander() {
  var x = (($field.width() - $box.width()) / 2) * (Math.random() * 1.8 - 0.9),
      y = (($field.height() - $box.height()) / 2) * (Math.random() * 1.4 - 0.7);
  wanderTween = gsap.to($box, {duration: 2.5, x:x, y:y, ease:"power1.inOut", onComplete:wander});
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
  2. https://cdn.jsdelivr.net/npm/gsap@3.7.1/dist/gsap.min.js