Compare commits

..

10 Commits

7 changed files with 289 additions and 92 deletions

3
.gitignore vendored
View File

@ -1 +1,4 @@
*.swp
eng240-twine
feels

23
hidepage.js Normal file
View 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

Binary file not shown.

View File

@ -1,17 +1,61 @@
<!doctype 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">
<canvas id="walker-canvas"></canvas>
</div>
</body>
<script src="walkers.js" walkers></script>
<head>
<title>shoe says hi!</title>
<link rel="stylesheet" href="walkers.css">
</head>
<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>

53
style.css Normal file
View 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;
}

View File

@ -24,3 +24,7 @@ body {
height: 100%;
background: black;
}
#page-content-hidden {
display:none;
}

View File

@ -1,12 +1,66 @@
var constants = {
step_time: 200,
cell_size: 22,
color: "#FFB000",
};
/***************************************************************************
* Buttons that interact with the UI *
****************************************************************************/
// 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.
@ -27,11 +81,18 @@ Number.prototype.div = function(divisor) {
* 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() {
// Draw a grid of boxes on the canvas
setInterval(draw, 20);
// TODO: it would be cool to have this changable, but I may just ... not
setInterval(move_walker, constants.step_time);
setInterval(update_trails, 200);
// create an initial walker. also creates its timer with setInterval.
create_new_walker();
}
// check if the trails array has a position.
@ -46,7 +107,33 @@ function trails_find_position(row, col) {
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
var index = trails_find_position(walker.row, walker.col);
if (index) {
@ -55,42 +142,28 @@ function move_walker() {
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
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);
if (rand === 0) {
pos.row++;
pos.row = pos.row.mod(n_rows);
walker.row++;
walker.row = walker.row.mod(n_rows);
} else if (rand === 1) {
pos.row--;
pos.row = pos.row.mod(n_rows);
walker.row--;
walker.row = walker.row.mod(n_rows);
} else if (rand === 2) {
pos.col++;
pos.col = pos.col.mod(n_cols);
walker.col++;
walker.col = walker.col.mod(n_cols);
} else {
pos.col--;
pos.col = pos.col.mod(n_cols);
walker.col--;
walker.col = walker.col.mod(n_cols);
}
}
@ -118,69 +191,66 @@ function tweak_color_luminance(hex, lum) {
return rgb;
}
function draw() {
// pixel width and height
var old_width = ctx.canvas.width;
var old_height = ctx.canvas.height;
// when called, fixes the canvas and grid size. will cause the canvas to go
// black until it's drawn again, though.
function fix_grid_size() {
// 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.height = window.innerHeight;
if (old_width !== canvas.width || old_height != canvas.height) {
var old_n_rows = n_rows;
var old_n_cols = n_cols;
n_rows = canvas.height.div(constants.cell_size);
n_cols = canvas.width.div(constants.cell_size);
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
// update all the globals we're using too
n_rows = canvas.height.div(cell_size);
n_cols = canvas.width.div(cell_size);
offset_h = (canvas.width - (cell_size * n_cols)).div(2);
offset_v = (canvas.height - (cell_size * n_rows)).div(2);
}
// draw on the canvas a grid square of that color
function draw_grid_square(row, col, color) {
var margin = 2;
var pos_h = offset_h + (cell_size * col) + margin;
var pos_v = offset_v + (cell_size * row) + margin;
ctx.fillStyle = color;
var pos_h = offset.h + (constants.cell_size * col) + 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));
ctx.fillRect(pos_h, pos_v, cell_size - (2*margin), cell_size - (2*margin));
}
/****************************************************************************
* ON SCRIPT LOAD *
****************************************************************************/
// "make sure to eat up your globals honey, they're good for you"
// find the canvas and set its initial size
var canvas = document.getElementById("walker-canvas")
var ctx = canvas.getContext('2d')
canvas.width = window.innerWidth;
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
var n_rows = canvas.height.div(constants.cell_size);
var n_cols = canvas.width.div(constants.cell_size);
var offset_h = (canvas.width - (constants.cell_size * n_cols)).div(2);
var offset_v = (canvas.height - (constants.cell_size * n_rows)).div(2);
var offset = {h: offset_h, v: offset_v};
var cell_size = 22;
var n_rows = canvas.height.div(cell_size);
var n_cols = canvas.width.div(cell_size);
var offset_h = (canvas.width - (cell_size * n_cols)).div(2);
var offset_v = (canvas.height - (cell_size * n_rows)).div(2);
// 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};
trails = []
var walkers = [];
var walker_timers = [];
var trails = []
init_walk();