$default-threshold: pi()/180/20; @function convert-angle($value, $unit-name) { $factors: ( rad: 1rad, deg: 180deg/pi(), grad: 200grad/pi(), turn: .5turn/pi() ); @if not unitless($value) { @warn '`#{$value}` should be unitless'; @return false; } @if not map-has-key($factors, $unit-name) { @warn 'unit `#{$unit-name}` is not a valid unit - please make sure it is either `deg`, `rad`, `grad` or `turn`'; @return false; } @return $value*map-get($factors, $unit-name); } @function asin($z, $unit-name: deg, $threshold: $default-threshold) { $sum: 0; $complement: false; $sign: if($z != 0, $z/abs($z), 1); $z: abs($z); @if $z > 1 { @warn 'illegal `#{$z}` value for function'; @return false; } @if $z > sin(pi()/4) { $complement: true; $z: sqrt(1 - pow($z, 2)); } $term: $z; $i: 0; $k: 1; @while $term > $threshold { $sum: $sum + $term; $i: $i + 1; $k: $k*(2*$i - 1)/(2*$i); $j: 2*$i + 1; $term: $k*pow($z, $j)/$j; } @return convert-angle($sign*(if($complement, pi()/2 - $sum, $sum)), $unit-name); } @function acos($z, $unit-name: deg, $threshold: $default-threshold) { @return convert-angle(pi()/2, $unit-name) - asin($z, $unit-name, $threshold); } @function atan($z, $unit-name: deg, $threshold: $default-threshold) { @return asin($z/sqrt(1 + pow($z, 2)), $unit-name, $threshold); } @function complexAdd($a,$b) { @return pow($a,2) + pow($b,2); } @function complexMult($a,$b) { @return 2*$a*$b; } @function firstAngle($a,$b,$c) { @return acos((complexAdd($b,$c) - pow($a,2))/complexMult($b,$c)); } @function secondAngle($A,$a,$b) { @return asin(sin($A)*$b/$a); } @function thirdAngle($A,$B) { @return 180deg - $A - $B; } @function secondSide($a,$A,$B) { @return $a*sin($B)/sin($A); } @function thirdSide($A,$b,$c) { @return sqrt(complexAdd($b,$c) - complexMult($b,$c)*cos($A)); } @function AAS($A,$C,$c) { $B: thirdAngle($A,$C); // B = 180deg - A - C $a: secondSide($c,$C,$A); // a/sin(A) = c/sin(C) $b: secondSide($c,$C,$B); // b/sin(B) = c/sin(C) $ret: (a:$a,b:$b,c:$c,A:$A,B:$B,C:$C); @return $ret; } @function ASA($A,$B,$c) { $C: thirdAngle($A,$B); // C = 180deg - A - B $a: secondSide($c,$C,$A); // a/sin(A) = c/sin(C) $b: secondSide($c,$C,$B); // b/sin(B) = c/sin(C) $ret: (a:$a,b:$b,c:$c,A:$A,B:$B,C:$C); @return $ret; } @function SAS($A,$b,$c) { $a: thirdSide($A,$b,$c); // a2 = b2 + c2 − 2 * b * c * cos(A) $B: secondAngle($A,$a,$b); // sinB/b = sinA/a $C: thirdAngle($A,$B); // C = 180deg - A - B $ret: (a:$a,b:$b,c:$c,A:$A,B:$B,C:$C); @return $ret; } @function SSA($B,$b,$c) { $C: secondAngle($B,$b,$c); // sin(C)/c = sin(B)/b $A: thirdAngle($B,$C); // A = 180deg - B - C $a: secondSide($b,$B,$A); // a/sin(A) = b/sin(B) $ret: (a:$a,b:$b,c:$c,A:$A,B:$B,C:$C); @return $ret; } @function SSS($a,$b,$c) { $A: firstAngle($a,$b,$c); // cos(A) = (b2 + c2 − a2) / 2bc $B: firstAngle($b,$c,$a); // cos(B) = (c2 + a2 − b2) / 2ca $C: thirdAngle($A,$B); $ret: (a:$a,b:$b,c:$c,A:$A,B:$B,C:$C); @return $ret; } $size: 160px; $color: #3F51B5; body { background: #ddd; } .pane { position: absolute; top: 50%; left: 50%; height: $size; width: $size; margin: $size/-2; perspective: 700px; // debug //box-shadow: 0 0 0 5px #0f0; // prepare 3d basics and resets &, *, *:before, *:after { position: absolute; top: 50%; left: 50%; box-sizing: border-box; transform-style: preserve-3d; backface-visibility: visible; visibility: hidden; } } .cube { height: $size/2; width: $size/2; margin: $size/-4; animation: rotate 9s linear infinite; // debug //box-shadow: 0 0 0 5px #f00; @at-root { @keyframes rotate { 0% { transform: rotate3d(1,1,1,0deg); } 100% { transform: rotate3d(1,1,1,-360deg); } } } .side { height: $size/2; width: $size/2; margin: $size/-4; // debug line-height: $size/2; text-align: center; font-size: $size/2; //visibility: visible; //box-shadow: 0 0 0 2px rgba(0,0,0,0.8) inset; background: rgba(0,0,0,0.3); @for $i from 1 to 7 { &:nth-child(#{$i}) { transform: if($i<4,rotatex($i*90deg),rotatey($i*90deg)) if($i==6,rotatey(90deg),()) translate3d(0,0,$size/4); } } .hypersides { display: block; height: 200%; width: 200%; margin: -100%; transform: translate3d(0,0,$size/4); //box-shadow: 0 0 0 2px rgba(0,0,0,0.8) inset; background: rgba(0,0,0,0.1); //visibility: visible; .hyperside { $dir: 1; $trunc: 2; $offset: 0; $triangle: SAS(90deg*$dir,$size/$trunc/1px,$size/$trunc/1px); &:nth-child(5) { $pos: $size - $size/$trunc*2; height: $pos; width: $pos; margin: $pos/-2; transform: translate3d(0,0,$size/$trunc*$dir); background: rgba(#F44336 ,0.1); visibility: visible; box-shadow: 0 0 0 2px rgba(#F44336 ,0.4) inset; } @for $i from 0 to 4 { &:nth-child(#{$i + 1}) { right: if($i==1,0,auto); height: 100%; width: 100%; margin: -50%; transform: rotate3d(0,0,1,$i*90deg); &:before { $height: map-get($triangle,a)*1px; content: ''; height: $height; width: 100%; top: 0; left: 0; transform-origin: 50% 0%; visibility: visible; transform: rotate3d(1,0,0,map-get($triangle,B)); clip-path: polygon( 0 0, map-get($triangle,c)*1px 100%, $size - map-get($triangle,c)*1px 100%, 100% 0, 0 0); box-shadow: 0 -2px 0 0 rgba($color,0.9) inset; background-color: rgba($color,0.1); $inner-triangle: SAS( 90deg, map-get($triangle,b)*sqrt(2), map-get($triangle,c)); $inner2-triangle: SAS( 90deg, map-get($inner-triangle,a), map-get($inner-triangle,a)); //content: '#{$inner-triangle}'; background-image: linear-gradient( map-get($inner-triangle,B), rgba($color,0.9) map-get($inner2-triangle, b)*0.5px - $offset, rgba($color,0) map-get($inner2-triangle, b)*0.5px - $offset), linear-gradient( map-get($inner-triangle,B)*-1, rgba($color,0.9) map-get($inner2-triangle, c)*0.5px - $offset, rgba($color,0) map-get($inner2-triangle, c)*0.5px - $offset); } } } } } } }