diff --git a/macrovision.js b/macrovision.js index ea535c2c..1114322f 100644 --- a/macrovision.js +++ b/macrovision.js @@ -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; }