Skip to content

Commit

Permalink
Got a lot farther, but still can't render pixels
Browse files Browse the repository at this point in the history
  • Loading branch information
AtHeartEngineer committed Dec 5, 2022
1 parent 4928cdf commit 557bda8
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 104 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/
target/
dist/
15 changes: 13 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
name = "animated-background"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.htm
description = "A simple animated background for your website"
repository = "https://github.com/AtHeartEngineer/animated_background"
license = "MIT"
authors = ["AtHeartEngineer"]

[lib]
crate-type = ["cdylib"]

[dependencies]
js-sys = "0.3.60"
wasm-bindgen = "0.2.83"
console_error_panic_hook = "0.1.7"

[dependencies.web-sys]
version = "0.3.60"
features = [
'console',
'CanvasRenderingContext2d',
'Document',
'Element',
Expand Down
18 changes: 18 additions & 0 deletions bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as wasm from "./pkg/index_bg.wasm";
wasm.init_panic_hook();
document.body.style.margin = 0;
let canvas = document.getElementById("bg-canvas");
let ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
let universe = wasm.universe_new(ctx);

const renderLoop = () => {
debugger;
wasm.universe_tick(universe).catch(console.error);
requestAnimationFrame(renderLoop);
};

renderLoop();
9 changes: 3 additions & 6 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
<!DOCTYPE html>
<html>

<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
<title>Animated Background Demo</title>
</head>

<body>
<canvas id="bg-canvas" style="position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;"></canvas>
<canvas id="bg-canvas"></canvas>
</body>

</html>
4 changes: 0 additions & 4 deletions index.js

This file was deleted.

245 changes: 165 additions & 80 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,106 +1,191 @@
use std::f64;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::CanvasRenderingContext2d;
extern crate console_error_panic_hook;

const DENSITY: u8 = 100; // lower = more dense
const HUE_START: u8 = 120;
const HUE_END: u8 = 230;
const MAX_SIZE: u8 = 3;
const MIN_LIGHT: u8 = 33;
const MAX_LIGHT: u8 = 67;
const MIN_TRANSPARENCY: u8 = 10;
const MAX_TRANSPARENCY: u8 = 60;
const SATURATION: u8 = 100;
const START_ANGLE: u8 = 240;
const END_ANGLE: u8 = 300;
const MAX_SPEED: u8 = 20;

#[wasm_bindgen(start)]
pub fn start() {
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
let canvas = document.get_element_by_id("bg-canvas").unwrap();
let canvas: web_sys::HtmlCanvasElement = canvas
.dyn_into::<web_sys::HtmlCanvasElement>()
.map_err(|_| ())
.unwrap();
const DENSITY: usize = 100; // lower = more dense
const HUE_START: usize = 120;
const HUE_END: usize = 230;
const MAX_SIZE: usize = 3;
const MIN_LIGHT: usize = 33;
const MAX_LIGHT: usize = 67;
const MIN_TRANSPARENCY: usize = 10;
const MAX_TRANSPARENCY: usize = 60;
const SATURATION: usize = 100;
const START_ANGLE: usize = 240;
const END_ANGLE: usize = 300;
const MAX_SPEED: usize = 20;

let ctx = canvas
.get_context("2d")
.unwrap()
.unwrap()
.dyn_into::<web_sys::CanvasRenderingContext2d>()
.unwrap();
// A macro to provide `println!(..)`-style syntax for `console.log` logging.
macro_rules! log {
( $( $t:tt )* ) => {
web_sys::console::log_1(&format!( $( $t )* ).into());
}
}

let mut num_bits: u32 = 0;
let mut bits: Vec<&Bit> = Vec::new();
let mut canvas_width: u32 = 0;
let mut canvas_height: u32 = 0;
resizeCanvas(&canvas, &canvas_width, &canvas_height, &num_bits, &bits);

window.set_onresize(Some(&resizeCanvas(
&canvas,
&canvas_width,
&canvas_height,
&num_bits,
&bits,
)));
#[wasm_bindgen]
pub fn init_panic_hook() {
console_error_panic_hook::set_once();
}

pub fn draw(context: CanvasRenderingContext2d, width: &f64, height: &f64) {
todo!()
#[wasm_bindgen]
pub struct Universe {
context: CanvasRenderingContext2d,
width: usize,
height: usize,
num_bits: usize,
bits: Vec<Bit>,
}

#[wasm_bindgen]
impl Universe {
pub fn new(context: CanvasRenderingContext2d) -> Self {
init_panic_hook();
let (width, height) = get_window_size();
log!("Window Size: {}x{}", width, height);
let num_bits = (width as f32 * height as f32 / DENSITY.pow(2) as f32).floor() as usize;
log!("Number of Bits: {}", num_bits);
let bits = (0..num_bits).map(|_| Bit::new(&width, &height)).collect();
log!("Bits Created");
Self {
context,
width,
height,
num_bits,
bits,
}
}

fn set_num_bits(&mut self) {
self.num_bits =
(self.width as f32 * self.height as f32 / DENSITY.pow(2) as f32).floor() as usize;
}

fn set_size(&mut self) {
(self.width, self.height) = get_window_size();
self.set_num_bits();
}

fn generate_bits(&mut self) {
self.bits = (0..self.num_bits)
.map(|_| Bit::new(&self.width, &self.height))
.collect();
}

pub fn tick(&mut self) {
for bit in &mut self.bits {
bit.tick(&self.width, &self.height);
}
self.draw();
}

fn draw(&mut self) {
self.reset_canvas();
// for bit in &self.bits {
// bit.draw(&self.context);
// }
}

pub fn reset_canvas(&mut self) {
let (width, height) = get_window_size();
if (width != self.width) || (height != self.height) {
self.width = width;
self.height = height;
self.set_num_bits();
}
self.context.begin_path();
let fill_style = self.context.fill_style().as_string().unwrap();
log!("{}", fill_style);
self.context.set_fill_style(&"rgb(0,0,0)".into());
self.context
.fill_rect(0.0, 0.0, width as f64, height as f64);
self.context
.clear_rect(0.0, 0.0, self.width as f64, self.height as f64);
self.context.stroke();
}
}

#[derive(Clone)]
pub struct Bit {
pub x: f64,
pub y: f64,
pub radius: f64,
pub color: String,
pub speed: f64,
pub angle: f64,
pub x: isize,
pub y: isize,
pub size: usize,
pub hue: usize,
pub saturation: usize,
pub lightness: usize,
pub transparency: usize,
pub speed: usize,
pub angle: f32,
}

impl Bit {
pub fn new(x: f64, y: f64, radius: f64, color: String, speed: f64, angle: f64) -> Bit {
pub fn new(width: &usize, height: &usize) -> Bit {
let x = random_range(0, *width) as isize;
let y = random_range(0, *height) as isize;
let size = random_range(1, random_range(1, MAX_SIZE));
let hue = random_range(HUE_START, HUE_END);
let lightness = random_range(MIN_LIGHT, MAX_LIGHT);
let saturation = SATURATION;
let transparency = random_range(MIN_TRANSPARENCY, MAX_TRANSPARENCY);
let angle = random_range(START_ANGLE, END_ANGLE) as f32;
let speed = (random_range(1, MAX_SPEED) as f32 * 0.025) as usize;
Bit {
x,
y,
radius,
color,
size,
hue,
saturation,
lightness,
transparency,
speed,
angle,
}
}

// Move is a keyword in rust, so we are escaping it here
pub fn r#move(&mut self, width: &f64, height: &f64) {
self.x += self.speed * self.angle.cos(); // not sure if this is expecting radians or degrees
self.y += self.speed * self.angle.sin();
if self.x < 0.0 {
self.x = *width;
} else if self.x > *width {
self.x = 0.0;
pub fn tick(&mut self, width: &usize, height: &usize) {
self.x += (self.speed as f32 * self.angle.cos()) as isize; // not sure if this is expecting radians or degrees
self.y += (self.speed as f32 * self.angle.sin()) as isize;
if self.x < 0 {
self.x = *width as isize;
} else if self.x > *width as isize {
self.x = 0;
}
if self.y < 0.0 {
self.y = *height;
} else if self.y > *height {
self.y = 0.0;
if self.y < 0 {
self.y = *height as isize;
} else if self.y > *height as isize {
self.y = 0;
}
}

pub fn draw(&self, ctx: &CanvasRenderingContext2d) {
log!("Drawing Bit");
ctx.set_fill_style(
&format!(
"hsla({}, {}%, {}%, {})",
self.hue, self.saturation, self.lightness, self.transparency
)
.into(),
);
ctx.begin_path();
ctx.arc(
self.x as f64,
self.y as f64,
self.size as f64,
0.0,
2.0 * std::f64::consts::PI,
)
.unwrap();
ctx.fill();
}
}

pub fn generateBits() {
todo!()
pub fn resize_canvas(canvas: &web_sys::HtmlCanvasElement) {
let (width, height) = get_window_size();
canvas.set_width(width as u32);
canvas.set_height(height as u32);
log!("Canvas Resized to {}x{}", width, height);
}

pub fn resizeCanvas(
canvas: &web_sys::HtmlCanvasElement,
width: &u32,
height: &u32,
num_bits: &u32,
bits: &Vec<&Bit>,
) {
pub fn get_window_size() -> (usize, usize) {
let width = web_sys::window()
.unwrap()
.inner_width()
Expand All @@ -113,9 +198,9 @@ pub fn resizeCanvas(
.unwrap()
.as_f64()
.unwrap();
canvas.set_width(width as u32);
canvas.set_height(height as u32);
num_bits = &((width as f32 * height as f32 / DENSITY as f32 / DENSITY as f32).floor() as u32);
bits = &Vec::new();
generateBits();
(width as usize, height as usize)
}

pub fn random_range(min: usize, max: usize) -> usize {
js_sys::Math::random() as usize * (max - min) + min
}
Loading

0 comments on commit 557bda8

Please sign in to comment.