| @@ -703,10 +703,26 @@ function drawRulers() { | |||
| ctx.scale(deviceScale, deviceScale); | |||
| 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.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.lineTo(end.x, end.y); | |||
| ctx.lineWidth = 5; | |||
| @@ -728,7 +744,7 @@ function drawRulers() { | |||
| const offsetX = Math.cos(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 textSize = ctx.measureText(distanceInUnits.format({ precision: 3})); | |||
| ctx.fillText(distanceInUnits.format({ precision: 3}), -offsetX * 10 - textSize.width / 2, -offsetY*10); | |||
| @@ -1405,6 +1421,9 @@ function clickUp(e) { | |||
| } | |||
| function deselect(e) { | |||
| if (rulerMode) { | |||
| return; | |||
| } | |||
| if (e !== undefined && e.which != 1) { | |||
| 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": { | |||
| name: "Default Units", | |||
| desc: "Which kind of unit to use by default", | |||
| @@ -3074,6 +3105,21 @@ function selectNewUnit() { | |||
| 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", () => { | |||
| prepareMenu(); | |||
| prepareEntities(); | |||
| @@ -3346,8 +3392,16 @@ document.addEventListener("DOMContentLoaded", () => { | |||
| if (e.which == 1 && rulerMode) { | |||
| let entX = document.querySelector("#entities").getBoundingClientRect().x; | |||
| 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 => { | |||
| @@ -3363,8 +3417,15 @@ document.addEventListener("DOMContentLoaded", () => { | |||
| if (rulerMode) { | |||
| let entX = document.querySelector("#entities").getBoundingClientRect().x; | |||
| 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 => { | |||
| @@ -4442,6 +4503,10 @@ document.addEventListener("mousemove", (e) => { | |||
| let entX = document.querySelector("#entities").getBoundingClientRect().x; | |||
| let entY = document.querySelector("#entities").getBoundingClientRect().y; | |||
| let position = pix2pos({ x: e.clientX - entX, y: e.clientY - entY }); | |||
| if (config.rulersStick && selected) { | |||
| position = entityRelativePosition(position, selected) | |||
| } | |||
| currentRuler.x1 = position.x; | |||
| currentRuler.y1 = position.y; | |||
| } | |||
| @@ -4453,6 +4518,9 @@ document.addEventListener("touchmove", (e) => { | |||
| let entX = document.querySelector("#entities").getBoundingClientRect().x; | |||
| let entY = document.querySelector("#entities").getBoundingClientRect().y; | |||
| 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.y1 = position.y; | |||
| } | |||