|
// initial sequence |
|
$sequence: 1,1; |
|
// to be left values |
|
$sequence_lefts: (); |
|
// to be top values |
|
$sequence_tops: (); |
|
// how many iterations |
|
// best when multiple of 4 |
|
// must match jade line 1 |
|
$iterations: 4; |
|
// how many items per iteration |
|
$per_iteration: 8; |
|
// total item count |
|
$count: $iterations * $per_iteration; |
|
|
|
|
|
// |
|
// creating the fibonacci sequence |
|
// |
|
|
|
// prepend function for big > small order |
|
@function prepend($list, $value) { |
|
@return join($value, $list); |
|
} |
|
|
|
// string replace method |
|
// http://hugogiraudel.com/2014/01/13/sass-string-replacement-function/ |
|
// http://sassmeister.com/gist/1b4f2da5527830088e4d |
|
@function str-replace($string, $search, $replace: '') { |
|
$index: str-index($string, $search); |
|
@if $index { |
|
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); |
|
} |
|
@return $string; |
|
} |
|
|
|
// reverse a list |
|
@function reverse($list, $recursive: false) { |
|
$result: (); |
|
@for $i from length($list)*-1 through -1 { |
|
@if type-of(nth($list, abs($i))) == list and $recursive { |
|
$result: append($result, reverse(nth($list, abs($i)), $recursive)); |
|
} |
|
@else { |
|
$result: append($result, nth($list, abs($i)), comma); |
|
} |
|
} |
|
@return $result; |
|
} |
|
|
|
// main commafy method |
|
@function commafy($int) { |
|
// get decimal |
|
$decimal: $int - floor($int); |
|
// round down |
|
@if $decimal == 0 { $decimal: ""; } |
|
@else { $decimal: str-replace(inspect($decimal),"0.", "."); } |
|
$int: floor($int); |
|
// empty array |
|
$arr: (); |
|
// empty comma string |
|
$comma_int: ""; |
|
// integer to string |
|
$int_str: inspect($int); |
|
|
|
// if greater than 3 |
|
@if str-length($int_str) > 3 { |
|
// pushing every three numbers to our array |
|
$str_length: str-length($int_str); |
|
|
|
// groups of three after first 1-2 |
|
@for $i from 1 through floor($str_length / 3) { |
|
$slice_start: $str_length - ($i * 3) + 1; |
|
$slice_end: $slice_start + 2; |
|
$arr: append($arr, str-slice($int_str, $slice_start, $slice_end), comma); |
|
} |
|
|
|
// get first group of numbers if length not an even multiple of three |
|
@if floor(str-length($int_str) / 3) != str-length($int_str) / 3 { |
|
$diff: str-length($int_str) % 3; |
|
$slice_start: 1; |
|
$slice_end: $slice_start + $diff - 1; |
|
$arr: append($arr, str-slice($int_str, $slice_start, $slice_end), comma); |
|
} |
|
// reverse the array |
|
$arr: reverse($arr); |
|
// removing spaces from array string |
|
$comma_int: str-replace(inspect($arr), " ", ""); |
|
//$comma_int: inspect($arr); |
|
|
|
} @else { |
|
// three or less integers, just return the string |
|
$comma_int: inspect($int_str); |
|
} |
|
// return commafied integer string plus potential decimal |
|
@return $comma_int + $decimal; |
|
} |
|
|
|
// start at 3 (length of sequence plus 1) |
|
// end at count (multiple of per_iteration) |
|
@for $i from (length($sequence) + 1) through $count { |
|
// get two previous values |
|
$prev1: nth($sequence, (length($sequence) + 2 - $i)); |
|
$prev2: nth($sequence, (length($sequence) + 3 - $i)); |
|
// new value is sum of two previous values |
|
$val: $prev1 + $prev2; |
|
// add new value to sequence |
|
$sequence: prepend($sequence, $val); |
|
} |
|
|
|
// origins |
|
$origin_top: 0; |
|
$origin_left: 0; |
|
|
|
// getting left values |
|
@for $i from 1 through length($sequence) { |
|
|
|
// initial TR quarter |
|
@if ($i == 1) { |
|
|
|
$sequence_lefts: append($sequence_lefts, 0); |
|
$sequence_tops: append($sequence_tops, 0); |
|
|
|
// initial TL quarter |
|
} @elseif ($i == 2) { |
|
|
|
$sequence_lefts: append($sequence_lefts, nth($sequence, 1)); |
|
$sequence_tops: append($sequence_tops, nth($sequence, 3)); |
|
|
|
// initial BL quarter |
|
} @elseif ($i == 3) { |
|
|
|
$sequence_lefts: append($sequence_lefts, nth($sequence, 1) + nth($sequence, 4)); |
|
$sequence_tops: append($sequence_tops, 0); |
|
|
|
// initial BR quarter |
|
} @elseif ($i == 4) { |
|
|
|
$sequence_lefts: append($sequence_lefts, nth($sequence, 1)); |
|
$sequence_tops: append($sequence_tops, 0); |
|
|
|
// all other quarters |
|
} @else { |
|
// initial left, top |
|
$left: 0; $top: 0; |
|
|
|
// if TR |
|
@if ($i % 4 == 1) { |
|
|
|
$left: nth($sequence_lefts, $i - 4) + nth($sequence, $i - 4); |
|
$top: nth($sequence_tops, $i - 1) + nth($sequence, $i - 1); |
|
|
|
// if TL |
|
} @elseif ($i % 4 == 2) { |
|
|
|
$left: nth($sequence_lefts, $i - 1) + nth($sequence, $i - 1); |
|
$top: nth($sequence_tops, $i - 4) - nth($sequence, $i); |
|
|
|
// if BL |
|
} @elseif ($i % 4 == 3) { |
|
|
|
$left: nth($sequence_lefts, $i - 4) - nth($sequence, $i); |
|
$top: nth($sequence_tops, $i - 3) + nth($sequence, $i - 3); |
|
|
|
// if BR |
|
} @elseif ($i % 4 == 0) { |
|
|
|
$left: nth($sequence_lefts, $i - 3) + nth($sequence, $i - 3); |
|
$top: nth($sequence_tops, $i - 4) + nth($sequence, $i - 4); |
|
|
|
} |
|
|
|
// if last first, set origins |
|
@if ($i == length($sequence) - 8) { |
|
$origin_top: $top; |
|
$origin_left: $left; |
|
} |
|
|
|
// append left and top values |
|
$sequence_lefts: append($sequence_lefts, $left); |
|
$sequence_tops: append($sequence_tops, $top); |
|
} |
|
} |
|
|
|
// power function |
|
@function power($x, $n) { |
|
$ret: 1; |
|
@if $n >= 0 { |
|
@for $i from 1 through $n { |
|
$ret: $ret * $x; |
|
} |
|
} @else { |
|
@for $i from $n to 0 { |
|
$ret: $ret / $x; |
|
} |
|
} |
|
@return $ret; |
|
} |
|
|
|
|
|
$golden_ratio: 1.6180339887498948482; |
|
$golden_ratio_inverse: 1/$golden_ratio; |
|
|
|
$container_w: 700px; |
|
$fig_w: $container_w * power($golden_ratio,$iterations); |
|
$fig_h: $fig_w * $golden_ratio_inverse; |
|
$rel_origin_left: ($origin_left / (nth($sequence, 1) + nth($sequence, 2)) * 100%); |
|
$rel_origin_top: ($origin_top / nth($sequence, 1) * 100%); |
|
|
|
|
|
section { |
|
width: $container_w; |
|
height: $container_w * $golden_ratio_inverse; |
|
position: absolute; |
|
overflow: hidden; |
|
left: calc(50% - #{$container_w / 2}); |
|
top: calc(50% - #{$container_w / 2 * $golden_ratio_inverse}); |
|
&::after { |
|
border: 1px solid #444; |
|
content: ""; |
|
position: absolute; |
|
top: 0; right: 0; bottom: 0; left: 0; |
|
} |
|
> div { |
|
position: absolute; |
|
left: $rel_origin_left; top: $rel_origin_top; |
|
} |
|
} |
|
|
|
|
|
figure { |
|
background: #444; |
|
width: $fig_w; |
|
height: $fig_h; |
|
position: absolute; |
|
margin-left: $rel_origin_left / 100% * $fig_w * -1; |
|
margin-top: $rel_origin_top / 100% * ($fig_w * $golden_ratio_inverse) * -1; |
|
&:not(.bg) { |
|
animation: |
|
// slowing comes from relative scaling. |
|
// linear slows towards the end. ease-in helps a little. |
|
// crazy cubic bezier fix? |
|
scale-fig 2s * $iterations ease-in infinite, |
|
fade-fig 2s * $iterations ease-in infinite; |
|
animation-delay: 2s; |
|
} |
|
transform: scale(power($golden_ratio_inverse, $iterations)); |
|
transform-origin: $rel_origin_left $rel_origin_top; |
|
span { |
|
display: block; |
|
border-radius: 100% 0 0 0; |
|
position: absolute; |
|
&::after { |
|
color: rgba(255,255,255,0.2); |
|
position: absolute; |
|
bottom: 2%; right: 2%; |
|
} |
|
} |
|
} |
|
|
|
@for $i from 1 through length($sequence) { |
|
$ratio: nth($sequence, $i) / nth($sequence, 1); |
|
$mod: $i % 4; |
|
$mod_ratio: ($mod + 1) / 4; |
|
|
|
span:nth-child(#{$i}) { |
|
// square |
|
width: $ratio * $fig_w * $golden_ratio_inverse; |
|
padding-bottom: $ratio * $fig_w * $golden_ratio_inverse; |
|
|
|
// positioning |
|
left: nth($sequence_lefts, $i) / (nth($sequence, 1) + nth($sequence, 2)) * $fig_w; |
|
top: nth($sequence_tops, $i) / nth($sequence, 1) * $fig_h; |
|
|
|
// alternating grayscale |
|
background-color: rgba(255,255,255,$mod_ratio); |
|
// straight white |
|
background-color: white; |
|
// alternating color |
|
background-color: hsl(360 - $mod_ratio * 360, 50, 50); |
|
|
|
// rotations |
|
@if ($i % 4 == 1) { |
|
transform: rotate(-90deg); |
|
} @elseif ($i % 4 == 2) { |
|
transform: rotate(-180deg); |
|
} @elseif ($i % 4 == 3) { |
|
transform: rotate(-270deg); |
|
} @elseif ($i % 4 == 0) { |
|
transform: rotate(-360deg); |
|
} |
|
|
|
// after |
|
&::after { |
|
content: "#{commafy(nth($sequence, $i))}"; |
|
font-size: $iterations * 50px * $ratio; |
|
} |
|
|
|
} |
|
} |
|
|
|
// fading out at end, fading back in once zoomed out |
|
@keyframes fade-fig { |
|
0%, 80%, 95%, 100% { opacity: 1; } |
|
90%, 91% { opacity: 0; } |
|
} |
|
|
|
// scaling in and out. timed with fade. |
|
@keyframes scale-fig { |
|
0%, 91%, 95%, 100% { transform: scale(power($golden_ratio_inverse, $iterations)); } |
|
80%, 90% { transform: scale(power($golden_ratio, $iterations)); } |
|
} |
|
|
|
// the output |
|
body::after { |
|
content: "Generated Sequence: #{reverse($sequence)}"; |
|
position: absolute; |
|
bottom: 24px; |
|
left: calc(50% - #{$container_w/2}); |
|
width: $container_w; |
|
color: #666; |
|
text-align: center; |
|
font-weight: light; |
|
line-height: 1.8; |
|
font-size: 12px; |
|
} |
|
|
|
// other shit |
|
body { background: #222; } |