From: Ian Jackson Date: Mon, 11 Apr 2022 18:10:36 +0000 (+0100) Subject: dice: Provide die_cooldown_path X-Git-Tag: otter-1.1.0~588 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=ce3b5f1de498405b83281fd8408b0f7484a21821;p=otter.git dice: Provide die_cooldown_path Signed-off-by: Ian Jackson --- diff --git a/base/misc.rs b/base/misc.rs index f966e5a9..ba3029cf 100644 --- a/base/misc.rs +++ b/base/misc.rs @@ -32,6 +32,30 @@ pub fn raw_angle_transform(compass: u8) -> String { else { format!("rotate({})", -45 * (compass as i16)) } } +#[throws(fmt::Error)] +pub fn die_cooldown_path(mut w: W, r: f64, remaining: f64) { + write!(w, "M 0,-{r} A")?; + + let mut arcto = move |proportion: f64| { + let angle = proportion * std::f64::consts::TAU; + let x = r * angle.cos(); + let y = -r * angle.sin(); + write!(w, " {r},{r} 0 0 1 {x},{y}") + // | | `sweep-flag (1 = clockwise) + // | `large-arc-flag (see below) + // `"angle" (ellipse skew angle) + }; + + // This avoids ever trying to draw an arc segment that is around 180 degrees. + // If we did so there could be rounding errors that would mean we might + // disagree with the SVG renderer about whether the angle is <=> 180. + for split in [0.33, 0.67] { + if split >= remaining { break } + arcto(split)?; + } + arcto(remaining)?; +} + pub fn default() -> T { Default::default() } #[macro_export] diff --git a/wasm/wasm.rs b/wasm/wasm.rs index c7db365b..a88928fa 100644 --- a/wasm/wasm.rs +++ b/wasm/wasm.rs @@ -217,6 +217,16 @@ pub fn space_rect_attrs(x: Number, y: Number) -> JsValue { .to_jsvalue() } +// ---------- die cooldown ---------- + +#[wasm_bindgen] +pub fn die_cooldown_path(radius: f64, remaining: f64) -> JsString { + let mut s = String::new(); + base_misc::die_cooldown_path(&mut s, radius, remaining) + .expect("format to string failed!"); + s.into() +} + // ---------- setup ---------- #[wasm_bindgen]