www.spaceplanner.app

Web client to the spaceplanner API
git clone git://jacobedwards.org/www.spaceplanner.app
Log | Files | Refs

commit 024f7f8fb66aa7c25342f03f6c9c5f15009a2284
parent 4accff757e0b9989ede89386ee0250d18420b3fd
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date:   Sat, 17 Aug 2024 13:28:41 -0700

Add a unit system to editor

Diffstat:
Mfiles/floorplans/floorplan/editor.js | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mfiles/floorplans/floorplan/main.js | 7++++---
2 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/files/floorplans/floorplan/editor.js b/files/floorplans/floorplan/editor.js @@ -40,6 +40,79 @@ SVG.extend(SVG.Circle, { } }) +class Units { + constructor() { + this.data = {} + this.systems = {} + } + + add(name, factor, options) { + options = options ?? {} + + if (!name || !factor) { + throw new Error("Requires name and factor") + } + if (this.data[name]) { + throw new Error("Already exists") + } + if (options.base && (!this.data[options.base] || this.data[options.base].next)) { + throw new Error("Invalid base (already used or does not exist)") + } + if (options.base && options.system) { + throw new Error("Class may only be set on base units") + } + if (options.system && this.systems[options.system]) { + throw new Error("Unit system already exists") + } + + this.data[name] = { + name: name, + factor: factor, + } + if (options.system) { + this.data[name].system = options.system + this.systems[options.system] = name + } + if (options.symbol) { + this.data[name].symbol = options.symbol + } + if (options.base) { + this.data[options.base].next = name + this.data[name].base = options.base + } + } + + get(name, num) { + if (!name || !this.data[name]) { + throw new Error("Invalid unit") + } + let n = this.data[name].factor + if (this.data[name].base) { + n *= this.get(this.data[name].base) + } + return n * (num ?? 1) + } + + system(name) { + return this.data[this.smallest(name)].system + } + + smallest(name) { + return traverse(name, "base") + } + + biggest(name) { + return traverse(name, "next") + } + + walk(name, key) { + while (this.data[name][key]) { + name = this.data[name][key] + } + return name + } +} + export class FloorplanEditor { constructor(svg, floorplan, options) { if (!options) { @@ -51,6 +124,13 @@ export class FloorplanEditor { this.modes = {} this.mode_states = {} + // Setup units + this.units = new Units() + this.units.add("inch", 96, { symbol: '"', system: "imperial" }) + this.units.add("foot", 12, { base: "inch", symbol: "'" }) + this.units.add("centimeter", this.units.get("inch") / 2.54, { system: "metric" }) + this.units.add("meter", 100, { base: "centimeter" }) + if (!options.backend) { options.backend = {} } diff --git a/files/floorplans/floorplan/main.js b/files/floorplans/floorplan/main.js @@ -26,11 +26,11 @@ function init() { let draw = SVG() .addTo("#editor") - .viewbox("0 0 400 400") .panZoom({ panButton: buttons.right, - zoomMin: .25, - zoomMax: 4, + // These need to be set using device size + zoomMin: .025, + zoomMax: .5, zoomFactor: .5 }) @@ -52,6 +52,7 @@ function init() { } } }) + editor.draw.viewbox(0, 0, editor.units.get("foot", 40), editor.units.get("foot", 40)) let push = ui.button("Push", "Push updates", "arrow-up", { handlers: { click: function() { editor.backend.push(); notify("Pushed floorplan", "pushpull") } } })