My attempt at making something notable for #neonHexagonsWeekend
Ripped off half this code from something I was working on a while ago. We'll see if the original ends up becoming public.
A Pen by Jake Albaugh on CodePen.
My attempt at making something notable for #neonHexagonsWeekend
Ripped off half this code from something I was working on a while ago. We'll see if the original ends up becoming public.
A Pen by Jake Albaugh on CodePen.
| %figure.hex | |
| %span.cube | |
| - (1..6).each do |i| | |
| %span{:class => "side-#{i}"} | |
| %span.alpha | |
| - (1..3).each do |i| | |
| %span{:class => "alpha-#{i}"} |
| // | |
| // variables | |
| // | |
| // color map | |
| $colors: ( | |
| // other global colors | |
| 'global': ( | |
| 1: #888, | |
| 2: #666, | |
| 3: #444, | |
| neon: #ADFF00 | |
| ), | |
| 'alpha': ( | |
| 1: transparentize(#fff, 0.8), | |
| 2: transparentize(#000, 0.8), | |
| 3: transparentize(#000, 0.9) | |
| ) | |
| ); | |
| // size map | |
| $hex-radius: 170px; | |
| $sizes: ( | |
| // triangle side | |
| hex-radius: $hex-radius, | |
| // triangle height | |
| hex-segment-height: 1.73205080757 / 2 * $hex-radius, | |
| // explosion size | |
| explode: $hex-radius / 2 | |
| ); | |
| // rotations map | |
| $rotation-amount: (360deg/6); | |
| $rotations: ( | |
| rotation-1: $rotation-amount * 1 - $rotation-amount, | |
| rotation-2: $rotation-amount * 2 - $rotation-amount, | |
| rotation-3: $rotation-amount * 3 - $rotation-amount, | |
| rotation-4: $rotation-amount * 4 - $rotation-amount, | |
| rotation-5: $rotation-amount * 5 - $rotation-amount, | |
| rotation-6: $rotation-amount * 6 - $rotation-amount | |
| ); | |
| // timing map | |
| $total-time: 6000ms; | |
| $assembly-time: $total-time * 0.55; | |
| $border-time: $total-time * 0.2; | |
| $timings: ( | |
| // side animation time (out of max assembly time) | |
| side-in-increment: ($assembly-time * 0.52) / 6, | |
| // starting times for each hexagon assembly | |
| o-in: $assembly-time * 0.28, | |
| // starting times for each hexagon border color change | |
| o-border-in: $assembly-time, | |
| // border color change time | |
| border: $border-time * 0.5, | |
| // start rotation | |
| alpha-fade-in: $border-time + $assembly-time | |
| ); | |
| // | |
| // functions | |
| // | |
| // retrieve color from map ie. `color(light, 1)` | |
| @function color($color-group, $color-name) { | |
| @return map-get(map-get($colors, $color-group), $color-name); | |
| } | |
| // retrieve size from map ie. `size(hex-radius)` | |
| @function size($size-name) { | |
| @return map-get($sizes, $size-name); | |
| } | |
| // retrieve rotation from map ie. `rotation(1)` | |
| @function rotation($number) { | |
| @return map-get($rotations, rotation-#{$number}); | |
| } | |
| // retrieve timing from map ie. `timing(base-time)` | |
| @function timing($timing) { | |
| @return map-get($timings, $timing); | |
| } | |
| // | |
| // style mixins | |
| // | |
| // cube structure | |
| @mixin cube-base($segment-height, $cube-radius) { | |
| // positioning and sizing | |
| position: absolute; display: block; | |
| width: $cube-radius * 2; height: $segment-height * 2; | |
| // center cube in parent context | |
| top: calc(50% - #{$segment-height}); left: calc(50% - #{$cube-radius}); | |
| // each side | |
| span { | |
| position: absolute; | |
| display: block; | |
| transform-origin: 50% 50%; | |
| // two trianges per side | |
| &::before, &::after { | |
| content: ''; | |
| position: absolute; | |
| height: 0; width: 0; | |
| border-left: $cube-radius / 2 solid transparent; | |
| border-right: $cube-radius / 2 solid transparent; | |
| } | |
| } | |
| // initial triangle border styles | |
| $border-style-light: $segment-height solid color('global', 1); | |
| $border-style-med: $segment-height solid color('global', 2); | |
| $border-style-dark: $segment-height solid color('global', 3); | |
| .side-6 { | |
| &::before { border-bottom: $border-style-light } | |
| &::after { border-top: $border-style-light } | |
| } | |
| .side-4, .side-5 { | |
| &::before { border-bottom: $border-style-med } | |
| &::after { border-top: $border-style-med } | |
| } | |
| .side-1, .side-2, .side-3 { | |
| &::before { border-bottom: $border-style-dark } | |
| &::after { border-top: $border-style-dark } | |
| } | |
| // side positioning | |
| .side-1 { z-index: 1; bottom: 0; right: 0; } // bottom | |
| .side-2 { z-index: 1; top: 0; right: 0; } // back | |
| .side-3 { z-index: 5; right: 0; } // right | |
| .side-4 { z-index: 5; bottom: 0; left: 0; } // front | |
| .side-5 { z-index: 4; left: 0; } // left | |
| .side-6 { z-index: 6; top: 0; left: 0; } // top | |
| // side container size (portrait or landscape) | |
| .side-1, .side-2, .side-4, .side-6 { | |
| height: $segment-height; width: $cube-radius * 1.5; | |
| } | |
| .side-3, .side-5 { | |
| height: $segment-height * 2; width: $cube-radius; | |
| } | |
| // side positioning and unique color | |
| .side-3, .side-5 { &::before { top: 0; } &::after { bottom: 0; } } | |
| .side-2, .side-4 { &::before { right: 0; } &::after { left: 0; } } | |
| .side-6, .side-1 { &::before { left: 0; } &::after { right: 0; } } | |
| } | |
| // cube animations handled outside of | |
| @mixin cube-animations($prefix) { | |
| // each side | |
| span { | |
| opacity: 0; | |
| // side animation | |
| animation-delay: timing(#{$prefix}-in); | |
| animation-timing-function: ease-out; | |
| animation-fill-mode: forwards; | |
| // two trianges per side | |
| &::before, &::after { | |
| // border color animation | |
| animation: #{$prefix}-triangle timing(border) ease-out timing(#{$prefix}-border-in) forwards; | |
| } | |
| } | |
| // side animations (delaying increments per side) | |
| @for $i from 1 through 6 { | |
| .side-#{$i} { | |
| animation-name: side-#{$i}; | |
| animation-duration: timing(side-in-increment) * $i; | |
| } | |
| } | |
| } | |
| // alpha structure | |
| @mixin alpha-base($segment-height, $cube-radius) { | |
| // positioning and sizing | |
| position: absolute; display: block; | |
| z-index: 9; | |
| width: $cube-radius * 2; height: $segment-height * 2; | |
| // center cube in parent context | |
| top: calc(50% - #{$segment-height}); left: calc(50% - #{$cube-radius}); | |
| opacity: 0; | |
| // fade animation | |
| animation: fade timing(border) linear timing(o-border-in) forwards; | |
| // each side | |
| span { | |
| position: absolute; | |
| display: block; | |
| height: $segment-height; width: $cube-radius; | |
| transform-origin: 50% 50%; | |
| // two trianges per side | |
| &::before, &::after { | |
| content: ''; | |
| animation-duration: 6s; | |
| animation-timing-function: ease-in-out; | |
| animation-delay: timing(alpha-fade-in); | |
| animation-iteration-count: infinite; | |
| position: absolute; | |
| height: 0; width: 0; | |
| border-left: $cube-radius / 2 solid transparent; | |
| border-right: $cube-radius / 2 solid transparent; | |
| } | |
| } | |
| $border-style-light: $segment-height solid color('global', light); | |
| .alpha-1 { | |
| top: 0; left: 0; // top | |
| &::before { left: 0; animation-name: alpha-1-b; border-bottom: $segment-height solid color('alpha', 1) } | |
| &::after { right: 0; animation-name: alpha-1-a; border-top: $segment-height solid color('alpha', 1) } | |
| } | |
| .alpha-2 { | |
| top: 0; right: 0; // right | |
| &::before { top: 0; animation-name: alpha-2-b; border-bottom: $segment-height solid color('alpha', 2) } | |
| &::after { bottom: 0; animation-name: alpha-2-a; border-top: $segment-height solid color('alpha', 2) } | |
| } | |
| .alpha-3 { | |
| bottom: 0; left: 0; // bottom | |
| &::before { right: 0; animation-name: alpha-3-b; border-bottom: $segment-height solid color('alpha', 3) } | |
| &::after { left: 0; animation-name: alpha-3-a; border-top: $segment-height solid color('alpha', 3) } | |
| } | |
| // alpha container size (portrait or landscape) | |
| .alpha-1, .alpha-3 { | |
| height: $segment-height; width: $cube-radius * 1.5; | |
| } | |
| .alpha-2 { | |
| height: $segment-height * 2; width: $cube-radius; | |
| } | |
| } | |
| // | |
| // styles | |
| // | |
| // hex | |
| .hex { | |
| width: size(hex-radius) * 2; | |
| height: size(hex-segment-height) * 2; | |
| position: relative; | |
| margin: 100px auto; | |
| } | |
| // only use the mixins | |
| .cube { | |
| @include cube-base(size(hex-segment-height), size(hex-radius)); | |
| @include cube-animations('o'); | |
| } | |
| .alpha { | |
| @include alpha-base(size(hex-segment-height), size(hex-radius)); | |
| } | |
| // body | |
| body { background-color: #2f2f2f; } | |
| // | |
| // animation mixins | |
| // | |
| @mixin keyframes($name) { | |
| @keyframes #{$name} { | |
| @content; | |
| } | |
| } | |
| // | |
| // animations | |
| // | |
| // alpha fade animation | |
| @keyframes fade { | |
| from { opacity: 0 } | |
| to { opacity: 1 } | |
| } | |
| // alpha fade animation | |
| @keyframes alpha-1-b { | |
| 0%, 100% { border-bottom-color: color('alpha', 1); } | |
| 33.33% { border-bottom-color: color('alpha', 3); } | |
| 66.66% { border-bottom-color: color('alpha', 2); } | |
| } | |
| @keyframes alpha-1-a { | |
| 0%, 100% { border-top-color: color('alpha', 1); } | |
| 33.33% { border-top-color: color('alpha', 3); } | |
| 66.66% { border-top-color: color('alpha', 2); } | |
| } | |
| @keyframes alpha-2-b { | |
| 0%, 100% { border-bottom-color: color('alpha', 2); } | |
| 33.33% { border-bottom-color: color('alpha', 1); } | |
| 66.66% { border-bottom-color: color('alpha', 3); } | |
| } | |
| @keyframes alpha-2-a { | |
| 0%, 100% { border-top-color: color('alpha', 2); } | |
| 33.33% { border-top-color: color('alpha', 1); } | |
| 66.66% { border-top-color: color('alpha', 3); } | |
| } | |
| @keyframes alpha-3-b { | |
| 0%, 100% { border-bottom-color: color('alpha', 3); } | |
| 33.33% { border-bottom-color: color('alpha', 2); } | |
| 66.66% { border-bottom-color: color('alpha', 1); } | |
| } | |
| @keyframes alpha-3-a { | |
| 0%, 100% { border-top-color: color('alpha', 3); } | |
| 33.33% { border-top-color: color('alpha', 2); } | |
| 66.66% { border-top-color: color('alpha', 1); } | |
| } | |
| // mixin for triangle animation | |
| @mixin triangle-animation($color) { | |
| border-top-color: $color; | |
| border-bottom-color: $color; | |
| } | |
| // triangle color animation | |
| @keyframes o-triangle { | |
| 0% { @include triangle-animation(color('global', 1));} | |
| 100% { @include triangle-animation(color('global', neon)); } | |
| } | |
| // side-level animations | |
| $inc: size(explode); | |
| $bg-scale: 0.75; // background | |
| $mg-scale: 1.00; // midground | |
| $fg-scale: 1.10; // foreground | |
| // redundant styles for side animations depth of field only specific for initial states | |
| @mixin scaleFade-0 ($dof) { opacity: 0; transform: scale($dof); } | |
| @mixin scaleFade-1 () { opacity: 1; transform: scale($mg-scale); } | |
| // the actual position-specific keyframes. | |
| @keyframes side-1 { | |
| 0% { @include scaleFade-0($bg-scale); bottom: -$inc; right: -$inc; } | |
| 100% { @include scaleFade-1(); bottom: 0; right: 0; } | |
| } | |
| @keyframes side-2 { | |
| 0% { @include scaleFade-0($bg-scale); top: -$inc * 0.5; right: -$inc; } | |
| 100% { @include scaleFade-1(); top: 0; right: 0; } | |
| } | |
| @keyframes side-3 { | |
| 0% { @include scaleFade-0($fg-scale); right: -$inc * 0.5; } | |
| 100% { @include scaleFade-1(); right: 0; } | |
| } | |
| @keyframes side-4 { | |
| 0% { @include scaleFade-0($bg-scale); bottom: -$inc * 0.5; left: -$inc; } | |
| 100% { @include scaleFade-1(); bottom: 0; left: 0; } | |
| } | |
| @keyframes side-5 { | |
| 0% { @include scaleFade-0($bg-scale); left: -$inc * 1.5; } | |
| 100% { @include scaleFade-1(); left: 0; } | |
| } | |
| @keyframes side-6 { | |
| 0% { @include scaleFade-0($fg-scale); top: -$inc; left: -$inc; } | |
| 100% { @include scaleFade-1(); top: 0; left: 0; } | |
| } |