diff --git a/macrovision.css b/macrovision.css
index 5ea3e262..a890f404 100644
--- a/macrovision.css
+++ b/macrovision.css
@@ -633,7 +633,7 @@ option.filtered {
.scroll-button {
position: absolute;
- height: 25%;
+ height: 20%;
width: 50px;
font-size: 40px;
background: #ffffff33;
@@ -664,27 +664,37 @@ option.filtered {
}
#scroll-left {
left: 0%;
- top: 25%;
+ top: 20%;
}
#scroll-right {
right: 0%;
- top: 25%;
+ top: 20%;
+}
+
+#scroll-up {
+ left: 0%;
+ top: 40%;
+}
+
+#scroll-down {
+ right: 0%;
+ top: 40%;
}
#shrink {
left: 0%;
- top: 50%;
+ top: 60%;
}
#grow {
right: 0%;
- top: 50%;
+ top: 60%;
}
#fit {
right: 0%;
- top: 75%;
+ top: 80%;
}
#toggle-menu {
diff --git a/macrovision.html b/macrovision.html
index 4dbfd942..12cd8836 100644
--- a/macrovision.html
+++ b/macrovision.html
@@ -262,6 +262,12 @@
+
+
diff --git a/macrovision.js b/macrovision.js
index 623a09c8..bdcd6e28 100644
--- a/macrovision.js
+++ b/macrovision.js
@@ -193,6 +193,8 @@ const unitChoices = {
}
const config = {
height: math.unit(1500, "meters"),
+ x: 0,
+ y: 0,
minLineSize: 100,
maxLineSize: 150,
autoFit: false,
@@ -243,8 +245,8 @@ function pos2pix(coords) {
const worldWidth = config.height.toNumber("meters") / canvasHeight * canvasWidth;
const worldHeight = config.height.toNumber("meters");
- const x = (coords.x / worldWidth + 0.5) * canvasWidth + 50;
- const y = (1 - coords.y / worldHeight) * canvasHeight;
+ const x = ((coords.x - config.x) / worldWidth + 0.5) * canvasWidth + 50;
+ const y = (1 - (coords.y - config.y) / worldHeight) * canvasHeight;
return { x: x, y: y };
}
@@ -253,8 +255,8 @@ function pix2pos(coords) {
const worldWidth = config.height.toNumber("meters") / canvasHeight * canvasWidth;
const worldHeight = config.height.toNumber("meters");
- const x = (((coords.x - 50) / canvasWidth) - 0.5) * worldWidth;
- const y = (1 - (coords.y / canvasHeight)) * worldHeight;
+ const x = (((coords.x - 50) / canvasWidth) - 0.5) * worldWidth + config.x;
+ const y = (1 - (coords.y / canvasHeight)) * worldHeight + config.y;
return { x: x, y: y };
}
@@ -332,7 +334,7 @@ function drawScale(ifDirty = false) {
return;
function drawTicks(/** @type {CanvasRenderingContext2D} */ ctx, pixelsPer, heightPer) {
let total = heightPer.clone();
- total.value = 0;
+ total.value = math.unit(config.y, "meters").toNumber(config.unit);
for (let y = ctx.canvas.clientHeight - 50; y >= 50; y -= pixelsPer) {
drawTick(ctx, 50, y, total);
total = math.add(total, heightPer);
@@ -1659,10 +1661,13 @@ function setHelpDate() {
}
}
-function doScroll() {
- document.querySelectorAll(".entity-box").forEach(element => {
- element.dataset.x = parseFloat(element.dataset.x) + scrollDirection / 180;
- });
+function doYScroll() {
+ config.y += scrollDirection / 180;
+ updateSizes();
+ scrollDirection *= 1.05;
+}
+function doXScroll() {
+ config.x += scrollDirection / 180;
updateSizes();
scrollDirection *= 1.05;
}
@@ -2017,28 +2022,57 @@ document.addEventListener("DOMContentLoaded", () => {
document.querySelector("#scroll-left").addEventListener("mousedown", e => {
scrollDirection = 1;
clearInterval(scrollHandle);
- scrollHandle = setInterval(doScroll, 1000 / 20);
+ scrollHandle = setInterval(doXScroll, 1000 / 20);
e.stopPropagation();
});
document.querySelector("#scroll-right").addEventListener("mousedown", e => {
scrollDirection = -1;
clearInterval(scrollHandle);
- scrollHandle = setInterval(doScroll, 1000 / 20);
+ scrollHandle = setInterval(doXScroll, 1000 / 20);
e.stopPropagation();
});
document.querySelector("#scroll-left").addEventListener("touchstart", e => {
scrollDirection = 1;
clearInterval(scrollHandle);
- scrollHandle = setInterval(doScroll, 1000 / 20);
+ scrollHandle = setInterval(doXScroll, 1000 / 20);
e.stopPropagation();
});
document.querySelector("#scroll-right").addEventListener("touchstart", e => {
scrollDirection = -1;
clearInterval(scrollHandle);
- scrollHandle = setInterval(doScroll, 1000 / 20);
+ scrollHandle = setInterval(doXScroll, 1000 / 20);
+ e.stopPropagation();
+ });
+
+
+ document.querySelector("#scroll-up").addEventListener("mousedown", e => {
+ scrollDirection = 1;
+ clearInterval(scrollHandle);
+ scrollHandle = setInterval(doYScroll, 1000 / 20);
+ e.stopPropagation();
+ });
+
+ document.querySelector("#scroll-down").addEventListener("mousedown", e => {
+ scrollDirection = -1;
+ clearInterval(scrollHandle);
+ scrollHandle = setInterval(doYScroll, 1000 / 20);
+ e.stopPropagation();
+ });
+
+ document.querySelector("#scroll-up").addEventListener("touchstart", e => {
+ scrollDirection = 1;
+ clearInterval(scrollHandle);
+ scrollHandle = setInterval(doYScroll, 1000 / 20);
+ e.stopPropagation();
+ });
+
+ document.querySelector("#scroll-down").addEventListener("touchstart", e => {
+ scrollDirection = -1;
+ clearInterval(scrollHandle);
+ scrollHandle = setInterval(doYScroll, 1000 / 20);
e.stopPropagation();
});
@@ -2899,7 +2933,9 @@ function exportScene() {
const unit = document.querySelector("#options-height-unit").value;
results.world = {
height: config.height.toNumber(unit),
- unit: unit
+ unit: unit,
+ x: config.x,
+ y: config.y
}
results.version = migrationDefs.length;
@@ -2969,7 +3005,16 @@ function findEntity(name) {
}
const migrationDefs = [
+ /*
+ Migration: 0 -> 1
+
+ Adds x and y coordinates for the camera
+ */
+ data => {
+ data.world.x = 0;
+ data.world.y = 0;
+ }
]
@@ -2979,7 +3024,9 @@ function migrateScene(data) {
console.trace()
data.version = 0;
} else if (data.version < migrationDefs.length) {
- migrateScene(migrationDefs[data.version](data));
+ migrationDefs[data.version](data);
+ data.version += 1;
+ migrateScene(data);
}
}
@@ -2995,6 +3042,9 @@ function importScene(data) {
});
config.height = math.unit(data.world.height, data.world.unit);
+ config.x = data.world.x;
+ config.y = data.world.y;
+
document.querySelector("#options-height-unit").value = data.world.unit;
if (data.canvasWidth) {