Allow resizing of canvas
This commit is contained in:
parent
0e79b5d09d
commit
f5ae56cc9c
@ -45,6 +45,8 @@
|
||||
<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>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>
|
||||
<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
|
||||
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
|
||||
// as the grid becomes more crammed.
|
||||
// There are 4 levels from 0 to 3.
|
||||
@ -221,6 +227,10 @@ function addBiome(biomeDef) {
|
||||
lastBiomeID++;
|
||||
}
|
||||
|
||||
// Current cursor position on the canvas
|
||||
let canvas_cursor_x = null;
|
||||
let canvas_cursor_y = null;
|
||||
|
||||
// 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})
|
||||
|
||||
@ -919,6 +929,27 @@ function draw(recalculate) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1096,6 +1127,15 @@ function getNearestPointFromCanvasPos(x, y, maxDist) {
|
||||
|
||||
// Whether the mouse is currently pressed
|
||||
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
|
||||
// or is about to start
|
||||
let dragDropStartPos = null;
|
||||
@ -1149,6 +1189,10 @@ function updateAltitudeText() {
|
||||
/* Update the text that shows the biome coordinates
|
||||
of the cursor when it's on the diagram */
|
||||
function updateCoordinateDisplay(pixelX, pixelY) {
|
||||
if (pixelX === null || pixelY === null) {
|
||||
coordinateDisplay.innerHtml = " ";
|
||||
return;
|
||||
}
|
||||
// show coordinates
|
||||
let [heat, humidity] = canvasPixelCoordsToBiomeCoords(pixelX, pixelY);
|
||||
if (!drawError) {
|
||||
@ -1162,21 +1206,27 @@ function updateCoordinateDisplay(pixelX, pixelY) {
|
||||
/* Updates and changes the cursor type on the diagram
|
||||
canvas depending on whether we can select, drag or do nothing
|
||||
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) {
|
||||
// a special message is shown; use auto cursor
|
||||
voronoiCanvas.style.cursor = "auto";
|
||||
return
|
||||
}
|
||||
|
||||
let nearest = getNearestPointFromCanvasPos(event.offsetX, event.offsetY, POINT_SELECT_DISTANCE);
|
||||
let nearest = getNearestPointFromCanvasPos(x, y, POINT_SELECT_DISTANCE);
|
||||
if (nearest !== null) {
|
||||
let [id, elem] = getSelectedBiomeIDAndElement();
|
||||
if (id !== null && nearest.id === id) {
|
||||
// This cursor indicates we can grab the point
|
||||
voronoiCanvas.style.cursor = "grab";
|
||||
} else {
|
||||
// This cursor indicates we can grab the point
|
||||
// This cursor indicates we can select the point
|
||||
voronoiCanvas.style.cursor = "crosshair";
|
||||
}
|
||||
} else {
|
||||
@ -1237,9 +1287,58 @@ function initBiomeColorSelectors() {
|
||||
|
||||
/***** 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) {
|
||||
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
|
||||
if (dragDropState !== 2 && dragDropPointID !== null && mouseIsDown && dragDropStartPos !== null) {
|
||||
let dist = getDistance(dragDropStartPos.x, dragDropStartPos.y, event.offsetX, event.offsetY)
|
||||
@ -1254,17 +1353,34 @@ voronoiCanvas.onmousemove = function(event) {
|
||||
updatePointWhenDragged(dragDropPointID);
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
// select point by clicking.
|
||||
// initiate drag-n-drop if already selected.
|
||||
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) {
|
||||
// Points need to be shown for drag-n-drop to work
|
||||
return;
|
||||
@ -1281,7 +1397,7 @@ voronoiCanvas.onmousedown = function(event) {
|
||||
if (alreadySelected) {
|
||||
dragDropState = 1;
|
||||
}
|
||||
updateDragDropCursorStatus();
|
||||
updateCanvasCursorStatus(event.offsetX, event.offsetY);
|
||||
}
|
||||
}
|
||||
voronoiCanvas.onmouseup = function(event) {
|
||||
@ -1300,7 +1416,10 @@ voronoiCanvas.onmouseleave = function() {
|
||||
dragDropStartPos = null;
|
||||
dragDropPointID = null;
|
||||
dragDropState = 0;
|
||||
canvas_cursor_x = null;
|
||||
canvas_cursor_y = null;
|
||||
coordinateDisplay.innerHTML = " ";
|
||||
draw(false);
|
||||
}
|
||||
|
||||
/* Biome list events */
|
||||
|
Loading…
x
Reference in New Issue
Block a user