- let n_rows = 8, n_cols = 21, n_dots = 7;
- let m = n_rows*n_cols;
style
- for(let j = 0; j < n_cols; j++)
| .cell:nth-child(#{n_cols}n + #{j + 1}) { --i: #{j} }
- for(let j = 0; j < n_rows; j++)
| .cell:nth-child(n + #{n_cols*j + 1}) { --j: #{j} }
- for(let j = 0; j < n_dots; j++)
| .dot:nth-child(#{j + 1}) { --idx: #{j} }
.grid(style=`--n-rows: ${n_rows}; --n-cols: ${n_cols}; --n-dots: ${n_dots}`)
- for(let i = 0; i < m; i++)
.cell
- for(let j = 0; j < n_dots; j++)
.dot
View Compiled
$d: .5em;
$r: .5*$d;
$p: 5%;
$t: 1s;
body, div { display: grid }
body { background: #262626 }
.grid {
grid-gap: $d 2*$d;
grid-template:
repeat(var(--n-rows), calc(var(--n-dots)*#{$d})) /
repeat(var(--n-cols), $d);
place-self: center
}
.dot {
--k: calc(var(--idx)/var(--n-dots));
--mj: calc(.5*(var(--n-rows) - 1));
--abs-j: max(var(--mj) - var(--j), var(--j) - var(--mj));
--mi: calc(.5*(var(--n-cols) - 1));
--abs-i: max(var(--mi) - var(--i), var(--i) - var(--mi));
grid-area: 1/ 1;
align-self: start;
padding: $r;
border-radius: 50%;
background: hsl(calc(var(--k)*360), 80%, 65%);
mix-blend-mode: screen;
animation: osc $t ease-in-out infinite alternate;
animation-delay:
calc((var(--abs-j)/var(--mj) +
var(--abs-i)/var(--mi) +
var(--k) - 3)*#{$t})
}
@keyframes osc {
0%, #{$p} { transform: none }
#{100% - $p}, 100% { transform: translatey(calc((var(--n-dots) - 1)*#{$d})) }
}
View Compiled