JSFiddle - React, Tailwind, and code Playground

by Michael Prosser

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://aninoob.com/noobshapes/js/noob.shapes.js"></script>
<link rel="stylesheet" href="https://aninoob.com/noobshapes/css/noob.shapes.css">
<div class="stage">

</div>

<button onclick="$('.duck').addClass('duckglide');$('.duck').removeClass('duckidle');$('.duck').removeClass('ducktakeoff');">GLIDE</button>
<button onclick="$('.duck').removeClass('duckglide');$('.duck').removeClass('duckidle');$('.duck').addClass('ducktakeoff');">TAKE OFF</button>
<button onclick="$('.duck').removeClass('duckglide');$('.duck').addClass('duckidle');$('.duck').removeClass('ducktakeoff');">IDLE</button>

CSS

html{
  height:100%;
}
body{
  height:100%;
  perspective:500px;
  perspective-origin:25% 25%;
}
.stage{
  transform-style:preserve-3d;
  position:absolute;
  left:50%;
  top:50%;
  width:0px;
  height:0px;
  /*animation: staging infinite 5s;*/
}
.duck-ai{
  transform-style:preserve-3d;
  position:absolute;
  left:50%;
  top:50%;
  width:0px;
  height:0px;
  /*animation: staging infinite 5s;*/
}
@keyframes staging{
  0% { transform: rotateY(0deg) }
  100% { transform: rotateY(360deg) }
}
.duck{
  transform: translateY(0px) rotateY(180deg) rotateX(0deg) !important;
  transition:all 0s !important;
}
.duck.duckglide{
  animation: duckglide infinite 1s 300ms !important;
}
@keyframes duckglide{
  0% { transform: translateY(0px) rotateY(180deg) rotateX(0deg) }
  50% { transform: translateY(-10px) rotateY(180deg) rotateX(10deg) }
  100% { transform: translateY(0px) rotateY(180deg) rotateX(0deg) }
}
.duck.duckglide>.duck-left-wing{
  animation: duckflappingleft infinite 1s !important;
  transform-origin: -20px 0px 0px !important;
}
@keyframes duckflappingleft{
  0% { transform: translateX(40px) skewY(-30deg) }
  50% { transform: translateX(40px) skewY(30deg) }
  100% { transform: translateX(40px) skewY(-30deg) }
}
.duck.duckglide>.duck-right-wing{
  animation: duckflappingright infinite 1s !important;
  transform-origin: 20px 0px 0px !important;
}
@keyframes duckflappingright{
  0% { transform: translateX(-40px) skewY(30deg) }
  50% { transform: translateX(-40px) skewY(-30deg) }
  100% { transform: translateX(-40px) skewY(30deg) }
}
.duck.duckglide>.duck-beak-bottom{
  animation: duckbeakbottom infinite 1s !important;
  transform-origin: 0px -2px 9px !important;
}
@keyframes duckbeakbottom{
  0% { transform: translateY(6px) translateZ(61px) rotateY(180deg) rotateX(0deg) }
  50% { transform: translateY(6px) translateZ(61px) rotateY(180deg) rotateX(19deg) }
  100% { transform: translateY(6px) translateZ(61px) rotateY(180deg) rotateX(0deg) }
}



.duck.ducktakeoff{
 ...

JavaScript

noobshapes.init($('.stage'),$('body'));

var ducks_ai = {

	element: null,
	
  position: { x: 0, y: 0, z: 500, rx: 0, ry: 0, rz: 0, sx: 1, sy: 1, sz: 1 },
  
  speed: 5,
  state: 'duckglide',
  direction: { rx: 10, ry: 10, rz: 40 },
  
  setState: function(newstate){
  
  	var cached_this = this;
    
    cached_this.element.find('>.duck').removeClass('duckglide');
    cached_this.element.find('>.duck').removeClass('ducktakeoff');
    cached_this.element.find('>.duck').removeClass('duckidle');
    cached_this.element.find('>.duck').addClass(newstate);
    
  },
  
  onStart: function(){
  
  	var cached_this = this;
    
    // start creation of duck
    
    noobshape_0 = noobshapes.create('cube',{"class":"duck...