| @@ -703,10 +703,26 @@ function drawRulers() { | |||||
| ctx.scale(deviceScale, deviceScale); | ctx.scale(deviceScale, deviceScale); | ||||
| rulers.concat(currentRuler ? [currentRuler] : []).forEach(rulerDef => { | rulers.concat(currentRuler ? [currentRuler] : []).forEach(rulerDef => { | ||||
| let x0 = rulerDef.x0; | |||||
| let y0 = rulerDef.y0; | |||||
| let x1 = rulerDef.x1; | |||||
| let y1 = rulerDef.y1; | |||||
| if (rulerDef.entityKey !== null) { | |||||
| const entity = entities[rulerDef.entityKey] | |||||
| const entityElement = document.querySelector("#entity-" + rulerDef.entityKey) | |||||
| x0 *= entity.scale; | |||||
| y0 *= entity.scale; | |||||
| x1 *= entity.scale; | |||||
| y1 *= entity.scale; | |||||
| x0 += parseFloat(entityElement.dataset.x) | |||||
| x1 += parseFloat(entityElement.dataset.x) | |||||
| y0 += parseFloat(entityElement.dataset.y) | |||||
| y1 += parseFloat(entityElement.dataset.y) | |||||
| } | |||||
| ctx.save(); | ctx.save(); | ||||
| ctx.beginPath(); | ctx.beginPath(); | ||||
| const start = pos2pix({x: rulerDef.x0, y: rulerDef.y0}); | |||||
| const end = pos2pix({x: rulerDef.x1, y: rulerDef.y1}); | |||||
| const start = pos2pix({x: x0, y: y0}); | |||||
| const end = pos2pix({x: x1, y: y1}); | |||||
| ctx.moveTo(start.x, start.y); | ctx.moveTo(start.x, start.y); | ||||
| ctx.lineTo(end.x, end.y); | ctx.lineTo(end.x, end.y); | ||||
| ctx.lineWidth = 5; | ctx.lineWidth = 5; | ||||
| @@ -728,7 +744,7 @@ function drawRulers() { | |||||
| const offsetX = Math.cos(angle + Math.PI/2); | const offsetX = Math.cos(angle + Math.PI/2); | ||||
| const offsetY = Math.sin(angle + Math.PI/2); | const offsetY = Math.sin(angle + Math.PI/2); | ||||
| const distance = Math.sqrt(Math.pow(rulerDef.y1 - rulerDef.y0, 2) + Math.pow(rulerDef.x1 - rulerDef.x0, 2)); | |||||
| const distance = Math.sqrt(Math.pow(y1 - y0, 2) + Math.pow(x1 - x0, 2)); | |||||
| const distanceInUnits = math.unit(distance, "meters").to(document.querySelector("#options-height-unit").value); | const distanceInUnits = math.unit(distance, "meters").to(document.querySelector("#options-height-unit").value); | ||||
| const textSize = ctx.measureText(distanceInUnits.format({ precision: 3})); | const textSize = ctx.measureText(distanceInUnits.format({ precision: 3})); | ||||
| ctx.fillText(distanceInUnits.format({ precision: 3}), -offsetX * 10 - textSize.width / 2, -offsetY*10); | ctx.fillText(distanceInUnits.format({ precision: 3}), -offsetX * 10 - textSize.width / 2, -offsetY*10); | ||||
| @@ -1405,6 +1421,9 @@ function clickUp(e) { | |||||
| } | } | ||||
| function deselect(e) { | function deselect(e) { | ||||
| if (rulerMode) { | |||||
| return; | |||||
| } | |||||
| if (e !== undefined && e.which != 1) { | if (e !== undefined && e.which != 1) { | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -2681,6 +2700,18 @@ const settingsData = { | |||||
| } | } | ||||
| } | } | ||||
| }, | }, | ||||
| "attach-rulers": { | |||||
| name: "Attach Rulers", | |||||
| desc: "Rulers will attach to the currently-selected entity, moving around with it.", | |||||
| type: "toggle", | |||||
| default: true, | |||||
| get value() { | |||||
| return config.rulersStick; | |||||
| }, | |||||
| set value(param) { | |||||
| config.rulersStick = param; | |||||
| } | |||||
| }, | |||||
| "units": { | "units": { | ||||
| name: "Default Units", | name: "Default Units", | ||||
| desc: "Which kind of unit to use by default", | desc: "Which kind of unit to use by default", | ||||
| @@ -3074,6 +3105,21 @@ function selectNewUnit() { | |||||
| unitSelector.dataset.oldUnit = unitSelector.value; | unitSelector.dataset.oldUnit = unitSelector.value; | ||||
| } | } | ||||
| // given a world position, return the position relative to the entity at normal scale | |||||
| function entityRelativePosition(pos, entityElement) { | |||||
| const entity = entities[entityElement.dataset.key] | |||||
| const x = parseFloat(entityElement.dataset.x) | |||||
| const y = parseFloat(entityElement.dataset.y) | |||||
| pos.x /= entity.scale | |||||
| pos.y /= entity.scale | |||||
| pos.x -= x | |||||
| pos.y -= y | |||||
| return pos | |||||
| } | |||||
| document.addEventListener("DOMContentLoaded", () => { | document.addEventListener("DOMContentLoaded", () => { | ||||
| prepareMenu(); | prepareMenu(); | ||||
| prepareEntities(); | prepareEntities(); | ||||
| @@ -3346,8 +3392,16 @@ document.addEventListener("DOMContentLoaded", () => { | |||||
| if (e.which == 1 && rulerMode) { | if (e.which == 1 && rulerMode) { | ||||
| let entX = document.querySelector("#entities").getBoundingClientRect().x; | let entX = document.querySelector("#entities").getBoundingClientRect().x; | ||||
| let entY = document.querySelector("#entities").getBoundingClientRect().y; | let entY = document.querySelector("#entities").getBoundingClientRect().y; | ||||
| const pos = pix2pos({ x: e.clientX - entX, y: e.clientY - entY }); | |||||
| currentRuler = { x0: pos.x, y0: pos.y, x1: pos.y, y1: pos.y }; | |||||
| let pos = pix2pos({ x: e.clientX - entX, y: e.clientY - entY }); | |||||
| if (config.rulersStick && selected) { | |||||
| pos = entityRelativePosition(pos, selected) | |||||
| } | |||||
| currentRuler = { x0: pos.x, y0: pos.y, x1: pos.y, y1: pos.y, entityKey: null }; | |||||
| if (config.rulersStick && selected) { | |||||
| currentRuler.entityKey = selected.dataset.key | |||||
| } | |||||
| } | } | ||||
| }); | }); | ||||
| document.querySelector("#world").addEventListener("mouseup", e => { | document.querySelector("#world").addEventListener("mouseup", e => { | ||||
| @@ -3363,8 +3417,15 @@ document.addEventListener("DOMContentLoaded", () => { | |||||
| if (rulerMode) { | if (rulerMode) { | ||||
| let entX = document.querySelector("#entities").getBoundingClientRect().x; | let entX = document.querySelector("#entities").getBoundingClientRect().x; | ||||
| let entY = document.querySelector("#entities").getBoundingClientRect().y; | let entY = document.querySelector("#entities").getBoundingClientRect().y; | ||||
| const pos = pix2pos({ x: e.touches[0].clientX - entX, y: e.touches[0].clientY - entY }); | |||||
| currentRuler = { x0: pos.x, y0: pos.y, x1: pos.y, y1: pos.y }; | |||||
| let pos = pix2pos({ x: e.touches[0].clientX - entX, y: e.touches[0].clientY - entY }); | |||||
| if (config.rulersStick && selected) { | |||||
| pos = entityRelativePosition(pos, selected) | |||||
| } | |||||
| currentRuler = { x0: pos.x, y0: pos.y, x1: pos.y, y1: pos.y, entityKey: null }; | |||||
| if (config.rulersStick && selected) { | |||||
| currentRuler.entityKey = selected.dataset.key | |||||
| } | |||||
| } | } | ||||
| }); | }); | ||||
| document.querySelector("#world").addEventListener("touchend", e => { | document.querySelector("#world").addEventListener("touchend", e => { | ||||
| @@ -4442,6 +4503,10 @@ document.addEventListener("mousemove", (e) => { | |||||
| let entX = document.querySelector("#entities").getBoundingClientRect().x; | let entX = document.querySelector("#entities").getBoundingClientRect().x; | ||||
| let entY = document.querySelector("#entities").getBoundingClientRect().y; | let entY = document.querySelector("#entities").getBoundingClientRect().y; | ||||
| let position = pix2pos({ x: e.clientX - entX, y: e.clientY - entY }); | let position = pix2pos({ x: e.clientX - entX, y: e.clientY - entY }); | ||||
| if (config.rulersStick && selected) { | |||||
| position = entityRelativePosition(position, selected) | |||||
| } | |||||
| currentRuler.x1 = position.x; | currentRuler.x1 = position.x; | ||||
| currentRuler.y1 = position.y; | currentRuler.y1 = position.y; | ||||
| } | } | ||||
| @@ -4453,6 +4518,9 @@ document.addEventListener("touchmove", (e) => { | |||||
| let entX = document.querySelector("#entities").getBoundingClientRect().x; | let entX = document.querySelector("#entities").getBoundingClientRect().x; | ||||
| let entY = document.querySelector("#entities").getBoundingClientRect().y; | let entY = document.querySelector("#entities").getBoundingClientRect().y; | ||||
| let position = pix2pos({ x: e.touches[0].clientX - entX, y: e.touches[0].clientY - entY }); | let position = pix2pos({ x: e.touches[0].clientX - entX, y: e.touches[0].clientY - entY }); | ||||
| if (config.rulersStick && selected) { | |||||
| position = entityRelativePosition(position, selected) | |||||
| } | |||||
| currentRuler.x1 = position.x; | currentRuler.x1 = position.x; | ||||
| currentRuler.y1 = position.y; | currentRuler.y1 = position.y; | ||||
| } | } | ||||