Compare commits
10 Commits
f3ae7860a5
...
1bfcf5ac27
Author | SHA1 | Date | |
---|---|---|---|
1bfcf5ac27 | |||
2b8fdf669d | |||
eeff471c96 | |||
7150be9dfb | |||
5f5d299421 | |||
c5876c87e1 | |||
e336a48fd2 | |||
25629dd65e | |||
f8f9934833 | |||
26e4296596 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,4 @@
|
|||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
|
eng240-twine
|
||||||
|
feels
|
||||||
|
23
hidepage.js
Normal file
23
hidepage.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
function hide_page() {
|
||||||
|
// to unhide the hidden element, we also need to un-ID it
|
||||||
|
// to make the CSS rule stop applying
|
||||||
|
// janky hack, but it makes it not have 1 frame of showing on load.
|
||||||
|
hidden.id = '';
|
||||||
|
hidden.style.display = '';
|
||||||
|
shown.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
function unhide_page() {
|
||||||
|
shown.style.display = '';
|
||||||
|
hidden.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
var shown = document.getElementById("page-content");
|
||||||
|
var hidden = document.getElementById("page-content-hidden");
|
||||||
|
|
||||||
|
document
|
||||||
|
.getElementById("button-hide-page")
|
||||||
|
.addEventListener("click", hide_page);
|
||||||
|
document
|
||||||
|
.getElementById("button-unhide-page")
|
||||||
|
.addEventListener("click", unhide_page);
|
BIN
inconsolata.ttf
Normal file
BIN
inconsolata.ttf
Normal file
Binary file not shown.
70
index.html
70
index.html
@ -1,17 +1,61 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
|
||||||
<title>control the walker!</title>
|
|
||||||
<link rel="stylesheet" href="walkers.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>this page is wildly in-progress</h1>
|
|
||||||
<p>as in i am repeatedly breaking stuff all the time</p>
|
|
||||||
<p>code modified from <a href="https://jackmckew.dev/interactive-random-walkers-with-javascript.html">https://jackmckew.dev/interactive-random-walkers-with-javascript.html</a></p>
|
|
||||||
|
|
||||||
<div id="canvas-container">
|
<head>
|
||||||
<canvas id="walker-canvas"></canvas>
|
<title>shoe says hi!</title>
|
||||||
</div>
|
<link rel="stylesheet" href="walkers.css">
|
||||||
</body>
|
</head>
|
||||||
<script src="walkers.js" walkers></script>
|
<body>
|
||||||
|
|
||||||
|
<div id="page-content">
|
||||||
|
<h1>this page wildly under construction</h1>
|
||||||
|
<p>aka i am gonna be repeatedly redoing like everything</p>
|
||||||
|
|
||||||
|
<div id="hi">
|
||||||
|
<h1>hi, i'm shoe.</h1>
|
||||||
|
<p>i hope you like this place!</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="about-shoe">
|
||||||
|
<h1>about shoe</h1>
|
||||||
|
<ul>
|
||||||
|
<li>they/them</li>
|
||||||
|
<li>i like sysadmin</li>
|
||||||
|
<li>TODO: I really need this section to not read like garbo<li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="controls">
|
||||||
|
<h1>controls</h1>
|
||||||
|
<p>mess with the random walkers</p>
|
||||||
|
<ul>
|
||||||
|
<li><button id="button-create-walker">create one</button></li>
|
||||||
|
<li><button id="button-destroy-walker">kill one :(</button></li>
|
||||||
|
<li><button id="button-reset-walkers">kill them all D:</button></li>
|
||||||
|
</ul>
|
||||||
|
<p>if you want, you can <button id="button-hide-page">hide</button> the page to just watch the random walk</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="inspiration">
|
||||||
|
<h1>inspiration</h1>
|
||||||
|
<p>gotta cite your sources >w<</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/~nebula"> ~nebula's homepage</a> is beautiful and convinced me to make a lot of empty space, including the right-aligned elements</li>
|
||||||
|
<li><a href="https://jackmckew.dev/interactive-random-walkers-with-javascript.html" target="_blank">Jack McKew's blogpost</a> about random walkers in js was my starting point, even though mine looks nothing like theirs</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="page-content-hidden">
|
||||||
|
<button id="button-unhide-page">unhide</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- this is the canvas that makes up the page background -->
|
||||||
|
<div id="canvas-container">
|
||||||
|
<canvas id="walker-canvas"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<script src="walkers.js" walkers></script>
|
||||||
|
<script src="hidepage.js" hidepage></script>
|
||||||
</html>
|
</html>
|
||||||
|
53
style.css
Normal file
53
style.css
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/* load font from local file because fuck yeah */
|
||||||
|
@font-face {
|
||||||
|
font-family: inconsolata;
|
||||||
|
src: url("inconsolata.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #22241f;
|
||||||
|
color: #d7fcc2;
|
||||||
|
font-family: inconsolata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make <pre> match overall font and size */
|
||||||
|
pre {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* change ul bullet points to dashes for ~style~
|
||||||
|
* derived from https://www.w3schools.com/cssref/pr_list-style-type.php */
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 16px;
|
||||||
|
}
|
||||||
|
ul > li::before {
|
||||||
|
content: "-";
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* style the page banner/signature thing to be big and bold */
|
||||||
|
#banner {
|
||||||
|
font-size: large;
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* recolor links to still be blue and purple,
|
||||||
|
* but be visible against the dark bg */
|
||||||
|
a {
|
||||||
|
color: #64adf1;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
color: #a76ff5;
|
||||||
|
}
|
||||||
|
a:active {
|
||||||
|
color: #ff0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* style tilde.town ring appropriately */
|
||||||
|
#tilde_ring {
|
||||||
|
background-color: black;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
@ -24,3 +24,7 @@ body {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
background: black;
|
background: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page-content-hidden {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
228
walkers.js
228
walkers.js
@ -1,12 +1,66 @@
|
|||||||
var constants = {
|
/***************************************************************************
|
||||||
step_time: 200,
|
* Buttons that interact with the UI *
|
||||||
cell_size: 22,
|
****************************************************************************/
|
||||||
color: "#FFB000",
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// a rainbow-adjacent set of colors for the walkers to cycle through
|
||||||
|
var walker_colors = [
|
||||||
|
"#ffb000", // amber, from https://superuser.com/a/1206781
|
||||||
|
"#ff7700", // orange
|
||||||
|
"#33ff00", // green, also from https://superuser.com/a/1206781
|
||||||
|
"#004cff", // blue
|
||||||
|
"#8500ff", // purple
|
||||||
|
"#ff2e00", // red
|
||||||
|
];
|
||||||
|
var color_idx = 0;
|
||||||
|
|
||||||
|
// create a new walker with random position and color
|
||||||
|
function create_new_walker() {
|
||||||
|
// create random-param walker and add to the array
|
||||||
|
var my_row = Math.floor(Math.random() * n_rows);
|
||||||
|
var my_col = Math.floor(Math.random() * n_cols);
|
||||||
|
var my_color = walker_colors[color_idx];
|
||||||
|
var new_length = walkers.push({row: my_row, col: my_col, color: my_color});
|
||||||
|
|
||||||
|
// decide how fast this walker updates and push that to the interval array
|
||||||
|
var update_time = random_update_time();
|
||||||
|
var timer = setInterval((function() {
|
||||||
|
update_walker(walkers[new_length - 1]);
|
||||||
|
}), update_time);
|
||||||
|
walker_timers.push(timer);
|
||||||
|
|
||||||
|
// go to the next color
|
||||||
|
color_idx = (color_idx + 1).mod(walker_colors.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// choose a random walker to kill. does not kill the trail.
|
||||||
|
function destroy_random_walker() {
|
||||||
|
// choose a random walker to destroy, draw black over its location.
|
||||||
|
var choice = Math.floor(Math.random() * walkers.length);
|
||||||
|
var removed = walkers.splice(choice, 1)[0];
|
||||||
|
draw_grid_square(removed.row, removed.col, "black");
|
||||||
|
|
||||||
|
// also stop its timer
|
||||||
|
var removed_timer = walker_timers.splice(choice, 1)[0];
|
||||||
|
clearInterval(removed_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// kill all walkers, but not their trails.
|
||||||
|
function destroy_all_walkers() {
|
||||||
|
// delete all walkers, draw black where they used to be
|
||||||
|
var removed = walkers.splice(0, walkers.length);
|
||||||
|
for (var i = 0; i < removed.length; i++) {
|
||||||
|
draw_grid_square(removed[i].row, removed[i].col, "black");
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop all timers as well
|
||||||
|
var removed_timers = walker_timers.splice(0, walker_timers.length);
|
||||||
|
for (var i = 0; i < removed_timers.length; i++) {
|
||||||
|
clearInterval(removed_timers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* TODO: CATEOGORIZE THESE BULLSHITS *
|
* Functions JS doesn't want you to have, ig *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
// Define a new mod function that behaves different on negatives.
|
// Define a new mod function that behaves different on negatives.
|
||||||
@ -27,11 +81,18 @@ Number.prototype.div = function(divisor) {
|
|||||||
* Random walk implementation (movement functions) *
|
* Random walk implementation (movement functions) *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
// return a random update time. 25 to 175ms in increments of 50
|
||||||
|
function random_update_time() {
|
||||||
|
var speed = Math.floor(Math.random() * 4);
|
||||||
|
return (speed * 50) + 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start up the functions that run FOREVER!!!
|
||||||
function init_walk() {
|
function init_walk() {
|
||||||
// Draw a grid of boxes on the canvas
|
setInterval(update_trails, 200);
|
||||||
setInterval(draw, 20);
|
|
||||||
// TODO: it would be cool to have this changable, but I may just ... not
|
// create an initial walker. also creates its timer with setInterval.
|
||||||
setInterval(move_walker, constants.step_time);
|
create_new_walker();
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the trails array has a position.
|
// check if the trails array has a position.
|
||||||
@ -46,7 +107,33 @@ function trails_find_position(row, col) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function move_walker() {
|
// update and draw all trails in the array
|
||||||
|
function update_trails() {
|
||||||
|
// for all existing trails, make them darker
|
||||||
|
for (var i = 0; i < trails.length; i++) {
|
||||||
|
var darker = tweak_color_luminance(trails[i].color, -0.1);
|
||||||
|
trails[i].color = darker;
|
||||||
|
|
||||||
|
// delete any trails with 0 for first digit of RGB
|
||||||
|
// (think of them as near-black)
|
||||||
|
// e.g. #050500
|
||||||
|
if (darker[1] === "0" && darker[3] == "0" && darker[5] == "0") {
|
||||||
|
// draw black, just so we don't leave behind an almost-black square
|
||||||
|
draw_grid_square(trails[i].row, trails[i].col, "black");
|
||||||
|
|
||||||
|
// delete the item from the array
|
||||||
|
trails.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// after all trails have been darkened/removed, draw the remaining ones
|
||||||
|
for (var i = 0; i < trails.length; i++) {
|
||||||
|
draw_grid_square(trails[i].row, trails[i].col, trails[i].color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update and draw all walkers in the array
|
||||||
|
function update_walker(walker) {
|
||||||
// leave a trail behind
|
// leave a trail behind
|
||||||
var index = trails_find_position(walker.row, walker.col);
|
var index = trails_find_position(walker.row, walker.col);
|
||||||
if (index) {
|
if (index) {
|
||||||
@ -55,42 +142,28 @@ function move_walker() {
|
|||||||
trails.push({row: walker.row, col: walker.col, color: walker.color});
|
trails.push({row: walker.row, col: walker.col, color: walker.color});
|
||||||
}
|
}
|
||||||
|
|
||||||
// for all existing trails, make them darker
|
|
||||||
for (var i = 0; i < trails.length; i++) {
|
|
||||||
var t = trails[i];
|
|
||||||
t.color = tweak_color_luminance(t.color, -0.1);
|
|
||||||
|
|
||||||
// delete any trails with 0 for first digit of RGB
|
|
||||||
// (think of them as near-black)
|
|
||||||
// e.g. #050500
|
|
||||||
if (t.color[1] === "0" && t.color[3] == "0" && t.color[5] == "0") {
|
|
||||||
// draw black there just to be safe
|
|
||||||
draw_grid_square(t.row, t.col, "black");
|
|
||||||
|
|
||||||
// delete the item from the array
|
|
||||||
trails.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`${trails.length} items in trails array`);
|
|
||||||
|
|
||||||
// move in random dir
|
// move in random dir
|
||||||
add_random_direction(walker);
|
add_random_direction(walker);
|
||||||
|
|
||||||
|
// draw a colored square at walker locations
|
||||||
|
draw_grid_square(walker.row, walker.col, walker.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_random_direction(pos) {
|
// give this function a walker and it will update the walkerition by one tile
|
||||||
|
function add_random_direction(walker) {
|
||||||
let rand = Math.floor(Math.random() * 4);
|
let rand = Math.floor(Math.random() * 4);
|
||||||
if (rand === 0) {
|
if (rand === 0) {
|
||||||
pos.row++;
|
walker.row++;
|
||||||
pos.row = pos.row.mod(n_rows);
|
walker.row = walker.row.mod(n_rows);
|
||||||
} else if (rand === 1) {
|
} else if (rand === 1) {
|
||||||
pos.row--;
|
walker.row--;
|
||||||
pos.row = pos.row.mod(n_rows);
|
walker.row = walker.row.mod(n_rows);
|
||||||
} else if (rand === 2) {
|
} else if (rand === 2) {
|
||||||
pos.col++;
|
walker.col++;
|
||||||
pos.col = pos.col.mod(n_cols);
|
walker.col = walker.col.mod(n_cols);
|
||||||
} else {
|
} else {
|
||||||
pos.col--;
|
walker.col--;
|
||||||
pos.col = pos.col.mod(n_cols);
|
walker.col = walker.col.mod(n_cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,69 +191,66 @@ function tweak_color_luminance(hex, lum) {
|
|||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
// when called, fixes the canvas and grid size. will cause the canvas to go
|
||||||
// pixel width and height
|
// black until it's drawn again, though.
|
||||||
var old_width = ctx.canvas.width;
|
function fix_grid_size() {
|
||||||
var old_height = ctx.canvas.height;
|
// note: changing width and height clears the canvas, so this will cause a
|
||||||
|
// black screen until the next draw call for each thing.
|
||||||
canvas.width = window.innerWidth;
|
canvas.width = window.innerWidth;
|
||||||
canvas.height = window.innerHeight;
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
if (old_width !== canvas.width || old_height != canvas.height) {
|
// update all the globals we're using too
|
||||||
var old_n_rows = n_rows;
|
n_rows = canvas.height.div(cell_size);
|
||||||
var old_n_cols = n_cols;
|
n_cols = canvas.width.div(cell_size);
|
||||||
n_rows = canvas.height.div(constants.cell_size);
|
offset_h = (canvas.width - (cell_size * n_cols)).div(2);
|
||||||
n_cols = canvas.width.div(constants.cell_size);
|
offset_v = (canvas.height - (cell_size * n_rows)).div(2);
|
||||||
offset_h = (canvas.width - (constants.cell_size * n_cols)).div(2);
|
|
||||||
offset_v = (canvas.height - (constants.cell_size * n_rows)).div(2);
|
|
||||||
offset = {h: offset_h, v: offset_v};
|
|
||||||
// TODO: for every walker and every trail, adjust their position to the new canvas size
|
|
||||||
// we wanna just mod it, probably. that way if you shrink it you don't
|
|
||||||
// lose anything.
|
|
||||||
|
|
||||||
// TODO: HANDLE RESIZE
|
|
||||||
console.log(`dimensions changed from ${old_width}x${old_height} to ${ctx.canvas.width}x${ctx.canvas.height}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw a colored square at the walker location
|
|
||||||
draw_grid_square(walker.row, walker.col, walker.color);
|
|
||||||
|
|
||||||
// for any trails, draw them
|
|
||||||
for (var i = 0; i < trails.length; i++) {
|
|
||||||
t = trails[i];
|
|
||||||
draw_grid_square(t.row, t.col, t.color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO CODE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw on the canvas a grid square of that color
|
||||||
function draw_grid_square(row, col, color) {
|
function draw_grid_square(row, col, color) {
|
||||||
var margin = 2;
|
var margin = 2;
|
||||||
|
var pos_h = offset_h + (cell_size * col) + margin;
|
||||||
|
var pos_v = offset_v + (cell_size * row) + margin;
|
||||||
|
|
||||||
ctx.fillStyle = color;
|
ctx.fillStyle = color;
|
||||||
var pos_h = offset.h + (constants.cell_size * col) + margin;
|
ctx.fillRect(pos_h, pos_v, cell_size - (2*margin), cell_size - (2*margin));
|
||||||
var pos_v = offset.v + (constants.cell_size * row) + margin;
|
|
||||||
|
|
||||||
ctx.fillRect(pos_h, pos_v, constants.cell_size - (2*margin), constants.cell_size - (2*margin));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* ON SCRIPT LOAD *
|
* ON SCRIPT LOAD *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
// "make sure to eat up your globals honey, they're good for you"
|
||||||
|
|
||||||
// find the canvas and set its initial size
|
// find the canvas and set its initial size
|
||||||
var canvas = document.getElementById("walker-canvas")
|
var canvas = document.getElementById("walker-canvas")
|
||||||
var ctx = canvas.getContext('2d')
|
var ctx = canvas.getContext('2d')
|
||||||
canvas.width = window.innerWidth;
|
canvas.width = window.innerWidth;
|
||||||
canvas.height = window.innerHeight;
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
|
// set up a handler so the grid gets fixed whenever the window resizes
|
||||||
|
window.addEventListener('resize', fix_grid_size);
|
||||||
|
|
||||||
|
// find the UI buttons and give them click handlers to activate our functions
|
||||||
|
document
|
||||||
|
.getElementById("button-create-walker")
|
||||||
|
.addEventListener("click", create_new_walker);
|
||||||
|
document
|
||||||
|
.getElementById("button-destroy-walker")
|
||||||
|
.addEventListener("click", destroy_random_walker);
|
||||||
|
document
|
||||||
|
.getElementById("button-reset-walkers")
|
||||||
|
.addEventListener("click", destroy_all_walkers);
|
||||||
|
|
||||||
// compute the initial rows and columns
|
// compute the initial rows and columns
|
||||||
var n_rows = canvas.height.div(constants.cell_size);
|
var cell_size = 22;
|
||||||
var n_cols = canvas.width.div(constants.cell_size);
|
var n_rows = canvas.height.div(cell_size);
|
||||||
var offset_h = (canvas.width - (constants.cell_size * n_cols)).div(2);
|
var n_cols = canvas.width.div(cell_size);
|
||||||
var offset_v = (canvas.height - (constants.cell_size * n_rows)).div(2);
|
var offset_h = (canvas.width - (cell_size * n_cols)).div(2);
|
||||||
var offset = {h: offset_h, v: offset_v};
|
var offset_v = (canvas.height - (cell_size * n_rows)).div(2);
|
||||||
|
|
||||||
// set start position of walker and start the random walk
|
// set start position of walker and start the random walk
|
||||||
var walker = {row: n_rows.div(2), col: n_cols.div(2), color: constants.color};
|
var walkers = [];
|
||||||
trails = []
|
var walker_timers = [];
|
||||||
|
var trails = []
|
||||||
init_walk();
|
init_walk();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user