Skip to content

Instantly share code, notes, and snippets.

@cange
Last active August 29, 2015 14:25
Show Gist options
  • Save cange/cbc028595bd5c5a49497 to your computer and use it in GitHub Desktop.
Save cange/cbc028595bd5c5a49497 to your computer and use it in GitHub Desktop.
CSS Spinning 3D cube for loading sequence
//
// Variables
// -------------------------------------
$blue: #00a3de;
$blue-light: #7fd1ee;
$blue-lightest: #e5f6fc;
$grey: #b5babd;
$side-color-a: $grey;
$side-color-b: $grey;
$side-color-c: $grey;
$ease-in-out: cubic-bezier(0.65,0.05,0.36,1);
$face-size: 100px;
$face-center: $face-size / 2;
$scale-factor: .6;
$pulsating-duration: 1.4s;
$pulsating-factor-blow: 1.5;
$pulsating-factor-subtle: 1.05;
$alpha-pulse: .5;
//
// Frames
// -------------------------------------
@-webkit-keyframes pulsating-blow {
from { -webkit-transform: scale(0, 0); }
80% {
-webkit-transform: scale($scale-factor * $pulsating-factor-blow, $scale-factor * $pulsating-factor-blow);
opacity: 0;
}
to {
-webkit-transform: scale($scale-factor * $pulsating-factor-blow, $scale-factor * $pulsating-factor-blow);
opacity: 0;
}
}
@keyframes pulsating-blow {
from { transform: scale(0, 0); }
80% {
transform: scale($scale-factor * $pulsating-factor-blow, $scale-factor * $pulsating-factor-blow);
opacity: .05;
}
to {
transform: scale($scale-factor * $pulsating-factor-blow, $scale-factor * $pulsating-factor-blow);
opacity: 0;
}
}
@-webkit-keyframes pulsating-subtle {
40% {
-webkit-transform: scale($scale-factor, $scale-factor);
opacity: $alpha-pulse;
}
45% {
-webkit-transform: scale($scale-factor * $pulsating-factor-subtle, $scale-factor * $pulsating-factor-subtle);
opacity: .8;
}
to {
-webkit-transform: scale($scale-factor, $scale-factor);
opacity: $alpha-pulse;
}
}
@keyframes pulsating-subtle {
40% {
transform: scale($scale-factor, $scale-factor);
opacity: $alpha-pulse;
}
45% {
transform: scale($scale-factor * $pulsating-factor-subtle, $scale-factor * $pulsating-factor-subtle);
opacity: .8;
}
to {
transform: scale($scale-factor, $scale-factor);
opacity: $alpha-pulse;
}
}
@keyframes coloring-pulse {
40% { filter: grayscale(100%); }
45% { filter: grayscale(0%); }
to { filter: grayscale(100%); }
}
// -------------------------
@-webkit-keyframes spinning {
from { -webkit-transform: rotateX(-45deg) rotateY(-45deg); }
25% { -webkit-transform: rotateX(45deg) rotateY(45deg); }
50% { -webkit-transform: rotateX(135deg) rotateY(135deg); }
75% { -webkit-transform: rotateX(225deg) rotateY(225deg); }
100% { -webkit-transform: rotateX(315deg) rotateY(315deg); }
}
@keyframes spinning {
from { transform: rotateX(-45deg) rotateY(-45deg); }
25% { transform: rotateX(45deg) rotateY(45deg); }
50% { transform: rotateX(135deg) rotateY(135deg); }
75% { transform: rotateX(225deg) rotateY(225deg); }
100% { transform: rotateX(315deg) rotateY(315deg); }
}
@-webkit-keyframes coloring-a {
from { background-color: $grey; }
50% { background-color: $blue; }
to { background-color: $grey; }
}
@-webkit-keyframes coloring-b {
from { background-color: $grey; }
50% { background-color: $blue-light; }
to { background-color: $grey; }
}
@-webkit-keyframes coloring-c {
from { background-color: $grey; }
50% { background-color: $blue-lightest; }
to { background-color: $grey; }
}
@keyframes coloring-a {
from { background-color: $grey; }
50% { background-color: $blue; }
to { background-color: $grey; }
}
@keyframes coloring-b {
from { background-color: $grey; }
50% { background-color: $blue-light; }
to { background-color: $grey; }
}
@keyframes coloring-c {
from { background-color: $grey; }
50% { background-color: $blue-lightest; }
to { background-color: $grey; }
}
// mixins
// -------------------------------------
@mixin animation($definition) {
-webkit-animation: $definition;
animation: $definition;
}
@mixin animation-play-state($state) {
-webkit-animation-play-state: $state;
animation-play-state: $state;
}
@mixin transform($rule) {
-webkit-transform: $rule;
transform: $rule;
}
// animation
// -------------------------------------
.ani-pulse-blow {
@include animation(pulsating-blow $pulsating-duration infinite $ease-in-out);
@include animation-play-state(paused);
}
.ani-pulse-subtle {
@include animation(pulsating-subtle $pulsating-duration infinite $ease-in-out);
@include animation-play-state(paused);
margin-top: -100px;
}
.ani-color {
@each $group in a, b, c {
.face-group-#{$group} {
@include animation(coloring-#{$group} 1.5s infinite $ease-in-out);
@include animation-play-state(paused);
}
}
}
.ani-color-pulse {
@each $group in a, b, c {
.face-group-#{$group} {
@include animation(coloring-pulse $pulsating-duration infinite $ease-in-out);
}
}
}
// events
// -------------------------------------
.ani-spinning-action:active + .spinner {
.ani-color {
.face-group-a,
.face-group-b,
.face-group-c {
@include animation-play-state(running);
}
}
.ani-3d {
@include animation-play-state(running);
}
}
.ani-pulse-action:active {
+ .ani-pulse-blow {
@include animation-play-state(running);
}
~ .ani-pulse-subtle {
@include animation-play-state(running);
}
~ .ani-color-pulse {
.face-group-a,
.face-group-b,
.face-group-c {
//@include animation-play-state(running);
}
}
}
.ani-3d {
@include animation(spinning 3s infinite $ease-in-out);
@include animation-play-state(paused);
}
// shapes
// -------------------------------------
body {
font-family: sans-serif;
}
.spinner {
perspective: 0px;
perspective-origin: 100% 100%;
@include transform(scale($scale-factor, $scale-factor));
&:hover {
.axis {
display: block;
}
.face {
opacity: 0.1;
&:before {
color: white;
content: attr(data-axis);
font-size: $face-size * .57;
height: 100%;
line-height: 1.8;
position: absolute;
text-align: center;
width: 100%;
}
&:hover {
opacity: 0.9;
}
}
}
}
.spinner-inner {
position: relative;
margin: 0 auto;
height: $face-size;
@include transform(rotateX(-45deg) rotateY(-45deg));
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
will-change: transform;
width: $face-size;
}
.spinner-pulse {
opacity: $alpha-pulse;
}
.face {
background-color: $grey;
//box-shadow: 0 0 0 2px white inset;
position: absolute;
height: $face-size;
width: $face-size;
}
.axis {
display: none;
opacity: 0.5;
position: relative;
text-transform: uppercase;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
height: 0;
width: 20em;
&:before {
content: '';
display: block;
content: '+ ' attr(data-axis);
position: absolute;
}
&:after {
content: '- ' attr(data-axis);
position: absolute;
right: 0;
}
}
.a {
@include transform(translateZ($face-center));
}
.b {
@include transform(rotateY(90deg) translateZ($face-center));
}
.c {
@include transform(rotateX(90deg) translateZ($face-center));
}
.d {
@include transform(rotateY(180deg) translateZ($face-center));
}
.e {
@include transform(rotateY(-90deg) translateZ($face-center));
}
.f {
@include transform(rotateX(-90deg) translateZ($face-center) rotate(180deg));
}
.x {
box-shadow: 0 0 0 1px green;
@include transform(rotateY(-180deg) translateX(110px) translateY($face-center));
&:before,
&:after {
@include transform(rotateZ(180deg));
}
}
.y {
box-shadow: 0 0 0 1px red;
@include transform(rotateZ(-90deg) translateY(-($face-size + 10px)) translatex(-$face-center));
&:before,
&:after {
@include transform(rotateZ(90deg) translateX(-30px));
}
}
.z {
box-shadow: 0 0 0 1px blue;
@include transform(rotateY(90deg) translateZ(-($face-size + 10px)) translateY($face-center));
}
<h3>Spinning 3D cube</h3>
<button type="button" class="ani-spinning-action">play</button>
<div class="spinner">
<div class="spinner-inner ani-3d ani-color">
<div class="face a face-group-a" data-axis="a"></div>
<div class="face b face-group-b" data-axis="b"></div>
<div class="face c face-group-c" data-axis="c"></div>
<div class="face d face-group-a" data-axis="d"></div>
<div class="face e face-group-b" data-axis="e"></div>
<div class="face f face-group-c" data-axis="f"></div>
<div class="axis x" data-axis="x"></div>
<div class="axis y" data-axis="y"></div>
<div class="axis z" data-axis="z"></div>
</div>
</div>
<br>
<br>
<h3>Pulsing 3D cube</h3>
<button type="button" class="ani-pulse-action">play</button>
<div class="spinner spinner-pulse ani-pulse-blow">
<div class="spinner-inner">
<div class="face a face-group-a" data-ax-subtle="a"></div>
<div class="face b face-group-b" data-axis="b"></div>
<div class="face c face-group-c" data-axis="c"></div>
</div>
</div>
<div class="spinner spinner-pulse ani-pulse-subtle ani-color-pulse">
<div class="spinner-inner">
<div class="face a face-group-a" data-axis="a"></div>
<div class="face b face-group-b" data-axis="b"></div>
<div class="face c face-group-c" data-axis="c"></div>
</div>
</div>
name: CSS Spinning 3D cube
description: CSS Spinning 3D cube for loading sequence
authors:
- Christian Angermann
normalize_css: no
wrap: b
panel_css: 1
@cange
Copy link
Author

cange commented Jul 26, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment