2021-02-06 19:29:24 +11:00
|
|
|
import Vector2 from "../helpers/Vector2";
|
2021-02-07 11:16:36 +11:00
|
|
|
import {
|
|
|
|
|
getCellLocation,
|
|
|
|
|
getNearestCellCoordinates,
|
|
|
|
|
getCellCorners,
|
|
|
|
|
} from "../helpers/grid";
|
2021-02-06 19:29:24 +11:00
|
|
|
|
2021-02-07 16:42:29 +11:00
|
|
|
import useSetting from "./useSetting";
|
|
|
|
|
|
2021-02-06 19:29:24 +11:00
|
|
|
import { useGrid } from "../contexts/GridContext";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a function that when called will snap a node to the current grid
|
2021-02-07 16:42:29 +11:00
|
|
|
* @param {number=} snappingSensitivity 1 = Always snap, 0 = never snap if undefined the default user setting will be used
|
2021-02-06 19:29:24 +11:00
|
|
|
*/
|
2021-02-07 16:42:29 +11:00
|
|
|
function useGridSnapping(snappingSensitivity) {
|
|
|
|
|
const [defaultSnappingSensitivity] = useSetting(
|
|
|
|
|
"map.gridSnappingSensitivity"
|
|
|
|
|
);
|
|
|
|
|
snappingSensitivity = snappingSensitivity || defaultSnappingSensitivity;
|
|
|
|
|
|
2021-02-07 11:16:36 +11:00
|
|
|
const { grid, gridOffset, gridCellPixelSize } = useGrid();
|
2021-02-06 19:29:24 +11:00
|
|
|
|
|
|
|
|
/**
|
2021-02-09 14:13:08 +11:00
|
|
|
* @param {Vector2} node The node to snap
|
2021-02-06 19:29:24 +11:00
|
|
|
*/
|
2021-02-09 14:13:08 +11:00
|
|
|
function snapPositionToGrid(position) {
|
2021-02-07 11:16:36 +11:00
|
|
|
// Account for grid offset
|
|
|
|
|
let offsetPosition = Vector2.subtract(position, gridOffset);
|
|
|
|
|
// Move hex tiles to top left
|
|
|
|
|
if (grid.type === "hexVertical" || grid.type === "hexHorizontal") {
|
|
|
|
|
offsetPosition = Vector2.subtract(
|
|
|
|
|
offsetPosition,
|
|
|
|
|
Vector2.multiply(gridCellPixelSize, 0.5)
|
2021-02-06 19:29:24 +11:00
|
|
|
);
|
|
|
|
|
}
|
2021-02-07 11:16:36 +11:00
|
|
|
const nearsetCell = getNearestCellCoordinates(
|
|
|
|
|
grid,
|
|
|
|
|
offsetPosition.x,
|
|
|
|
|
offsetPosition.y,
|
|
|
|
|
gridCellPixelSize
|
|
|
|
|
);
|
|
|
|
|
const cellPosition = getCellLocation(
|
|
|
|
|
grid,
|
|
|
|
|
nearsetCell.x,
|
|
|
|
|
nearsetCell.y,
|
|
|
|
|
gridCellPixelSize
|
2021-02-06 19:29:24 +11:00
|
|
|
);
|
2021-02-07 11:16:36 +11:00
|
|
|
const cellCorners = getCellCorners(
|
|
|
|
|
grid,
|
|
|
|
|
cellPosition.x,
|
|
|
|
|
cellPosition.y,
|
|
|
|
|
gridCellPixelSize
|
2021-02-06 19:29:24 +11:00
|
|
|
);
|
|
|
|
|
|
2021-02-07 11:16:36 +11:00
|
|
|
const snapPoints = [cellPosition, ...cellCorners];
|
|
|
|
|
|
|
|
|
|
for (let snapPoint of snapPoints) {
|
|
|
|
|
const distanceToSnapPoint = Vector2.distance(offsetPosition, snapPoint);
|
|
|
|
|
if (
|
|
|
|
|
distanceToSnapPoint <
|
2021-02-07 16:42:29 +11:00
|
|
|
Vector2.min(gridCellPixelSize) * snappingSensitivity
|
2021-02-07 11:16:36 +11:00
|
|
|
) {
|
|
|
|
|
// Reverse grid offset
|
|
|
|
|
let offsetSnapPoint = Vector2.add(snapPoint, gridOffset);
|
|
|
|
|
// Reverse offset for hex tiles
|
|
|
|
|
if (grid.type === "hexVertical" || grid.type === "hexHorizontal") {
|
|
|
|
|
offsetSnapPoint = Vector2.add(
|
|
|
|
|
offsetSnapPoint,
|
|
|
|
|
Vector2.multiply(gridCellPixelSize, 0.5)
|
|
|
|
|
);
|
|
|
|
|
}
|
2021-02-09 14:13:08 +11:00
|
|
|
return offsetSnapPoint;
|
2021-02-07 11:16:36 +11:00
|
|
|
}
|
2021-02-06 19:29:24 +11:00
|
|
|
}
|
2021-02-09 14:13:08 +11:00
|
|
|
|
|
|
|
|
return position;
|
2021-02-06 19:29:24 +11:00
|
|
|
}
|
|
|
|
|
|
2021-02-09 14:13:08 +11:00
|
|
|
return snapPositionToGrid;
|
2021-02-06 19:29:24 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default useGridSnapping;
|