Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ja-k-e/df2f3c33b7e6b2e769ca to your computer and use it in GitHub Desktop.

Select an option

Save ja-k-e/df2f3c33b7e6b2e769ca to your computer and use it in GitHub Desktop.
Rotating Anonymously-Sided Polygons Sass mixin
.container
<!-- "start" and "end" variables in scss -->
- (3..12).each do |i|
%div{:class => "stage-viewport s#{i}"}
.stage
.spinner
- (1..i).each do
.facade

Rotating Anonymously-Sided Polygons Sass mixin

Originally constructed a similar plugin with LESS for a project here. Switched over to Sass for fun.

A Pen by Jake Albaugh on CodePen.

License.

/*
* the following vars get plugged into the mixin.
*/
// start and end values of .facade children count
$start: 3; $end: 12;
// width and height of facades
$width: 40px; $height: 60px;
// spacing between stage-viewports / 2 (half each side)
$spacing: 8px / 2;
// speed of the animation
$speed: 4s;
body {
background: #222;
margin: 0;
}
.container {
position: absolute;
top: 50%; left: 50%;
transform: translateY(-50%) translateX(-50%);
width: 100%;
text-align: center;
min-width: (
($width * 1.125) +
($spacing * 2)
) * ($end - $start + 2);
}
/*
* mixin takes face count, width, height,
* and show_viewport (boolean)
*/
@mixin stage-viewport(
$face_count: 3,
$size_w: 40px,
$size_h: 40px,
$show_viewport: false,
$speed: 6s
) {
$perspective_factor: $size_w * 1.5;
/*
* only really used for this code, may not be necessary in development.
*/
display: inline-block;
width: $size_w * 1.125;
height: $size_h * 1.125;
position: relative;
// uncomment overflow to see cropped result
//overflow: hidden;
margin: 0px $spacing;
@if ($show_viewport == true) {
&:after {
// viewport outline
content: '';
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
box-shadow: inset 0px 0px 0px 2px rgba(255,255,255,0.3);
}
}
.stage {
perspective: $perspective_factor * $face_count;
display: inline-block;
width: $size_w;
height: $size_h;
position: absolute;
top: 50%; left: 50%;
perspective-origin: 50% 50%;
transform: translateY(-50%) translateX(-50%);
}
/*
* spinning them.
*/
.spinner {
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: $speed;
transform-style: preserve-3d;
transform-origin: 50% 50%;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
.facade {
display: block;
position: absolute;
width: $size_w;
height: $size_h;
&::after {
// numbers
color: rgba(255,255,255,0.6);
line-height: 1;
font-size: $size_h/4;
font-weight: 200;
font-family: helvetica, arial, sans-serif;
position: absolute;
top: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%);
}
/*
* translateZ = apothem
* distance from polygon center to facade center
* apothem = facade_height / ( 2 * tangent(180 / facade_count) )
*/
$apothem: ($size_h / ( 2 * tan(180deg / $face_count) ));
@for $i from 1 through $face_count {
$ratio: $i / $face_count;
$zero_ratio: ($i - 1) / $face_count;
$x: $zero_ratio * 360;
&:nth-child(#{$i}) {
transform: rotateX($x+deg) translateZ($apothem);
background-color: hsla((360 * $zero_ratio), 50%, 50%, 0.8);
&::after {
content: '#{$i}';
}
}
}
}
}
@for $i from $start through $end {
.stage-viewport.s#{$i} {
@include stage-viewport(
/*
* OPTIONS:
* $face_count, $size_w, $size_h, $show_viewport, $speed
*/
$face_count: $i,
$size_w: $width,
$size_h: $height,
$show_viewport: false,
$speed: $speed
);
}
}
@keyframes spinner {
0% { transform: rotateX(0deg); }
20% { transform: rotateX(0deg); }
100% { transform: rotateX(-360deg); }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment