2021-02-06 03:29:24 -05:00
|
|
|
import Vector2 from "../helpers/Vector2";
|
2021-02-06 19:16:36 -05:00
|
|
|
import {
|
|
|
|
getCellLocation,
|
|
|
|
getNearestCellCoordinates,
|
|
|
|
getCellCorners,
|
|
|
|
} from "../helpers/grid";
|
2021-02-06 03:29:24 -05:00
|
|
|
|
2021-03-11 19:02:58 -05:00
|
|
|
import {
|
|
|
|
useGrid,
|
|
|
|
useGridOffset,
|
|
|
|
useGridCellPixelSize,
|
|
|
|
useGridCellPixelOffset,
|
2021-08-03 18:32:27 -04:00
|
|
|
useGridSnappingSensitivity,
|
2021-03-11 19:02:58 -05:00
|
|
|
} from "../contexts/GridContext";
|
2021-02-06 03:29:24 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a function that when called will snap a node to the current grid
|
2021-02-07 00:42:29 -05:00
|
|
|
* @param {number=} snappingSensitivity 1 = Always snap, 0 = never snap if undefined the default user setting will be used
|
2021-06-18 19:36:00 -04:00
|
|
|
* @param {boolean=} useCorners Snap to grid cell corners
|
2021-02-06 03:29:24 -05:00
|
|
|
*/
|
2021-07-13 04:50:18 -04:00
|
|
|
function useGridSnapping(
|
|
|
|
snappingSensitivity: number | undefined = undefined,
|
|
|
|
useCorners: boolean = true
|
|
|
|
) {
|
2021-08-03 18:32:27 -04:00
|
|
|
const defaultSnappingSensitivity = useGridSnappingSensitivity();
|
|
|
|
let gridSnappingSensitivity: number;
|
|
|
|
if (defaultSnappingSensitivity === -1) {
|
|
|
|
// Snapping disabled via shortcut
|
|
|
|
gridSnappingSensitivity = 0;
|
|
|
|
} else if (snappingSensitivity === undefined) {
|
|
|
|
gridSnappingSensitivity = defaultSnappingSensitivity;
|
|
|
|
} else {
|
|
|
|
gridSnappingSensitivity = snappingSensitivity;
|
|
|
|
}
|
2021-02-07 00:42:29 -05:00
|
|
|
|
2021-03-11 19:02:58 -05:00
|
|
|
const grid = useGrid();
|
|
|
|
const gridOffset = useGridOffset();
|
|
|
|
const gridCellPixelSize = useGridCellPixelSize();
|
|
|
|
const gridCellPixelOffset = useGridCellPixelOffset();
|
2021-02-06 03:29:24 -05:00
|
|
|
|
|
|
|
/**
|
2021-02-08 22:13:08 -05:00
|
|
|
* @param {Vector2} node The node to snap
|
2021-02-06 03:29:24 -05:00
|
|
|
*/
|
2021-07-13 04:50:18 -04:00
|
|
|
function snapPositionToGrid(position: Vector2) {
|
2021-02-06 19:16:36 -05:00
|
|
|
// Account for grid offset
|
2021-02-11 03:57:34 -05:00
|
|
|
let offsetPosition = Vector2.subtract(
|
|
|
|
Vector2.subtract(position, gridOffset),
|
|
|
|
gridCellPixelOffset
|
|
|
|
);
|
2021-02-06 19:16:36 -05:00
|
|
|
const nearsetCell = getNearestCellCoordinates(
|
|
|
|
grid,
|
|
|
|
offsetPosition.x,
|
|
|
|
offsetPosition.y,
|
|
|
|
gridCellPixelSize
|
|
|
|
);
|
|
|
|
const cellPosition = getCellLocation(
|
|
|
|
grid,
|
|
|
|
nearsetCell.x,
|
|
|
|
nearsetCell.y,
|
|
|
|
gridCellPixelSize
|
2021-02-06 03:29:24 -05:00
|
|
|
);
|
2021-02-06 19:16:36 -05:00
|
|
|
const cellCorners = getCellCorners(
|
|
|
|
grid,
|
|
|
|
cellPosition.x,
|
|
|
|
cellPosition.y,
|
|
|
|
gridCellPixelSize
|
2021-02-06 03:29:24 -05:00
|
|
|
);
|
|
|
|
|
2021-06-18 19:36:00 -04:00
|
|
|
const snapPoints = [cellPosition];
|
|
|
|
if (useCorners) {
|
|
|
|
snapPoints.push(...cellCorners);
|
|
|
|
}
|
2021-02-06 19:16:36 -05:00
|
|
|
|
|
|
|
for (let snapPoint of snapPoints) {
|
|
|
|
const distanceToSnapPoint = Vector2.distance(offsetPosition, snapPoint);
|
|
|
|
if (
|
|
|
|
distanceToSnapPoint <
|
2021-07-16 00:55:33 -04:00
|
|
|
Vector2.componentMin(gridCellPixelSize) * gridSnappingSensitivity
|
2021-02-06 19:16:36 -05:00
|
|
|
) {
|
|
|
|
// Reverse grid offset
|
2021-02-11 03:57:34 -05:00
|
|
|
let offsetSnapPoint = Vector2.add(
|
|
|
|
Vector2.add(snapPoint, gridOffset),
|
|
|
|
gridCellPixelOffset
|
|
|
|
);
|
2021-02-08 22:13:08 -05:00
|
|
|
return offsetSnapPoint;
|
2021-02-06 19:16:36 -05:00
|
|
|
}
|
2021-02-06 03:29:24 -05:00
|
|
|
}
|
2021-02-08 22:13:08 -05:00
|
|
|
|
|
|
|
return position;
|
2021-02-06 03:29:24 -05:00
|
|
|
}
|
|
|
|
|
2021-02-08 22:13:08 -05:00
|
|
|
return snapPositionToGrid;
|
2021-02-06 03:29:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
export default useGridSnapping;
|