- var n12hedron = 12;
- var n20hedron = 20;
- var n_open = 30;
- var n_shapes = 2;
- var n5gon = 5, n10gon = 10;
- var typ = ['inf', 'mid', 'sup'];

style
	- for(var i = 0; i < n12hedron; i++)
		| .s2d:nth-child(#{n5gon}n + #{i + 1}) { --j: #{i} }
	| .s5gon.cup { --j: 0 }
	| .s4gon:nth-child(n + #{.5*n_open + 1}) { --o: 1 }
.a3d
	while n_shapes--
		.s3d
			.s12hedron
				- for(var i = 0; i < n12hedron; i++) {
					- var cond = ~~(i/n10gon);
					- var idx = 2*(cond ? (i%2) : (~~(i/n5gon)));
					.s2d.s5gon(class=`${cond ? `cup` : `lat`} ${typ[idx]}`)
				- }
			.s20hedron
				- for(var i = 0; i < n20hedron; i++) {
					- var cond = (~~(i/n5gon))%2;
					- var idx = 2*~~(i/n10gon);
					.s2d.s3gon(class=`${cond ? 'cup' : 'lat'} ${typ[idx]}`)
				- }
			.open
				- for(var i = 0; i < n_open; i++) {
					- var idx = ~~(i/n10gon);
					- var cond = (1 - (idx%2))*~~((i%n10gon)/n5gon);
					.s2d.s4gon(class=`${cond ? 'cup' : 'lat'} ${typ[idx]}`)
				- }
View Compiled
@import 'compass/css3';

@function to-deg($val) {
	@if unitless($val) or unit($val) == 'rad' {
		@return $val*180deg/pi();
	}
}

@function hypot($v) {
	$n: length($v);
	$sum: 0;
	
	@for $i from 0 to $n {
		$sum: $sum + pow(nth($v, $i + 1), 2)
	}
	
	@return sqrt($sum)
}

@function cath1($h, $c0) {
	@return sqrt(pow($h, 2) - pow($c0, 2))
}

@function bc-ang($n: 3) { @return 360deg/$n }

@function vx-ang($n: 3) { @return 180deg*($n - 2)/$n }

@function in-rad($l, $ba) { @return .5*$l/tan(.5*$ba) }

@function cc-rad($l, $ba) { @return .5*$l/sin(.5*$ba) }

$l: 8vmin;
$tr: 1.5s;
$te: 9s;
$φ: .5*(1 + sqrt(5));
$bw-ini: 50%;
$bw-mid: 5px;
$bw-fin: 50%;

$n3gon: 3;
$ba3gon: bc-ang($n3gon);
$ri3gon: in-rad($l, $ba3gon);
$rc3gon: cc-rad($l, $ba3gon);
$h3gon: $rc3gon + $ri3gon;

$n4gon: 4;
$ba4gon: bc-ang($n4gon);
$ri4gon: in-rad($l, $ba4gon);
$rc4gon: cc-rad($l, $ba4gon);

$n5gon: 5;
$ba5gon: bc-ang($n5gon);
$va5gon: vx-ang($n5gon);
$ri5gon: in-rad($l, $ba5gon);
$rc5gon: cc-rad($l, $ba5gon);
$dg5gon: 2*$l*sin(.5*$va5gon);
$hi5gon: $l*cos($va5gon - 90deg);
$hs5gon: $l*cos(.5*$va5gon);
$h5gon: $hs5gon + $hi5gon;

$n12hedron: 12;
$l5sec12hedron: $dg5gon;
$rc5sec12hedron: cc-rad($l5sec12hedron, $ba5gon);
$ri5sec12hedron: in-rad($l5sec12hedron, bc-ang(5));
$fax12hedron: to-deg(asin(($ri5sec12hedron - $ri5gon)/$hi5gon));
$ri12hedron: .5*($h5gon + $hi5gon)*cos($fax12hedron);
$rc12hedron: hypot(($rc5gon $ri12hedron));
$rm12hedron: hypot(($ri5gon $ri12hedron));
$eaxc12hedron: to-deg(atan($ri12hedron/$ri5gon));
$eaxl12hedron: to-deg(asin(($rc5sec12hedron - $rc5gon)/$l));
$eaz12hedron: to-deg(acos(hypot(($rc5sec12hedron - $ri5sec12hedron .5*$l5sec12hedron))/$l));

$n20hedron: 20;
$faxc20hedron: to-deg(asin($ri5gon/$h3gon));
$faxm20hedron: to-deg(asin(($rc5gon - $ri5gon)/$h3gon));
$hc20hedron: cath1($h3gon, $ri5gon);
$hm20hedron: cath1($h3gon, $rc5gon - $ri5gon);
$rc20hedron: $hc20hedron + .5*$hm20hedron;
$ri20hedron: cath1($rc20hedron, $rc3gon);
$rm20hedron: hypot(($ri3gon $ri20hedron));

$rc62hedron: .5*sqrt(8*$φ + 7)*$l;
$ri3f62hedron: cath1($rc62hedron, $rc3gon);
$ri4f62hedron: cath1($rc62hedron, $rc4gon);
$ri5f62hedron: cath1($rc62hedron, $rc5gon);

@function getPolyPoints(
		$n: 3 /* number of poly vertices */, 
		$oa: -90deg /* angular offset of 1st poly vertex */, 
		$bw: $bw-ini /* polygon border-width */) {
	
	$ba: 360deg/$n; // base angle corrensponding to 1 poly edge
	$l0: (); // list of points, initially empty
	$l1: (); // list of points, initially empty
	
	@for $i from 0 through $n {
		$ca: $i*$ba + $oa; // angle current point is at wrt x axis
		$x: calc(50%*(1 + #{cos($ca)})); // x coord of current point
		$y: calc(50%*(1 + var(--s)*#{sin($ca)})); // y coord of current point
		$l0: $l0, $x $y; // add current point coords to points list
		$ca: -$i*$ba + $oa; // angle current point is at wrt x axis
		$x: calc(50% + (50% - #{$bw})*#{cos($ca)}); // x coord of current point
		$y: calc(50% + (50% - #{$bw})*var(--s)*#{sin($ca)}); // y coord of current point
		$l1: $l1, $x $y // add current point coords to points list
	}
	
	@return join($l0, $l1, comma)
}

@function iso-s3d($f) { @return scale3d($f, $f, $f) }

body {
	overflow: hidden;
	margin: 0;
	height: 100vh;
	perspective: 20em;
	background: #000
}

div, :before {
	position: absolute;
	transform-style: preserve-3d;
}

.a3d {
	top: 50%; left: 50%;
	animation: r $tr linear infinite
}

@keyframes r { to { transform: rotateY(1turn) } }

.s3d {
	--rdt: 0;
	--ani-exp: exp3d $te ease-in calc(var(--rdt)*#{-$te}) infinite;
	animation: var(--ani-exp);
		
	&:nth-child(2) {
		--rdt: .5;
		
		.s3gon {
			--z-ini: #{$ri20hedron};
			--f-ini: 1;
		}
		
		.s4gon {
			--z-ini: #{$rm20hedron};
			--f-ini: 0, 1;
		}
		
		.s5gon {
			--z-ini: #{$rc20hedron};
			--f-ini: 0;
		}
	}
}

.s2d {
	--b2: calc(1 - var(--b1));
	--s1: calc(1 - 2*var(--b1));
	--s: calc(-1*var(--s0)*var(--s1));
	--o: 0;
	--p: calc(var(--s0)*var(--s0));
	--q: calc(1 - var(--p));
	margin: calc(-1*var(--r2d));
	padding: var(--r2d);
	--z-fin: calc(var(--z-mid) + 13vmin);
	--f-mid: 1;
	--f-fin: .2;
	--dir: rotatey(calc(var(--my)*#{$ba5gon})) 
				 rotatex(calc(var(--s0)*(var(--b2)*var(--ax0) + var(--b1)*var(--ax1)))) 
				 var(--rx, unquote(' '));
	transform: var(--dir) translatez(var(--z-ini)) scale(var(--f-ini));
	filter: brightness(calc(1.375 + var(--s0)*.1));
	clip-path: polygon(var(--p-ini));
	animation: var(--ani-exp);
	animation-name: exp2d, fade, hole;
		
	&:not(.cup.s5gon):before {
		top: 0; right: 0; bottom: 0; left: 0;
		background: rgba(#000, .85);
		animation: shade .5*$tr linear calc(#{-.5*$tr} - var(--my)*#{$tr/$n5gon}) infinite alternate;
		content: ''
	}
}

.s3gon {
	--r2d: #{$rc3gon};
	--my: calc(var(--j) + .25*(var(--s0) - 1));
	--ax0: #{$faxm20hedron};
	--ax1: #{$faxc20hedron};
	--z-ini: #{$rc12hedron};
	--z-mid: #{$ri3f62hedron};
	--f-ini: 0;
	background: #e2a9e5;
	--p-ini: #{getPolyPoints()};
	--p-mid: #{getPolyPoints($bw: $bw-mid)};
	--p-fin: #{getPolyPoints($bw: $bw-fin)}
}

.s4gon {
	--s: 1;
	--r2d: #{$rc4gon};
	--my: calc(var(--j) + .25*(var(--s) - 1 - var(--q)) + .5*(var(--b2) + var(--o, 0)));
	--ax0: #{$eaxl12hedron};
	--ax1: #{$eaxc12hedron};
	--rx: rotate(calc(var(--b2)*(var(--q)*(1 - 2*var(--o))*#{$eaz12hedron} + var(--p)*90deg)));
	--z-ini: #{$rm12hedron};
	--z-mid: #{$ri4f62hedron};
	--f-ini: 1, 0;
	background: #4b384c;
	--p-ini: #{getPolyPoints(4, -.5*$ba4gon)};
	--p-mid: #{getPolyPoints(4, -.5*$ba4gon, $bw-mid)};
	--p-fin: #{getPolyPoints(4, -.5*$ba4gon, $bw-fin)}
}

.s5gon {
	--r2d: #{$rc5gon};
	--my: calc((var(--j) + .25*(var(--s0) + 1)));
	--ax0: #{$fax12hedron};
	--ax1: 90deg;
	--z-ini: #{$ri12hedron};
	--z-mid: #{$ri5f62hedron};
	--f-ini: 1;
	background: #632c65;
	--p-ini: #{getPolyPoints(5)};
	--p-mid: #{getPolyPoints(5, $bw: $bw-mid)};
	--p-fin: #{getPolyPoints(5, $bw: $bw-fin)}
}

.inf {
	--s0: -1
}

.mid {
	--s0: 0
}

.sup {
	--s0: 1
}

.cup {
	--b1: 1;
}

.lat {
	--b1: 0
}

@keyframes exp3d {
	0% { transform: iso-s3d(0) }
	25%, 100% { transform: iso-s3d(1) }
}

@keyframes exp2d {
	0%, 25% {
		transform: var(--dir) translatez(var(--z-ini)) scale(var(--f-ini))
	}	
	50%, 75% {
		transform: var(--dir) translatez(var(--z-mid)) scale(var(--f-mid));
		animation-timing-function: cubic-bezier(.21, 1, .32, 1)
	}
	100% {
		transform: var(--dir) translatez(var(--z-fin)) scale(var(--f-fin))
	}
}

@keyframes fade {
	0%, 87.5% { opacity: .99 }
	100% { opacity: .01 }
}

@keyframes hole {
	0%, 25% {
		clip-path: polygon(var(--p-ini));
		animation-timing-function: ease-out
	}
	50%, 75% {
		clip-path: polygon(var(--p-mid))
	}
	100% {
		clip-path: polygon(var(--p-fin))
	}
}

@keyframes shade { to { opacity: .001 } }
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.