Compare commits
11 Commits
temp-big-f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff0e680993 | ||
|
|
ce64fa40e7 | ||
|
|
1500d4ee55 | ||
|
|
e93fd30849 | ||
|
|
18a21bb899 | ||
|
|
52616dd10e | ||
|
|
5f9c29e29d | ||
|
|
f5cb3b5af4 | ||
|
|
b467c1ec88 | ||
|
|
cf2ed00d53 | ||
|
|
dba6834bdc |
@ -21,7 +21,7 @@ def svgpoly(points):
|
|||||||
return f'<polygon points="{ps}" stroke="black" opacity="50%" fill="none" />'
|
return f'<polygon points="{ps}" stroke="black" opacity="50%" fill="none" />'
|
||||||
|
|
||||||
def svgline(p1, p2):
|
def svgline(p1, p2):
|
||||||
return f'<line x1="{p1[0]}" y1="{p1[1]}" x2="{p2[0]}" y2="{p2[1]}" stroke="black" stroke-width="4" opacity="20%"/>\n'
|
return f'<line x1="{p1[0]}" y1="{p1[1]}" x2="{p2[0]}" y2="{p2[1]}" stroke="black" opacity="20%"/>\n'
|
||||||
|
|
||||||
def svglines(points):
|
def svglines(points):
|
||||||
lines = ""
|
lines = ""
|
||||||
@ -32,20 +32,16 @@ def svglines(points):
|
|||||||
lines += svgline(points[-1], points[0])
|
lines += svgline(points[-1], points[0])
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
print('<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">')
|
print('<svg width="800" height="1200" xmlns="http://www.w3.org/2000/svg">')
|
||||||
|
|
||||||
# n = 2
|
n = 2
|
||||||
# for j in range(11):
|
for j in range(11):
|
||||||
# for i in range(7):
|
for i in range(7):
|
||||||
# cx = 50 + i * 100
|
cx = 50 + i * 100
|
||||||
# cy = 50 + j * 100
|
cy = 50 + j * 100
|
||||||
# r = 40
|
r = 40
|
||||||
# print(svglines(fibopoly(cx, cy, r, n)))
|
print(svglines(fibopoly(cx, cy, r, n)))
|
||||||
# n += 1
|
n += 1
|
||||||
|
|
||||||
print(svglines(fibopoly(200, 200, 160, 50)))
|
|
||||||
|
|
||||||
print('</svg>')
|
print('</svg>')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
4
04/README.md
Normal file
4
04/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Genuary 04
|
||||||
|
|
||||||
|
The source code for this is on [a branch of the original FourJS repo](https://git.tilde.town/bombinans/fourdjs/src/branch/feature-pixels/)
|
||||||
|
|
||||||
35
05/animate.js
Normal file
35
05/animate.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
const pointer = { x: 0, y: 0 };
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
"pointermove",
|
||||||
|
(e) => {
|
||||||
|
pointer.x = e.clientX;
|
||||||
|
pointer.y = e.clientY;
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
const paths = document.getElementsByTagName("path");
|
||||||
|
const svg = document.getElementsByTagName("svg")[0];
|
||||||
|
|
||||||
|
console.log(paths);
|
||||||
|
function animate() {
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
const rect = svg.getBoundingClientRect();
|
||||||
|
const x = pointer.x - rect.left;
|
||||||
|
const y = pointer.y - rect.top;
|
||||||
|
for( const path of paths ) {
|
||||||
|
const i = Number(path.getAttribute("id"));
|
||||||
|
const xk = 0.004 * x;
|
||||||
|
const yk = 0.004 * (y + i - 200);
|
||||||
|
path.setAttribute(
|
||||||
|
"transform", `translate(${x}, ${y}) scale(${xk},${yk}) rotate(${xk * i * 2},20,20)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animate();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
76
05/coords.txt
Normal file
76
05/coords.txt
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
M 80.107 136.864
|
||||||
|
C 55.389 136.864 45.712 152.199 35.366 173.102
|
||||||
|
C 31.485 180.943 26.276 192.676 28.383 201.859
|
||||||
|
C 29.313 205.912 35.044 208.885 38.488 210.34
|
||||||
|
C 44.787 213.001 53.26 215.24 60.179 213.559
|
||||||
|
C 75.439 209.85 74.096 186.023 57.157 197.011
|
||||||
|
C 53.128 199.624 53.735 208.69 53.516 212.661
|
||||||
|
C 52.972 222.493 51.789 234.063 45.903 242.252
|
||||||
|
C 43.972 244.94 39.789 252.466 35.524 251.004
|
||||||
|
C 33.067 250.161 32.112 240.437 31.757 238.152
|
||||||
|
C 29.112 221.142 38.923 211.834 54.762 207.567
|
||||||
|
C 80.568 200.615 107.266 213.751 132.877 209.062
|
||||||
|
C 139.784 207.797 156.015 198.581 152.121 188.782
|
||||||
|
C 148.882 180.631 138.825 178.422 131.202 178.27
|
||||||
|
C 109.961 177.849 99.403 194.069 98.935 214.063
|
||||||
|
C 98.84 218.1 97.35 226.466 100.542 229.707
|
||||||
|
C 104.274 233.495 122.191 239.186 127.115 235.05
|
||||||
|
C 130.329 232.349 129.991 223.94 131.563 220.067
|
||||||
|
C 135.912 209.351 140.683 201.272 151.333 195.545
|
||||||
|
C 154.578 193.8 162.955 189.853 167.003 191.765
|
||||||
|
C 170.932 193.62 168.564 216.244 168.34 220.087
|
||||||
|
C 168.172 222.977 167.46 225.779 166.623 228.538
|
||||||
|
C 166.274 229.685 165.7 233.06 165.367 231.909
|
||||||
|
C 162.258 221.168 169.666 183.869 185.65 187.758
|
||||||
|
C 192.813 189.501 200.467 210.032 199.18 216.768
|
||||||
|
C 198.997 217.725 193.399 233.642 195.48 233.771
|
||||||
|
C 206.723 234.472 217.675 219.621 223.253 211.674
|
||||||
|
C 225.374 208.652 228.272 205.371 228.942 201.601
|
||||||
|
C 229.26 199.811 230.783 194.843 229.552 196.181
|
||||||
|
C 226.662 199.322 228.319 211.951 228.07 215.841
|
||||||
|
C 227.218 229.149 221.626 254.611 243.482 252.599
|
||||||
|
C 250.425 251.96 256.492 226.59 258.419 220.303
|
||||||
|
C 259.444 216.962 259.013 213.223 259.013 209.769
|
||||||
|
C 259.013 208.308 259.013 203.923 259.013 205.385
|
||||||
|
C 259.013 212.755 259.013 220.125 259.013 227.495
|
||||||
|
C 259.013 227.682 258.482 235.071 259.101 235.311
|
||||||
|
C 262.858 236.77 265.728 229.044 266.774 227.047
|
||||||
|
C 271.766 217.517 276.337 210.994 285.96 205.65
|
||||||
|
C 291.222 202.727 296.709 200.674 302.366 198.68
|
||||||
|
C 304.282 198.004 306.19 197.307 308.109 196.643
|
||||||
|
C 309.329 196.22 313.135 195.622 311.845 195.622
|
||||||
|
C 294.383 195.622 253.081 217.121 278.59 237.339
|
||||||
|
C 285.417 242.75 302.926 224.633 305.459 219.325
|
||||||
|
C 306.975 216.148 307.799 212.712 308.536 209.288
|
||||||
|
C 308.945 207.384 308.868 201.507 308.868 203.454
|
||||||
|
C 308.868 208.342 308.673 213.27 308.868 218.153
|
||||||
|
C 308.99 221.217 309.207 222.44 309.753 225.471
|
||||||
|
C 312.256 239.385 315.474 230.74 316.464 221.652
|
||||||
|
C 317.306 213.922 316.596 192.85 327.989 194.092
|
||||||
|
C 330.505 194.366 332.763 200.083 333.878 201.859
|
||||||
|
C 339.202 210.342 341.458 218.744 340.089 228.803
|
||||||
|
C 340.022 229.293 337.904 240.303 337.803 240.292
|
||||||
|
C 336.033 240.112 337.597 236.735 337.348 234.972
|
||||||
|
C 336.805 231.126 336.035 227.316 335.392 223.486
|
||||||
|
C 335.292 222.89 330.653 199.952 334.649 198.337
|
||||||
|
C 335.204 198.113 350.368 207.725 352.518 208.29
|
||||||
|
C 356.435 209.319 362.282 210.397 366.335 209.304
|
||||||
|
C 368.315 208.77 369.852 202.073 369.638 204.113
|
||||||
|
C 367.917 220.513 351.273 236.492 376.017 239.263
|
||||||
|
C 380.12 239.722 384.769 239.861 388.875 239.518
|
||||||
|
C 403.542 238.292 414.11 224.33 418.308 211.454
|
||||||
|
C 419.454 207.937 423.59 190.135 427.799 188.775
|
||||||
|
C 429.242 188.309 427.301 191.768 427.04 193.263
|
||||||
|
C 426.978 193.62 426.132 199.169 426.104 199.358
|
||||||
|
C 424.999 206.931 423.79 214.45 422.501 221.998
|
||||||
|
C 419.295 240.781 424.373 248.212 405.185 255.701
|
||||||
|
C 402.127 256.895 398.175 258.172 394.974 258.842
|
||||||
|
C 389.908 259.903 386.377 260.152 381.131 260.314
|
||||||
|
C 357.429 261.046 337.825 254.86 314.815 252.444
|
||||||
|
C 269.741 247.711 222.783 244.845 177.734 251.217
|
||||||
|
C 159.647 253.775 141.35 262.09 130.533 277.55
|
||||||
|
C 127.57 281.786 122.824 291.518 125.781 296.933
|
||||||
|
C 129.493 303.729 141.105 303.258 147.469 302.408
|
||||||
|
C 165.396 300.016 182.161 288.992 199.816 284.646
|
||||||
|
C 243.881 273.8 294.734 275.575 339.915 275.575
|
||||||
|
C 364.36 275.575 392.966 272.789 407.599 295.442
|
||||||
75
05/genuary05.py
Executable file
75
05/genuary05.py
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
COORDS = 'coords.txt'
|
||||||
|
import copy
|
||||||
|
|
||||||
|
def load_coords():
|
||||||
|
data = []
|
||||||
|
with open(COORDS, 'r') as cfh:
|
||||||
|
for line in cfh:
|
||||||
|
parts = line[:-1].split(" ")
|
||||||
|
datum = { "command": parts[0] }
|
||||||
|
points = []
|
||||||
|
for i in range(int((len(parts) - 1) / 2)):
|
||||||
|
points.append((float(parts[1 + i * 2]), float(parts[2 + i * 2])))
|
||||||
|
datum["points"] = points
|
||||||
|
data.append(datum)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def coords_string(coords):
|
||||||
|
return " ".join([ coords["command"] ] + [ f"{x} {y}" for x, y in coords["points"] ])
|
||||||
|
|
||||||
|
def coords_to_path(coords, i, r, g, b):
|
||||||
|
d = " ".join([ coords_string(c) for c in coords ])
|
||||||
|
svg = f'<path id="{i}" style="fill: none; stroke: rgb({r}, {g}, {b}); stroke-width:4; opacity: 85%"'
|
||||||
|
svg += f' d="{d}" />\n'
|
||||||
|
return svg
|
||||||
|
|
||||||
|
def apply_transform(command, f):
|
||||||
|
new_data = {
|
||||||
|
"command": command["command"]
|
||||||
|
}
|
||||||
|
new_data["points"] = [ f((x, y)) for x, y in command["points"] ]
|
||||||
|
return new_data
|
||||||
|
|
||||||
|
data = load_coords()
|
||||||
|
|
||||||
|
print("""
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>etc.mikelynch.org | Genuary 2026</title>
|
||||||
|
<link rel="stylesheet" href="../styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
<h1>Genuary 2026 - 05</h1>
|
||||||
|
|
||||||
|
<p>Prompt: Write "Genuary". Avoid using a font</p>
|
||||||
|
|
||||||
|
<p>I wrote "Genuary" using the Boxy SVG editor and then played around with it a bit
|
||||||
|
in Python and did a simple animation with JavaScript (move your mouse!)</p>
|
||||||
|
|
||||||
|
<p><a href="../">Back</a></p>
|
||||||
|
|
||||||
|
<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
""")
|
||||||
|
|
||||||
|
for i in range(-100, 100, 5):
|
||||||
|
warp = lambda p: (p[0], p[1] + i * 0.02 * p[1])
|
||||||
|
new_data = [ apply_transform(command, warp) for command in data ]
|
||||||
|
print(coords_to_path(new_data, i, 255, 128 + i, 0))
|
||||||
|
|
||||||
|
print("""
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<p><a href="https://git.tilde.town/bombinans/genuary2026/src/branch/main/05/genuary05.py">The Python script</p>
|
||||||
|
|
||||||
|
<script src="animate.js">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
""")
|
||||||
|
|
||||||
4
05/hand-drawn.svg
Normal file
4
05/hand-drawn.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
|
||||||
|
<path style="fill: none; stroke: rgb(0, 0, 0);" d="M 80.107 136.864 C 55.389 136.864 45.712 152.199 35.366 173.102 C 31.485 180.943 26.276 192.676 28.383 201.859 C 29.313 205.912 35.044 208.885 38.488 210.34 C 44.787 213.001 53.26 215.24 60.179 213.559 C 75.439 209.85 74.096 186.023 57.157 197.011 C 53.128 199.624 53.735 208.69 53.516 212.661 C 52.972 222.493 51.789 234.063 45.903 242.252 C 43.972 244.94 39.789 252.466 35.524 251.004 C 33.067 250.161 32.112 240.437 31.757 238.152 C 29.112 221.142 38.923 211.834 54.762 207.567 C 80.568 200.615 107.266 213.751 132.877 209.062 C 139.784 207.797 156.015 198.581 152.121 188.782 C 148.882 180.631 138.825 178.422 131.202 178.27 C 109.961 177.849 99.403 194.069 98.935 214.063 C 98.84 218.1 97.35 226.466 100.542 229.707 C 104.274 233.495 122.191 239.186 127.115 235.05 C 130.329 232.349 129.991 223.94 131.563 220.067 C 135.912 209.351 140.683 201.272 151.333 195.545 C 154.578 193.8 162.955 189.853 167.003 191.765 C 170.932 193.62 168.564 216.244 168.34 220.087 C 168.172 222.977 167.46 225.779 166.623 228.538 C 166.274 229.685 165.7 233.06 165.367 231.909 C 162.258 221.168 169.666 183.869 185.65 187.758 C 192.813 189.501 200.467 210.032 199.18 216.768 C 198.997 217.725 193.399 233.642 195.48 233.771 C 206.723 234.472 217.675 219.621 223.253 211.674 C 225.374 208.652 228.272 205.371 228.942 201.601 C 229.26 199.811 230.783 194.843 229.552 196.181 C 226.662 199.322 228.319 211.951 228.07 215.841 C 227.218 229.149 221.626 254.611 243.482 252.599 C 250.425 251.96 256.492 226.59 258.419 220.303 C 259.444 216.962 259.013 213.223 259.013 209.769 C 259.013 208.308 259.013 203.923 259.013 205.385 C 259.013 212.755 259.013 220.125 259.013 227.495 C 259.013 227.682 258.482 235.071 259.101 235.311 C 262.858 236.77 265.728 229.044 266.774 227.047 C 271.766 217.517 276.337 210.994 285.96 205.65 C 291.222 202.727 296.709 200.674 302.366 198.68 C 304.282 198.004 306.19 197.307 308.109 196.643 C 309.329 196.22 313.135 195.622 311.845 195.622 C 294.383 195.622 253.081 217.121 278.59 237.339 C 285.417 242.75 302.926 224.633 305.459 219.325 C 306.975 216.148 307.799 212.712 308.536 209.288 C 308.945 207.384 308.868 201.507 308.868 203.454 C 308.868 208.342 308.673 213.27 308.868 218.153 C 308.99 221.217 309.207 222.44 309.753 225.471 C 312.256 239.385 315.474 230.74 316.464 221.652 C 317.306 213.922 316.596 192.85 327.989 194.092 C 330.505 194.366 332.763 200.083 333.878 201.859 C 339.202 210.342 341.458 218.744 340.089 228.803 C 340.022 229.293 337.904 240.303 337.803 240.292 C 336.033 240.112 337.597 236.735 337.348 234.972 C 336.805 231.126 336.035 227.316 335.392 223.486 C 335.292 222.89 330.653 199.952 334.649 198.337 C 335.204 198.113 350.368 207.725 352.518 208.29 C 356.435 209.319 362.282 210.397 366.335 209.304 C 368.315 208.77 369.852 202.073 369.638 204.113 C 367.917 220.513 351.273 236.492 376.017 239.263 C 380.12 239.722 384.769 239.861 388.875 239.518 C 403.542 238.292 414.11 224.33 418.308 211.454 C 419.454 207.937 423.59 190.135 427.799 188.775 C 429.242 188.309 427.301 191.768 427.04 193.263 C 426.978 193.62 426.132 199.169 426.104 199.358 C 424.999 206.931 423.79 214.45 422.501 221.998 C 419.295 240.781 424.373 248.212 405.185 255.701 C 402.127 256.895 398.175 258.172 394.974 258.842 C 389.908 259.903 386.377 260.152 381.131 260.314 C 357.429 261.046 337.825 254.86 314.815 252.444 C 269.741 247.711 222.783 244.845 177.734 251.217 C 159.647 253.775 141.35 262.09 130.533 277.55 C 127.57 281.786 122.824 291.518 125.781 296.933 C 129.493 303.729 141.105 303.258 147.469 302.408 C 165.396 300.016 182.161 288.992 199.816 284.646 C 243.881 273.8 294.734 275.575 339.915 275.575 C 364.36 275.575 392.966 272.789 407.599 295.442"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.7 KiB |
112
05/index.html
Normal file
112
05/index.html
Normal file
File diff suppressed because one or more lines are too long
140
06/animate.js
Normal file
140
06/animate.js
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
|
||||||
|
const WIDTH = 800;
|
||||||
|
const HEIGHT = 800;
|
||||||
|
const NCRITTERS = 10;
|
||||||
|
const CLOSE = 20;
|
||||||
|
const BOUNCE = 0.02;
|
||||||
|
const STUN = 10;
|
||||||
|
const MIN_RADIUS = 2;
|
||||||
|
const HIDE_SPEED = 10.5;
|
||||||
|
|
||||||
|
const pointer = { x: 0, y: 0 };
|
||||||
|
|
||||||
|
const critters = [];
|
||||||
|
|
||||||
|
let lights = "off";
|
||||||
|
|
||||||
|
function dist(c1, c2) {
|
||||||
|
const dx = c1.x - c2.x;
|
||||||
|
const dy = c1.y - c2.y;
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Critter {
|
||||||
|
constructor(i) {
|
||||||
|
this.i = i;
|
||||||
|
this.x = Math.random() * WIDTH;
|
||||||
|
this.y = Math.random() * HEIGHT;
|
||||||
|
this.vx = Math.random() * 0.1 - 0.05;
|
||||||
|
this.vy = Math.random() * 0.1 - 0.05;
|
||||||
|
this.status = "go";
|
||||||
|
}
|
||||||
|
init() {
|
||||||
|
const i0 = `c00${this.i}`;
|
||||||
|
this.elt = document.getElementById(i0);
|
||||||
|
console.log(`elt ${i0} ${this.elt}`);
|
||||||
|
}
|
||||||
|
go_v(pos, vel) {
|
||||||
|
if( pos < 10 ) {
|
||||||
|
return vel + 0.01;
|
||||||
|
} else if ( pos > WIDTH - 10 ) {
|
||||||
|
return vel - 0.01;
|
||||||
|
} else {
|
||||||
|
return vel + Math.random() * 0.01 - 0.005;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update() {
|
||||||
|
if( this.status === "hide" ) {
|
||||||
|
if( this.tick > STUN ) {
|
||||||
|
this.tick--;
|
||||||
|
this.elt.setAttribute("r", this.tick + MIN_RADIUS);
|
||||||
|
} else {
|
||||||
|
this.hide_vec = Math.atan2(this.y - pointer.y, this.x - pointer.x);
|
||||||
|
this.vx = Math.cos(this.hide_vec) * HIDE_SPEED;
|
||||||
|
this.vy = Math.sin(this.hide_vec) * HIDE_SPEED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( this.status === "collide" ) {
|
||||||
|
this.tick--;
|
||||||
|
if( this.tick === 0 ) {
|
||||||
|
this.status = "go";
|
||||||
|
this.elt.setAttribute("fill", "blue");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( this.status === "go" ) {
|
||||||
|
const collisions = critters.filter((c) => c.i != this.i && dist(c, this) < CLOSE);
|
||||||
|
if( collisions.length > 0 ) {
|
||||||
|
const hit = collisions[0];
|
||||||
|
this.status = "collide";
|
||||||
|
this.tick = 20;
|
||||||
|
this.elt.setAttribute("fill", "red");
|
||||||
|
this.vx = (this.x - collisions[0].x) * BOUNCE;
|
||||||
|
this.vy = (this.y - collisions[0].y) * BOUNCE;
|
||||||
|
hit.status = "collide";
|
||||||
|
hit.tick = 20;
|
||||||
|
hit.vx = -this.vx;
|
||||||
|
hit.vy = -this.vy;
|
||||||
|
} else {
|
||||||
|
this.vx = this.go_v(this.x, this.vx);
|
||||||
|
this.vy = this.go_v(this.y, this.vy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.x += this.vx;
|
||||||
|
this.y += this.vy;
|
||||||
|
this.elt.setAttribute("cx", this.x);
|
||||||
|
this.elt.setAttribute("cy", this.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const svg = document.getElementsByTagName("svg")[0];
|
||||||
|
if (svg) { // Check if container exists
|
||||||
|
|
||||||
|
for( let i = 0; i < NCRITTERS; i++ ) {
|
||||||
|
const c = new Critter(i);
|
||||||
|
c.init(i);
|
||||||
|
c.update();
|
||||||
|
critters.push(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.addEventListener("click", () => {
|
||||||
|
const dark = document.getElementById("dark");
|
||||||
|
if( lights === "on" ) {
|
||||||
|
lights = "off";
|
||||||
|
dark.setAttribute("fill-opacity", "0.8");
|
||||||
|
for( const c of critters ) {
|
||||||
|
c.status = "go";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lights = "on";
|
||||||
|
dark.setAttribute("fill-opacity", "0");
|
||||||
|
for( const c of critters ) {
|
||||||
|
c.status = "hide";
|
||||||
|
c.tick = Math.random() * 10 + 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
/* const rect = svg.getBoundingClientRect();
|
||||||
|
const x = pointer.x - rect.left;
|
||||||
|
const y = pointer.y - rect.top;
|
||||||
|
*/ for( const c of critters ) {
|
||||||
|
c.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animate();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
43
06/index.html
Normal file
43
06/index.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>etc.mikelynch.org | Genuary 2026</title>
|
||||||
|
<link rel="stylesheet" href="../styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
<h1>Genuary 2026 - </h1>
|
||||||
|
|
||||||
|
<p>Prompt: Lights on/off. Make something that changes when you switch on or off the “digital” lights.</p>
|
||||||
|
|
||||||
|
<p>Not what I wanted, but I'm on holidays and need to go to bed</p>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<svg width="800" height="800" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect id="dark" x="0" y="0" width="800" height="800" fill="black" fill-opacity="0.8"></rect>
|
||||||
|
<circle id="c000" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c001" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c002" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c003" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c004" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c005" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c006" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c007" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c008" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c009" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<p><a href="../">Back</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="animate.js">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
34
07/genuary07.py
Executable file
34
07/genuary07.py
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
r0 = 2
|
||||||
|
|
||||||
|
print('<svg width="600" height="600" xmlns="http://www.w3.org/2000/svg">')
|
||||||
|
|
||||||
|
cache = {}
|
||||||
|
|
||||||
|
def bool_r(x, y):
|
||||||
|
if x in cache:
|
||||||
|
if y in cache[x]:
|
||||||
|
return cache[x][y]
|
||||||
|
else:
|
||||||
|
cache[x] = {}
|
||||||
|
if x < 1:
|
||||||
|
cache[x][y] = (y % 2 == 1)
|
||||||
|
else:
|
||||||
|
if y < 1:
|
||||||
|
cache[x][y] = (x % 2 == 1)
|
||||||
|
else:
|
||||||
|
a = bool_r(x - 1, y)
|
||||||
|
b = bool_r(x, y - 1)
|
||||||
|
cache[x][y] = (a and not b) or (b and not a)
|
||||||
|
return cache[x][y]
|
||||||
|
|
||||||
|
|
||||||
|
for x in range(128):
|
||||||
|
for y in range(128):
|
||||||
|
cx = r0 + x * r0 * 2
|
||||||
|
cy = r0 + y * r0 * 2
|
||||||
|
if bool_r(x, y):
|
||||||
|
print(f'<circle cx="{cx}" cy="{cy}" r="{r0}" style="fill:blue;"></circle>')
|
||||||
|
|
||||||
|
print("</svg>")
|
||||||
2225
07/index.html
Normal file
2225
07/index.html
Normal file
File diff suppressed because it is too large
Load Diff
35
dist/05/animate.js
vendored
Normal file
35
dist/05/animate.js
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
const pointer = { x: 0, y: 0 };
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
"pointermove",
|
||||||
|
(e) => {
|
||||||
|
pointer.x = e.clientX;
|
||||||
|
pointer.y = e.clientY;
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
const paths = document.getElementsByTagName("path");
|
||||||
|
const svg = document.getElementsByTagName("svg")[0];
|
||||||
|
|
||||||
|
console.log(paths);
|
||||||
|
function animate() {
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
const rect = svg.getBoundingClientRect();
|
||||||
|
const x = pointer.x - rect.left;
|
||||||
|
const y = pointer.y - rect.top;
|
||||||
|
for( const path of paths ) {
|
||||||
|
const i = Number(path.getAttribute("id"));
|
||||||
|
const xk = 0.004 * x;
|
||||||
|
const yk = 0.004 * (y + i - 200);
|
||||||
|
path.setAttribute(
|
||||||
|
"transform", `translate(${x}, ${y}) scale(${xk},${yk}) rotate(${xk * i * 2},20,20)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animate();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
112
dist/05/index.html
vendored
Normal file
112
dist/05/index.html
vendored
Normal file
File diff suppressed because one or more lines are too long
140
dist/06/animate.js
vendored
Normal file
140
dist/06/animate.js
vendored
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
|
||||||
|
const WIDTH = 800;
|
||||||
|
const HEIGHT = 800;
|
||||||
|
const NCRITTERS = 10;
|
||||||
|
const CLOSE = 20;
|
||||||
|
const BOUNCE = 0.02;
|
||||||
|
const STUN = 10;
|
||||||
|
const MIN_RADIUS = 2;
|
||||||
|
const HIDE_SPEED = 10.5;
|
||||||
|
|
||||||
|
const pointer = { x: 0, y: 0 };
|
||||||
|
|
||||||
|
const critters = [];
|
||||||
|
|
||||||
|
let lights = "off";
|
||||||
|
|
||||||
|
function dist(c1, c2) {
|
||||||
|
const dx = c1.x - c2.x;
|
||||||
|
const dy = c1.y - c2.y;
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Critter {
|
||||||
|
constructor(i) {
|
||||||
|
this.i = i;
|
||||||
|
this.x = Math.random() * WIDTH;
|
||||||
|
this.y = Math.random() * HEIGHT;
|
||||||
|
this.vx = Math.random() * 0.1 - 0.05;
|
||||||
|
this.vy = Math.random() * 0.1 - 0.05;
|
||||||
|
this.status = "go";
|
||||||
|
}
|
||||||
|
init() {
|
||||||
|
const i0 = `c00${this.i}`;
|
||||||
|
this.elt = document.getElementById(i0);
|
||||||
|
console.log(`elt ${i0} ${this.elt}`);
|
||||||
|
}
|
||||||
|
go_v(pos, vel) {
|
||||||
|
if( pos < 10 ) {
|
||||||
|
return vel + 0.01;
|
||||||
|
} else if ( pos > WIDTH - 10 ) {
|
||||||
|
return vel - 0.01;
|
||||||
|
} else {
|
||||||
|
return vel + Math.random() * 0.01 - 0.005;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update() {
|
||||||
|
if( this.status === "hide" ) {
|
||||||
|
if( this.tick > STUN ) {
|
||||||
|
this.tick--;
|
||||||
|
this.elt.setAttribute("r", this.tick + MIN_RADIUS);
|
||||||
|
} else {
|
||||||
|
this.hide_vec = Math.atan2(this.y - pointer.y, this.x - pointer.x);
|
||||||
|
this.vx = Math.cos(this.hide_vec) * HIDE_SPEED;
|
||||||
|
this.vy = Math.sin(this.hide_vec) * HIDE_SPEED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( this.status === "collide" ) {
|
||||||
|
this.tick--;
|
||||||
|
if( this.tick === 0 ) {
|
||||||
|
this.status = "go";
|
||||||
|
this.elt.setAttribute("fill", "blue");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( this.status === "go" ) {
|
||||||
|
const collisions = critters.filter((c) => c.i != this.i && dist(c, this) < CLOSE);
|
||||||
|
if( collisions.length > 0 ) {
|
||||||
|
const hit = collisions[0];
|
||||||
|
this.status = "collide";
|
||||||
|
this.tick = 20;
|
||||||
|
this.elt.setAttribute("fill", "red");
|
||||||
|
this.vx = (this.x - collisions[0].x) * BOUNCE;
|
||||||
|
this.vy = (this.y - collisions[0].y) * BOUNCE;
|
||||||
|
hit.status = "collide";
|
||||||
|
hit.tick = 20;
|
||||||
|
hit.vx = -this.vx;
|
||||||
|
hit.vy = -this.vy;
|
||||||
|
} else {
|
||||||
|
this.vx = this.go_v(this.x, this.vx);
|
||||||
|
this.vy = this.go_v(this.y, this.vy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.x += this.vx;
|
||||||
|
this.y += this.vy;
|
||||||
|
this.elt.setAttribute("cx", this.x);
|
||||||
|
this.elt.setAttribute("cy", this.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const svg = document.getElementsByTagName("svg")[0];
|
||||||
|
if (svg) { // Check if container exists
|
||||||
|
|
||||||
|
for( let i = 0; i < NCRITTERS; i++ ) {
|
||||||
|
const c = new Critter(i);
|
||||||
|
c.init(i);
|
||||||
|
c.update();
|
||||||
|
critters.push(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.addEventListener("click", () => {
|
||||||
|
const dark = document.getElementById("dark");
|
||||||
|
if( lights === "on" ) {
|
||||||
|
lights = "off";
|
||||||
|
dark.setAttribute("fill-opacity", "0.8");
|
||||||
|
for( const c of critters ) {
|
||||||
|
c.status = "go";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lights = "on";
|
||||||
|
dark.setAttribute("fill-opacity", "0");
|
||||||
|
for( const c of critters ) {
|
||||||
|
c.status = "hide";
|
||||||
|
c.tick = Math.random() * 10 + 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
/* const rect = svg.getBoundingClientRect();
|
||||||
|
const x = pointer.x - rect.left;
|
||||||
|
const y = pointer.y - rect.top;
|
||||||
|
*/ for( const c of critters ) {
|
||||||
|
c.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animate();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
43
dist/06/index.html
vendored
Normal file
43
dist/06/index.html
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>etc.mikelynch.org | Genuary 2026</title>
|
||||||
|
<link rel="stylesheet" href="../styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
<h1>Genuary 2026 - </h1>
|
||||||
|
|
||||||
|
<p>Prompt: Lights on/off. Make something that changes when you switch on or off the “digital” lights.</p>
|
||||||
|
|
||||||
|
<p>Not what I wanted, but I'm on holidays and need to go to bed</p>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<svg width="800" height="800" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect id="dark" x="0" y="0" width="800" height="800" fill="black" fill-opacity="0.8"></rect>
|
||||||
|
<circle id="c000" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c001" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c002" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c003" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c004" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c005" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c006" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c007" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c008" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
<circle id="c009" r="10" cx="100" cy="100" fill="blue" fill-opacity="0.5"></circle>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<p><a href="../">Back</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="animate.js">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
2225
dist/07/index.html
vendored
Normal file
2225
dist/07/index.html
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
dist/index.html
vendored
3
dist/index.html
vendored
@ -17,6 +17,9 @@ on the Fedivers at <a href="https://old.mermaid.town/@fsvo">@fsvo@old.mermaid.to
|
|||||||
<li><a href="02/">2: twelve principles of animation</a></li>
|
<li><a href="02/">2: twelve principles of animation</a></li>
|
||||||
<li><a href="03/">3: Fibonacci forever</a></li>
|
<li><a href="03/">3: Fibonacci forever</a></li>
|
||||||
<li><a href="04/">4: Low res</a></li>
|
<li><a href="04/">4: Low res</a></li>
|
||||||
|
<li><a href="05/">5: Write "Genuary". Avoid using a font.</a></li>
|
||||||
|
<li><a href="06/">6: Lights on/off.</a></li>
|
||||||
|
<li><a href="07/">7: Boolean algebra</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
28
template.html
Normal file
28
template.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>etc.mikelynch.org | Genuary 2026</title>
|
||||||
|
<link rel="stylesheet" href="../styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
<h1>Genuary 2026 - </h1>
|
||||||
|
|
||||||
|
<p>Prompt: </p>
|
||||||
|
|
||||||
|
<p></p>
|
||||||
|
|
||||||
|
<p><a href="../">Back</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p><a href="https://git.tilde.town/bombinans/genuary2026/src/branch/main/06/genuary05.py">The Python script</p>
|
||||||
|
|
||||||
|
<script src="animate.js">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user