add hex animation

mistress
xenofem 2020-06-21 23:55:06 -04:00
parent a0589885e3
commit f56bb48811
5 changed files with 295 additions and 0 deletions

60
content/hypno/hex/hex.css Normal file
View File

@ -0,0 +1,60 @@
.cell .hex {
width: 55px;
position: absolute;
z-index: -1;
transform: translate(-50%, -50%);
}
.cell .spiral {
width: 45px;
position: absolute;
animation: spin 1s linear infinite;
}
.cell.alive {
animation: birth 1s linear forwards;
}
.cell.dead {
animation: death 1s linear forwards;
}
#grid {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
overflow: hidden;
}
#controls {
display: none;
}
@keyframes death {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes birth {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes spin {
0% {
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}

208
content/hypno/hex/hex.js Normal file
View File

@ -0,0 +1,208 @@
var grid = document.getElementById("grid");
var cellsize = 60;
var width = Math.ceil(window.innerWidth / cellsize) + 1;
var height = Math.ceil(window.innerHeight / (cellsize*Math.sqrt(3)/2));
function xCoord(i, j) {
var x = i + j/2;
if (x > width - 1) {
x = x - width;
}
return x;
}
function yCoord(i, j) {
return Math.sqrt(3)*j/2;
}
var cells = new Array(width);
for (var i = 0; i < width; ++i) {
cells[i] = new Array(height);
for (var j = 0; j < height; ++j) {
cells[i][j] = document.createElement("div");
cells[i][j].classList.add("cell");
cells[i][j].classList.add("alive");
spiral = document.createElement("img");
spiral.classList.add("spiral");
spiral.src = "spiral.svg";
cells[i][j].appendChild(spiral);
hex = document.createElement("img");
hex.classList.add("hex");
hex.src = "hex.svg";
cells[i][j].appendChild(hex);
cells[i][j].style.position = "absolute";
cells[i][j].style.left = xCoord(i, j)*cellsize + "px";
cells[i][j].style.bottom = yCoord(i, j)*cellsize + "px";
grid.appendChild(cells[i][j]);
}
}
function prebirth(i, j) {
cells[i][j].classList.add("birthing");
}
function prekill(i, j) {
cells[i][j].classList.add("dying");
}
function birth(i, j) {
cells[i][j].classList.remove("dead");
cells[i][j].classList.add("alive");
}
function kill(i, j) {
cells[i][j].classList.remove("alive");
cells[i][j].classList.add("dead");
}
function update(i, j) {
var cl = cells[i][j].classList;
if (cl.contains("birthing")) {
cl.remove("birthing");
birth(i, j);
}
if (cl.contains("dying")) {
cl.remove("dying");
kill(i, j);
}
}
function isAlive(i, j) {
return !cells[i][j].classList.contains("dead");
}
function rotate(a) {
a.push(a.shift());
}
function arraysEq(a, b) {
if (a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function arraysRotatedEq(a, b) {
if (a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; ++i) {
if (arraysEq(a, b)) {
return true;
}
rotate(b);
}
return false;
}
function mod(m, n) {
return ((m % n) + n) % n;
}
function ip(i) {
return mod(i-1, width);
}
function is(i) {
return mod(i+1, width);
}
function jp(j) {
return mod(j-1, height);
}
function js(j) {
return mod(j+1, height);
}
function ll(i, j) {
return isAlive(ip(i), j);
}
function dl(i, j) {
return isAlive(i, jp(j));
}
function dr(i, j) {
return isAlive(is(i), jp(j));
}
function rr(i, j) {
return isAlive(is(i), j);
}
function ur(i, j) {
return isAlive(i, js(j));
}
function ul(i, j) {
return isAlive(ip(i), js(j));
}
function neighbors(i, j) {
return [ll(i, j), dl(i, j), dr(i, j), rr(i, j), ur(i, j), ul(i, j)];
}
function neighborsCount(i, j) {
return neighbors(i, j).filter(function (b) { return b; }).length;
}
function golay(i, j) {
var n = neighbors(i, j);
var g1 = [true, true, false, false, false, false];
var g2 = [true, false, true, false, false, false];
return (arraysRotatedEq(n, g1) || arraysRotatedEq(n, g2));
}
function preston(i, j) {
var n = neighbors(i, j);
var p1 = [true, true, false, false, false, false];
var p2 = [true, false, true, false, false, false];
return (isAlive(i, j) && (arraysRotatedEq(n, p1) || arraysRotatedEq(n, p2))) || (!isAlive(i, j) && neighborsCount(i, j) === 2);
}
function golayStep() {
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
if (golay(i, j)) {
prebirth(i, j);
} else {
prekill(i, j);
}
}
}
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
update(i, j);
}
}
}
function prestonStep() {
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
if (preston(i, j)) {
prebirth(i, j);
} else {
prekill(i, j);
}
}
}
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
update(i, j);
}
}
}
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
if (Math.floor(Math.random()*2) === 0) {
kill(i, j);
}
}
}
setInterval(prestonStep, 1000);

View File

@ -0,0 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- This file was generated by dvisvgm 2.3.5 -->
<svg height='203.9997pt' version='1.1' viewBox='56.4094 53.8583 177.2056 203.9997' width='177.2056pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
<g id='page1'>
<g transform='matrix(0.996264 0 0 0.996264 145.012 155.858)'>
<path d='M 6.1462e-15 -100.375L -86.9273 -50.1875L -86.9273 50.1875L -1.84386e-14 100.375L 86.9273 50.1875L 86.9273 -50.1875L 6.1462e-15 -100.375Z' fill='none' stroke='#ff0000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
</g></g>
</svg>

After

Width:  |  Height:  |  Size: 637 B

View File

@ -0,0 +1,8 @@
+++
title = "hex"
date = 2020-06-21T18:52:30-04:00
draft = false
unlisted = false
+++
<div id="grid"></div>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB