Changed min token and note scale to 0.5 and fix grid snapping for non integer values

This commit is contained in:
Mitchell McCaffrey 2020-11-06 15:48:35 +11:00
parent 088466ea07
commit cb2c432d0a
5 changed files with 72 additions and 66 deletions

View File

@ -6,7 +6,7 @@ import useImage from "use-image";
import useDataSource from "../../helpers/useDataSource";
import useDebounce from "../../helpers/useDebounce";
import usePrevious from "../../helpers/usePrevious";
import * as Vector2 from "../../helpers/vector2";
import { snapNodeToMap } from "../../helpers/map";
import AuthContext from "../../contexts/AuthContext";
import MapInteractionContext from "../../contexts/MapInteractionContext";
@ -82,35 +82,7 @@ function MapToken({
const tokenGroup = event.target;
// Snap to corners of grid
if (map.snapToGrid) {
const offset = Vector2.multiply(map.grid.inset.topLeft, {
x: mapWidth,
y: mapHeight,
});
const position = {
x: tokenGroup.x() + tokenGroup.width() / 2,
y: tokenGroup.y() + tokenGroup.height() / 2,
};
const gridSize = {
x:
(mapWidth *
(map.grid.inset.bottomRight.x - map.grid.inset.topLeft.x)) /
map.grid.size.x,
y:
(mapHeight *
(map.grid.inset.bottomRight.y - map.grid.inset.topLeft.y)) /
map.grid.size.y,
};
// Transform into offset space, round, then transform back
const gridSnap = Vector2.add(
Vector2.roundTo(Vector2.subtract(position, offset), gridSize),
offset
);
const gridDistance = Vector2.length(Vector2.subtract(gridSnap, position));
const minGrid = Vector2.min(gridSize);
if (gridDistance < minGrid * snappingThreshold) {
tokenGroup.x(gridSnap.x - tokenGroup.width() / 2);
tokenGroup.y(gridSnap.y - tokenGroup.height() / 2);
}
snapNodeToMap(map, mapWidth, mapHeight, tokenGroup, snappingThreshold);
}
}

View File

@ -5,7 +5,7 @@ import { useSpring, animated } from "react-spring/konva";
import AuthContext from "../../contexts/AuthContext";
import MapInteractionContext from "../../contexts/MapInteractionContext";
import * as Vector2 from "../../helpers/vector2";
import { snapNodeToMap } from "../../helpers/map";
import colors from "../../helpers/colors";
import usePrevious from "../../helpers/usePrevious";
@ -37,35 +37,7 @@ function Note({
const noteGroup = event.target;
// Snap to corners of grid
if (map.snapToGrid) {
const offset = Vector2.multiply(map.grid.inset.topLeft, {
x: mapWidth,
y: mapHeight,
});
const position = {
x: noteGroup.x() + noteGroup.width() / 2,
y: noteGroup.y() + noteGroup.height() / 2,
};
const gridSize = {
x:
(mapWidth *
(map.grid.inset.bottomRight.x - map.grid.inset.topLeft.x)) /
map.grid.size.x,
y:
(mapHeight *
(map.grid.inset.bottomRight.y - map.grid.inset.topLeft.y)) /
map.grid.size.y,
};
// Transform into offset space, round, then transform back
const gridSnap = Vector2.add(
Vector2.roundTo(Vector2.subtract(position, offset), gridSize),
offset
);
const gridDistance = Vector2.length(Vector2.subtract(gridSnap, position));
const minGrid = Vector2.min(gridSize);
if (gridDistance < minGrid * snappingThreshold) {
noteGroup.x(gridSnap.x - noteGroup.width() / 2);
noteGroup.y(gridSnap.y - noteGroup.height() / 2);
}
snapNodeToMap(map, mapWidth, mapHeight, noteGroup, snappingThreshold);
}
}

View File

@ -63,7 +63,7 @@ function NoteMenu({
}
function handleSizeChange(event) {
const newSize = parseInt(event.target.value);
const newSize = parseFloat(event.target.value);
note && onNoteChange({ ...note, size: newSize });
}
@ -177,8 +177,8 @@ function NoteMenu({
<Slider
value={(note && note.size) || 1}
onChange={handleSizeChange}
step={1}
min={1}
step={0.5}
min={0.5}
max={noteMaxSize}
mr={1}
/>

View File

@ -72,7 +72,7 @@ function TokenMenu({
}
function handleSizeChange(event) {
const newSize = parseInt(event.target.value);
const newSize = parseFloat(event.target.value);
tokenState &&
onTokenStateChange({ [tokenState.id]: { ...tokenState, size: newSize } });
}
@ -211,8 +211,8 @@ function TokenMenu({
<Slider
value={(tokenState && tokenState.size) || 1}
onChange={handleSizeChange}
step={1}
min={1}
step={0.5}
min={0.5}
max={tokenMaxSize}
mr={1}
/>

View File

@ -1,4 +1,5 @@
import GridSizeModel from "../ml/gridSize/GridSizeModel";
import * as Vector2 from "./vector2";
import { logError } from "./logging";
@ -162,3 +163,64 @@ export function getMapMaxZoom(map) {
// Return max grid size / 2
return Math.max(Math.min(map.grid.size.x, map.grid.size.y) / 2, 5);
}
export function snapNodeToMap(
map,
mapWidth,
mapHeight,
node,
snappingThreshold
) {
const offset = Vector2.multiply(map.grid.inset.topLeft, {
x: mapWidth,
y: mapHeight,
});
const gridSize = {
x:
(mapWidth * (map.grid.inset.bottomRight.x - map.grid.inset.topLeft.x)) /
map.grid.size.x,
y:
(mapHeight * (map.grid.inset.bottomRight.y - map.grid.inset.topLeft.y)) /
map.grid.size.y,
};
const position = node.position();
const halfSize = Vector2.divide({ x: node.width(), y: node.height() }, 2);
// Offsets to tranform the centered position into the four corners
const cornerOffsets = [
halfSize,
{ x: -halfSize.x, y: -halfSize.y },
{ x: halfSize.x, y: -halfSize.y },
{ x: -halfSize.x, y: halfSize.y },
];
// Minimum distance from a corner to the grid
let minCornerGridDistance = Number.MAX_VALUE;
// Minimum component of the difference between the min corner and the grid
let minCornerMinComponent;
// Closest grid value
let minGridSnap;
// Find the closest corner to the grid
for (let cornerOffset of cornerOffsets) {
const corner = Vector2.add(position, cornerOffset);
// Transform into offset space, round, then transform back
const gridSnap = Vector2.add(
Vector2.roundTo(Vector2.subtract(corner, offset), gridSize),
offset
);
const gridDistance = Vector2.length(Vector2.subtract(gridSnap, corner));
const minComponent = Vector2.min(gridSize);
if (gridDistance < minCornerGridDistance) {
minCornerGridDistance = gridDistance;
minCornerMinComponent = minComponent;
// Move the grid value back to the center
minGridSnap = Vector2.subtract(gridSnap, cornerOffset);
}
}
if (minCornerGridDistance < minCornerMinComponent * snappingThreshold) {
node.position(minGridSnap);
}
}