From 357a7f0e55e9f791c76ec652b0c14a693bf48301 Mon Sep 17 00:00:00 2001 From: Nick Baker Date: Sat, 5 Aug 2023 14:24:13 -0700 Subject: [PATCH] convert moves to Js `Array` + UI --- Cargo.lock | 1 + string-bean-wasm/Cargo.toml | 1 + string-bean-wasm/src/lib.rs | 56 ++++-- web/src/lib/utils.js | 56 ++++++ web/src/routes/+page.svelte | 340 +++++++++++++++++++----------------- 5 files changed, 282 insertions(+), 172 deletions(-) create mode 100644 web/src/lib/utils.js diff --git a/Cargo.lock b/Cargo.lock index 07d9152..d4a1944 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -648,6 +648,7 @@ dependencies = [ name = "string-bean-wasm" version = "0.1.0" dependencies = [ + "js-sys", "string-bean", "wasm-bindgen", ] diff --git a/string-bean-wasm/Cargo.toml b/string-bean-wasm/Cargo.toml index d634eff..2001485 100644 --- a/string-bean-wasm/Cargo.toml +++ b/string-bean-wasm/Cargo.toml @@ -9,5 +9,6 @@ crate-type = ["cdylib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +js-sys = "0.3.64" string-bean = { path = "../string-bean" } wasm-bindgen = "0.2.87" diff --git a/string-bean-wasm/src/lib.rs b/string-bean-wasm/src/lib.rs index 8f6b865..6db36ce 100644 --- a/string-bean-wasm/src/lib.rs +++ b/string-bean-wasm/src/lib.rs @@ -1,7 +1,9 @@ use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; +type ReturnArray = js_sys::Array; + #[wasm_bindgen] -pub fn plan_as_json( +pub fn json_plan_circle( line_count: u32, line_opacity: f32, anchor_count: u32, @@ -12,7 +14,7 @@ pub fn plan_as_json( height: usize, image_buffer: &[u8], start_anchor: usize, -) -> JsValue { +) -> ReturnArray { let (x_mid, y_mid) = (width / 2, height / 2); let radius = radius.min(x_mid.min(y_mid)) as f64; @@ -37,18 +39,48 @@ pub fn plan_as_json( image_buffer, ); - let moves = planner + planner .get_moves(start_anchor, line_count as _) - .unwrap_or(Vec::new()); + .unwrap_or(Vec::new()) + .into_iter() + .map(JsValue::from) + .collect() +} + +#[wasm_bindgen] +pub fn json_plan( + line_count: u32, + line_opacity: f32, + anchor_list: &[f64], + anchor_gap_count: usize, + penalty: f32, + width: usize, + height: usize, + image_buffer: &[u8], + start_anchor: usize, +) -> ReturnArray { + let anchors = anchor_list + .chunks_exact(2) + .map(|chunk| (chunk[0], chunk[1])) + .collect::>(); - JsValue::from_str(&format!( - "[{}]", - moves - .iter() - .map(usize::to_string) - .collect::>() - .join(","), - )) + let mut planner = string_bean::ThreadPlanner::new( + line_opacity as _, + &anchors, + anchor_gap_count, + penalty as _, + grid_raytrace, + width, + height, + image_buffer, + ); + + planner + .get_moves(start_anchor, line_count as _) + .unwrap_or(Vec::new()) + .into_iter() + .map(JsValue::from) + .collect() } /// https://playtechs.blogspot.com/2007/03/raytracing-on-grid.html diff --git a/web/src/lib/utils.js b/web/src/lib/utils.js new file mode 100644 index 0000000..093e1f4 --- /dev/null +++ b/web/src/lib/utils.js @@ -0,0 +1,56 @@ +/** + * Compute anchors for a circle + * @param {number} anchor_count + * @param {number} width + * @param {number} height + * @param {number} radius + * @returns {[number, number][]} + */ +export function circle_anchors(anchor_count, width, height, radius) { + const x_mid = width / 2; + const y_mid = height / 2; + + return Array.from({ length: anchor_count }) + .map((_, anchor) => (anchor * 2 * Math.PI) / anchor_count) + .map((angle) => [ + x_mid + radius * Math.cos(angle), + y_mid + radius * Math.sin(angle), + ]); +} + +/** + * Compute anchors for a rectangle. Starts in the top left. + * @param {number} anchor_count + * @param {number} width + * @param {number} height + * @returns {[number, number][]} + */ +export function rectangle_anchors(anchor_count, width, height) { + /** @type {[number, number][]} */ + const anchors = [[0, 0]]; + + const totalLength = width * 2 + height * 2; + const gapLength = totalLength / anchor_count; + + let currentLength = 0; + + for (let i = 1; i < anchor_count; i++) { + currentLength += gapLength; + + if (currentLength < width) { + // walk top left to right + anchors.push([currentLength, 0]); + } else if (currentLength < width + height) { + // walk right top to bottom + anchors.push([width, currentLength - (width)]); + } else if (currentLength < width * 2 + height) { + // walk bottom right to left + anchors.push([2 * width - (currentLength - height), height]); + } else { + // walk left bottom to top + anchors.push([0, height + 2 * width - (currentLength - height)]); + } + } + + return anchors; +} \ No newline at end of file diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 6a29b52..d3963b2 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -1,29 +1,55 @@ string-bean - + -
-
+
+
input
+
+ monochrome + +
output @@ -134,13 +169,14 @@
+ {#if state == STATES.UPLOAD}
{:else if state == STATES.CONFIGURE} -
- -
-
- -
+
+
+ +
-
-
{/if} + +