Moonstone Spinner Demo

Illustrates the implementation of a GPU-accelerated spinner, which uses transforms and animation keyframes to reduce JavaScript CPU thread usage.

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/1.7.0/less.min.js"></script>
<div class="some-arbitrary-container">
	Spinner:
	<div class="moon-spinner">
		<div class="moon-spinner-ball moon-spinner-ball1"></div>
		<div class="moon-spinner-ball moon-spinner-ball2"></div>
		<div class="moon-spinner-ball moon-spinner-ball3"></div>
	</div><br>
	No Background:
	<div class="moon-spinner moon-spinner-custom-background">
		<div class="moon-spinner-ball moon-spinner-ball1"></div>
		<div class="moon-spinner-ball moon-spinner-ball2"></div>
		<div class="moon-spinner-ball moon-spinner-ball3"></div>
	</div>
</div>
<div class="some-other-arbitrary-container">
	With Content:<br>
	<div class="moon-spinner">
		<div class="moon-spinner-ball-decorator">
			<div class="moon-spinner-ball moon-spinner-ball1"></div>
			<div class="moon-spinner-ball moon-spinner-ball2"></div>
			<div class="moon-spinner-ball moon-spinner-ball3"></div>
		</div>
		<div class="moon-spinner-text">Loading...</div>
	</div>
</div>
<div class="a-final-arbitrary-container">
	Huge Spinner: <small><em>(For serious waiting)</em></small>
	<div class="moon-spinner">
		<div class="moon-spinner-ball moon-spinner-ball1"></div>
		<div class="moon-spinner-ball moon-spinner-ball2"></div>
		<div class="moon-spinner-ball moon-spinner-ball3"></div>
	</div>
</div>

CSS

///// Spinner Variables /////
// Very slow
/*@moon-spinner-time: 20s;*/
// Normal Speed
@moon-spinner-time: 1.83s;

// Height and width of each ball
@moon-spinner-ball-height: 15%;
@moon-spinner-ball-width: @moon-spinner-ball-height;
// Distance each ball is from the center
@moon-spinner-ball-distance: 20%;
// Width of each ball, measured in degrees
@moon-spinner-ball-angle: 15deg;

/* Fun - Weird Clock*/
/*
@moon-spinner-ball-width: 5%;
@moon-spinner-ball-distance: 0%;
@moon-spinner-ball-angle: 40deg;
*/

@-webkit-keyframes spinBall {
  0%,		{ -webkit-transform: rotateZ(@moon-spinner-ball-angle); }
  /* Slow down toward the top */
  15%		{ -webkit-transform: rotateZ(160deg); }
  25%		{ -webkit-transform: rotateZ(200deg); }
  30%		{ -webkit-transform: rotateZ(225deg); }
  /* Speed back up as the ball falls */
  /* Impact at last ball */
  34%		{ -webkit-transform: rotateZ(360 - (@moon-spinner-ball-angle * 3)); }
  39%, 67%	{ -webkit-transform: rotateZ(360 - @moon-spinner-ball-angle); }
  72%		{ -webkit-transform: rotateZ(360 + @moon-spinner-ball-angle + 10); }
  79%, 100%	{ -webkit-transform: rotateZ(360 + @moon-spinner-ball-angle); }
}

@-webkit-keyframes spinBallAll {
  0%	{ -webkit-transform: rotateZ(17deg); }
  100%	{ -webkit-transform: rotateZ(377deg); }
}

body {
	color: #eee;
	background-color: #6289A5;
	font-size: 36px;
	padding: 1em 10%;
}

#info {
	font-size: 24px;
	border-radius: 1em;
	margin: 1em 5ex 0;
	padding: 0.5em;
	color: #000;
	background-color: rgba(255,255,255, 0.5);
}

.some-arbitrary-container,
.some-other-arbitrary-container,
.a-final-arbitrary-container {
	margin: 50px;
	font-size: 36px;
	display: inline-block;
	vertical-align: top;
}
.some-arbitrary-container {
	font-size: 36px;
}
.a-final-arbitrary-container .moon-spinner {
	font-size: 128px;
}
.some-other-arbitrary-container {
	font-size: 36px;
}

.moon-spinner {
	width: 2em;
	height: 2em;
	position: relative;
	background-color: rgba(102, 102, 102, 0.75);
	border-radius:...

JavaScript

/*

Illustrates the implementation of a GPU-accelerated spinner, 
which uses transforms and animation keyframes to reduce 
JavaScript CPU thread usage.

    Author's Twitter: @blakecode


"While we are waiting for JSFiddle to support LESS integration
I figured I would get a work around sorted so I can still 
write it in here"
    - Twitter: @aaronlayton
*/

// Step 1: Select the style element and change it to text/less
$('head style[type="text/css"]').attr('type', 'text/less');

// Step 2: Tell LESS to refresh the styles
less.refreshStyles();

/* 
    You could put this as a oneliner and use it as a shim for JSFiddle

    (function(){ $('head style[type="text/css"]').attr('type', 'text/less');less.refreshStyles(); })()
    
*/