Allow resizing of canvas
This commit is contained in:
parent
0e79b5d09d
commit
f5ae56cc9c
@ -45,6 +45,8 @@
|
|||||||
<h3>Diagram</h3>
|
<h3>Diagram</h3>
|
||||||
<p>Hover with the mouse cursor over the diagram to see the heat and humidity coordinates at this position. You can click on a dot to select it, click on it again and hold down the mouse button to drag it.</p>
|
<p>Hover with the mouse cursor over the diagram to see the heat and humidity coordinates at this position. You can click on a dot to select it, click on it again and hold down the mouse button to drag it.</p>
|
||||||
|
|
||||||
|
<p>When you hover the diagram, a small grabbing widget will apper in the bottom left corner. You can use this to resize the whole diagram. Hold down Shift while resizing to preserve the aspect ratio.</p>
|
||||||
|
|
||||||
<h3>Biome configuration</h3>
|
<h3>Biome configuration</h3>
|
||||||
<p>Here you can see a list of all currently active biomes. Each biome has a name of your choice. The program always starts with a default biome at (50, 50). Select a biome in the list so you can edit it.</p>
|
<p>Here you can see a list of all currently active biomes. Each biome has a name of your choice. The program always starts with a default biome at (50, 50). Select a biome in the list so you can edit it.</p>
|
||||||
|
|
||||||
|
133
mibpov.js
133
mibpov.js
@ -7,6 +7,12 @@ const MAX_Y_DEFAULT = 31000
|
|||||||
// Draw a grid line every GRID_STEP units
|
// Draw a grid line every GRID_STEP units
|
||||||
const GRID_STEP = 10
|
const GRID_STEP = 10
|
||||||
|
|
||||||
|
// Size of the resizing corner
|
||||||
|
const RESIZE_CORNER = 18;
|
||||||
|
|
||||||
|
// Minimum canvas side length (px)
|
||||||
|
const MIN_CANVAS_SIZE = 100;
|
||||||
|
|
||||||
// Grid widths. We use lower grid widths
|
// Grid widths. We use lower grid widths
|
||||||
// as the grid becomes more crammed.
|
// as the grid becomes more crammed.
|
||||||
// There are 4 levels from 0 to 3.
|
// There are 4 levels from 0 to 3.
|
||||||
@ -221,6 +227,10 @@ function addBiome(biomeDef) {
|
|||||||
lastBiomeID++;
|
lastBiomeID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Current cursor position on the canvas
|
||||||
|
let canvas_cursor_x = null;
|
||||||
|
let canvas_cursor_y = null;
|
||||||
|
|
||||||
// Add a default biome at the midpoint
|
// Add a default biome at the midpoint
|
||||||
addBiome({name: "default", heat:midpoint_heat, humidity:midpoint_humidity, min_y: MIN_Y_DEFAULT, max_y: MAX_Y_DEFAULT})
|
addBiome({name: "default", heat:midpoint_heat, humidity:midpoint_humidity, min_y: MIN_Y_DEFAULT, max_y: MAX_Y_DEFAULT})
|
||||||
|
|
||||||
@ -919,6 +929,27 @@ function draw(recalculate) {
|
|||||||
putPointName(context, point);
|
putPointName(context, point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (canvas_cursor_x !== null) {
|
||||||
|
const RESIZE_CORNER = 14;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(voronoiCanvas.width, voronoiCanvas.height - RESIZE_CORNER);
|
||||||
|
context.lineTo(voronoiCanvas.width - RESIZE_CORNER, voronoiCanvas.height);
|
||||||
|
context.lineTo(voronoiCanvas.width, voronoiCanvas.height);
|
||||||
|
context.fillStyle = "#80808080";
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
context.beginPath();
|
||||||
|
context.lineWidth = 1;
|
||||||
|
for (let c = RESIZE_CORNER; c>0; c-=4) {
|
||||||
|
context.moveTo(voronoiCanvas.width, voronoiCanvas.height - c);
|
||||||
|
context.lineTo(voronoiCanvas.width - c, voronoiCanvas.height);
|
||||||
|
}
|
||||||
|
context.strokeStyle = "#00000080";
|
||||||
|
context.closePath();
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1096,6 +1127,15 @@ function getNearestPointFromCanvasPos(x, y, maxDist) {
|
|||||||
|
|
||||||
// Whether the mouse is currently pressed
|
// Whether the mouse is currently pressed
|
||||||
let mouseIsDown = false;
|
let mouseIsDown = false;
|
||||||
|
// Whether the canvas is being resized
|
||||||
|
let resizing = false;
|
||||||
|
// Start coordinates of canvas resize or null if not resizing
|
||||||
|
let resizing_start_pos_x = null;
|
||||||
|
let resizing_start_pos_y = null;
|
||||||
|
// Start size of canvas when resizing or null if not resizing
|
||||||
|
let resizing_start_size_x = null;
|
||||||
|
let resizing_start_size_y = null;
|
||||||
|
|
||||||
// Coordinates of where the drag-n-drop started
|
// Coordinates of where the drag-n-drop started
|
||||||
// or is about to start
|
// or is about to start
|
||||||
let dragDropStartPos = null;
|
let dragDropStartPos = null;
|
||||||
@ -1149,6 +1189,10 @@ function updateAltitudeText() {
|
|||||||
/* Update the text that shows the biome coordinates
|
/* Update the text that shows the biome coordinates
|
||||||
of the cursor when it's on the diagram */
|
of the cursor when it's on the diagram */
|
||||||
function updateCoordinateDisplay(pixelX, pixelY) {
|
function updateCoordinateDisplay(pixelX, pixelY) {
|
||||||
|
if (pixelX === null || pixelY === null) {
|
||||||
|
coordinateDisplay.innerHtml = " ";
|
||||||
|
return;
|
||||||
|
}
|
||||||
// show coordinates
|
// show coordinates
|
||||||
let [heat, humidity] = canvasPixelCoordsToBiomeCoords(pixelX, pixelY);
|
let [heat, humidity] = canvasPixelCoordsToBiomeCoords(pixelX, pixelY);
|
||||||
if (!drawError) {
|
if (!drawError) {
|
||||||
@ -1162,21 +1206,27 @@ function updateCoordinateDisplay(pixelX, pixelY) {
|
|||||||
/* Updates and changes the cursor type on the diagram
|
/* Updates and changes the cursor type on the diagram
|
||||||
canvas depending on whether we can select, drag or do nothing
|
canvas depending on whether we can select, drag or do nothing
|
||||||
at the pointed position */
|
at the pointed position */
|
||||||
function updateDragDropCursorStatus() {
|
function updateCanvasCursorStatus(x, y) {
|
||||||
|
// Show resize cursor at the bottom right corner
|
||||||
|
if (resizing || (x > voronoiCanvas.width - RESIZE_CORNER && y > voronoiCanvas.height - RESIZE_CORNER)) {
|
||||||
|
voronoiCanvas.style.cursor = "nwse-resize";
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (drawError || !showPoints) {
|
if (drawError || !showPoints) {
|
||||||
// a special message is shown; use auto cursor
|
// a special message is shown; use auto cursor
|
||||||
voronoiCanvas.style.cursor = "auto";
|
voronoiCanvas.style.cursor = "auto";
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let nearest = getNearestPointFromCanvasPos(event.offsetX, event.offsetY, POINT_SELECT_DISTANCE);
|
let nearest = getNearestPointFromCanvasPos(x, y, POINT_SELECT_DISTANCE);
|
||||||
if (nearest !== null) {
|
if (nearest !== null) {
|
||||||
let [id, elem] = getSelectedBiomeIDAndElement();
|
let [id, elem] = getSelectedBiomeIDAndElement();
|
||||||
if (id !== null && nearest.id === id) {
|
if (id !== null && nearest.id === id) {
|
||||||
// This cursor indicates we can grab the point
|
// This cursor indicates we can grab the point
|
||||||
voronoiCanvas.style.cursor = "grab";
|
voronoiCanvas.style.cursor = "grab";
|
||||||
} else {
|
} else {
|
||||||
// This cursor indicates we can grab the point
|
// This cursor indicates we can select the point
|
||||||
voronoiCanvas.style.cursor = "crosshair";
|
voronoiCanvas.style.cursor = "crosshair";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1237,9 +1287,58 @@ function initBiomeColorSelectors() {
|
|||||||
|
|
||||||
/***** EVENTS *****/
|
/***** EVENTS *****/
|
||||||
|
|
||||||
/* Canvas events */
|
/* Body events */
|
||||||
|
document.body.onmousemove = function(event) {
|
||||||
|
if (resizing) {
|
||||||
|
// Get x,y position of canvas
|
||||||
|
let bodyRect = document.body.getBoundingClientRect();
|
||||||
|
let canvasRect = voronoiCanvas.getBoundingClientRect();
|
||||||
|
let cx = canvasRect.left - bodyRect.left;
|
||||||
|
let cy = canvasRect.top - bodyRect.top;
|
||||||
|
|
||||||
|
// Calculate new size
|
||||||
|
let rx = event.pageX - resizing_start_pos_x - cx;
|
||||||
|
let ry = event.pageY - resizing_start_pos_y - cy;
|
||||||
|
|
||||||
|
// Limit the width
|
||||||
|
let maxX = (bodyRect.width - cx) - 20;
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
voronoiCanvas.width = Math.min(maxX, Math.max(MIN_CANVAS_SIZE, resizing_start_size_x + rx));
|
||||||
|
|
||||||
|
// Holding down Shift preserves aspect ratio
|
||||||
|
if (event.shiftKey) {
|
||||||
|
voronoiCanvas.height = voronoiCanvas.width;
|
||||||
|
} else {
|
||||||
|
voronoiCanvas.height = Math.max(MIN_CANVAS_SIZE, resizing_start_size_y + ry);
|
||||||
|
}
|
||||||
|
draw(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.body.onmouseup = function(event) {
|
||||||
|
if (resizing) {
|
||||||
|
resizing = false;
|
||||||
|
updateCanvasCursorStatus(event.offsetX, event.offsetY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.body.onmouseleave = function(event) {
|
||||||
|
if (resizing) {
|
||||||
|
resizing = false;
|
||||||
|
updateCanvasCursorStatus(event.offsetX, event.offsetY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Canvas events */
|
||||||
voronoiCanvas.onmousemove = function(event) {
|
voronoiCanvas.onmousemove = function(event) {
|
||||||
|
if (resizing) {
|
||||||
|
updateCoordinateDisplay(event.offsetX, event.offsetY);
|
||||||
|
updateCanvasCursorStatus(event.offsetX, event.offsetY);
|
||||||
|
canvas_cursor_x = event.offsetX;
|
||||||
|
canvas_cursor_y = event.offsetY;
|
||||||
|
draw(false);
|
||||||
|
return
|
||||||
|
}
|
||||||
// update drag-n-drop state
|
// update drag-n-drop state
|
||||||
if (dragDropState !== 2 && dragDropPointID !== null && mouseIsDown && dragDropStartPos !== null) {
|
if (dragDropState !== 2 && dragDropPointID !== null && mouseIsDown && dragDropStartPos !== null) {
|
||||||
let dist = getDistance(dragDropStartPos.x, dragDropStartPos.y, event.offsetX, event.offsetY)
|
let dist = getDistance(dragDropStartPos.x, dragDropStartPos.y, event.offsetX, event.offsetY)
|
||||||
@ -1254,17 +1353,34 @@ voronoiCanvas.onmousemove = function(event) {
|
|||||||
updatePointWhenDragged(dragDropPointID);
|
updatePointWhenDragged(dragDropPointID);
|
||||||
}
|
}
|
||||||
updateCoordinateDisplay(event.offsetX, event.offsetY);
|
updateCoordinateDisplay(event.offsetX, event.offsetY);
|
||||||
updateDragDropCursorStatus();
|
updateCanvasCursorStatus(event.offsetX, event.offsetY);
|
||||||
|
canvas_cursor_x = event.offsetX;
|
||||||
|
canvas_cursor_y = event.offsetY;
|
||||||
|
draw(false);
|
||||||
}
|
}
|
||||||
voronoiCanvas.onmouseenter = function(event) {
|
voronoiCanvas.onmouseenter = function(event) {
|
||||||
updateCoordinateDisplay(event.offsetX, event.offsetY);
|
updateCoordinateDisplay(event.offsetX, event.offsetY);
|
||||||
updateDragDropCursorStatus();
|
updateCanvasCursorStatus(event.offsetX, event.offsetY);
|
||||||
|
canvas_cursor_x = event.offsetX;
|
||||||
|
canvas_cursor_y = event.offsetY;
|
||||||
|
draw(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
voronoiCanvas.onmousedown = function(event) {
|
voronoiCanvas.onmousedown = function(event) {
|
||||||
// select point by clicking.
|
// select point by clicking.
|
||||||
// initiate drag-n-drop if already selected.
|
// initiate drag-n-drop if already selected.
|
||||||
mouseIsDown = true;
|
mouseIsDown = true;
|
||||||
|
|
||||||
|
// Resizing the canvas
|
||||||
|
if (event.offsetX > voronoiCanvas.width - RESIZE_CORNER && event.offsetY > voronoiCanvas.height - RESIZE_CORNER) {
|
||||||
|
resizing_start_pos_x = event.offsetX;
|
||||||
|
resizing_start_pos_y = event.offsetY;
|
||||||
|
resizing_start_size_x = +this.width;
|
||||||
|
resizing_start_size_y = +this.height;
|
||||||
|
resizing = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (drawError || !showPoints) {
|
if (drawError || !showPoints) {
|
||||||
// Points need to be shown for drag-n-drop to work
|
// Points need to be shown for drag-n-drop to work
|
||||||
return;
|
return;
|
||||||
@ -1281,7 +1397,7 @@ voronoiCanvas.onmousedown = function(event) {
|
|||||||
if (alreadySelected) {
|
if (alreadySelected) {
|
||||||
dragDropState = 1;
|
dragDropState = 1;
|
||||||
}
|
}
|
||||||
updateDragDropCursorStatus();
|
updateCanvasCursorStatus(event.offsetX, event.offsetY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
voronoiCanvas.onmouseup = function(event) {
|
voronoiCanvas.onmouseup = function(event) {
|
||||||
@ -1300,7 +1416,10 @@ voronoiCanvas.onmouseleave = function() {
|
|||||||
dragDropStartPos = null;
|
dragDropStartPos = null;
|
||||||
dragDropPointID = null;
|
dragDropPointID = null;
|
||||||
dragDropState = 0;
|
dragDropState = 0;
|
||||||
|
canvas_cursor_x = null;
|
||||||
|
canvas_cursor_y = null;
|
||||||
coordinateDisplay.innerHTML = " ";
|
coordinateDisplay.innerHTML = " ";
|
||||||
|
draw(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Biome list events */
|
/* Biome list events */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user