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:
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") } } })