Compare commits
9 Commits
master
...
change-gri
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8802ea62ca | ||
![]() |
3c86b014de | ||
![]() |
c6f06dd1fc | ||
![]() |
922e28a198 | ||
![]() |
49363afac1 | ||
![]() |
28a1b9a787 | ||
![]() |
9cfab40343 | ||
![]() |
1d7c5705b2 | ||
![]() |
40cd4caeec |
@ -3,7 +3,7 @@ import { getDefaultAppState } from "../appState";
|
||||
import { ColorPicker } from "../components/ColorPicker";
|
||||
import { resetZoom, trash, zoomIn, zoomOut } from "../components/icons";
|
||||
import { ToolButton } from "../components/ToolButton";
|
||||
import { ZOOM_STEP } from "../constants";
|
||||
import { GRID_SIZE, ZOOM_STEP } from "../constants";
|
||||
import { getCommonBounds, getNonDeletedElements } from "../element";
|
||||
import { newElementWith } from "../element/mutateElement";
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
@ -52,7 +52,7 @@ export const actionClearCanvas = register({
|
||||
elementLocked: appState.elementLocked,
|
||||
exportBackground: appState.exportBackground,
|
||||
exportEmbedScene: appState.exportEmbedScene,
|
||||
gridSize: appState.gridSize,
|
||||
gridSize: appState.gridSize || GRID_SIZE,
|
||||
shouldAddWatermark: appState.shouldAddWatermark,
|
||||
showStats: appState.showStats,
|
||||
pasteDialog: appState.pasteDialog,
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { CODES, KEYS } from "../keys";
|
||||
import { register } from "./register";
|
||||
import { GRID_SIZE } from "../constants";
|
||||
import { AppState } from "../types";
|
||||
import { trackEvent } from "../analytics";
|
||||
import { CODES, KEYS } from "../keys";
|
||||
import { AppState } from "../types";
|
||||
import { register } from "./register";
|
||||
|
||||
export const actionToggleGridMode = register({
|
||||
name: "gridMode",
|
||||
@ -11,12 +10,12 @@ export const actionToggleGridMode = register({
|
||||
return {
|
||||
appState: {
|
||||
...appState,
|
||||
gridSize: this.checked!(appState) ? null : GRID_SIZE,
|
||||
showGrid: !appState.showGrid,
|
||||
},
|
||||
commitToHistory: false,
|
||||
};
|
||||
},
|
||||
checked: (appState: AppState) => appState.gridSize !== null,
|
||||
checked: (appState: AppState) => appState.showGrid,
|
||||
contextItemLabel: "labels.gridMode",
|
||||
keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.code === CODES.QUOTE,
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
DEFAULT_FONT_FAMILY,
|
||||
DEFAULT_FONT_SIZE,
|
||||
DEFAULT_TEXT_ALIGN,
|
||||
GRID_SIZE,
|
||||
} from "./constants";
|
||||
import { t } from "./i18n";
|
||||
import { AppState, NormalizedZoomValue } from "./types";
|
||||
@ -41,7 +42,7 @@ export const getDefaultAppState = (): Omit<
|
||||
exportBackground: true,
|
||||
exportEmbedScene: false,
|
||||
fileHandle: null,
|
||||
gridSize: null,
|
||||
gridSize: GRID_SIZE,
|
||||
height: window.innerHeight,
|
||||
isBindingEnabled: true,
|
||||
isLibraryOpen: false,
|
||||
@ -63,6 +64,7 @@ export const getDefaultAppState = (): Omit<
|
||||
selectionElement: null,
|
||||
shouldAddWatermark: false,
|
||||
shouldCacheIgnoreZoom: false,
|
||||
showGrid: false,
|
||||
showHelpDialog: false,
|
||||
showStats: false,
|
||||
startBoundElement: null,
|
||||
@ -120,6 +122,7 @@ const APP_STATE_STORAGE_CONF = (<
|
||||
exportEmbedScene: { browser: true, export: false },
|
||||
fileHandle: { browser: false, export: false },
|
||||
gridSize: { browser: true, export: true },
|
||||
showGrid: { browser: true, export: false },
|
||||
height: { browser: false, export: false },
|
||||
isBindingEnabled: { browser: false, export: false },
|
||||
isLibraryOpen: { browser: false, export: false },
|
||||
|
@ -456,6 +456,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
/>
|
||||
{this.state.showStats && (
|
||||
<Stats
|
||||
setAppState={this.setAppState}
|
||||
appState={this.state}
|
||||
elements={this.scene.getElements()}
|
||||
onClose={this.toggleStats}
|
||||
@ -1087,7 +1088,12 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
const dy = y - elementsCenterY;
|
||||
const groupIdMap = new Map();
|
||||
|
||||
const [gridX, gridY] = getGridPoint(dx, dy, this.state.gridSize);
|
||||
const [gridX, gridY] = getGridPoint(
|
||||
dx,
|
||||
dy,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
|
||||
const oldIdToDuplicatedId = new Map();
|
||||
const newElements = clipboardElements.map((element) => {
|
||||
@ -1195,6 +1201,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
this.actionManager.executeAction(actionToggleZenMode);
|
||||
};
|
||||
|
||||
toggleGridMode = () => {
|
||||
this.actionManager.executeAction(actionToggleGridMode);
|
||||
};
|
||||
|
||||
toggleStats = () => {
|
||||
if (!this.state.showStats) {
|
||||
trackEvent("dialog", "stats");
|
||||
@ -1307,7 +1317,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
|
||||
if (isArrowKey(event.key)) {
|
||||
const step =
|
||||
(this.state.gridSize &&
|
||||
(this.state.showGrid &&
|
||||
(event.shiftKey ? ELEMENT_TRANSLATE_AMOUNT : this.state.gridSize)) ||
|
||||
(event.shiftKey
|
||||
? ELEMENT_SHIFT_TRANSLATE_AMOUNT
|
||||
@ -1849,6 +1859,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
scenePointerX,
|
||||
scenePointerY,
|
||||
this.state.editingLinearElement,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
if (editingLinearElement !== this.state.editingLinearElement) {
|
||||
@ -2278,7 +2289,12 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
return {
|
||||
origin,
|
||||
originInGrid: tupleToCoors(
|
||||
getGridPoint(origin.x, origin.y, this.state.gridSize),
|
||||
getGridPoint(
|
||||
origin.x,
|
||||
origin.y,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
),
|
||||
),
|
||||
scrollbars: isOverScrollBars(
|
||||
currentScrollBars,
|
||||
@ -2634,7 +2650,8 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
const [gridX, gridY] = getGridPoint(
|
||||
pointerDownState.origin.x,
|
||||
pointerDownState.origin.y,
|
||||
elementType === "draw" ? null : this.state.gridSize,
|
||||
elementType === "draw" ? false : this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
|
||||
/* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.
|
||||
@ -2696,6 +2713,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
const [gridX, gridY] = getGridPoint(
|
||||
pointerDownState.origin.x,
|
||||
pointerDownState.origin.y,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
const element = newElement({
|
||||
@ -2785,6 +2803,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
const [gridX, gridY] = getGridPoint(
|
||||
pointerCoords.x,
|
||||
pointerCoords.y,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
|
||||
@ -2857,6 +2876,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
const [dragX, dragY] = getGridPoint(
|
||||
pointerCoords.x - pointerDownState.drag.offset.x,
|
||||
pointerCoords.y - pointerDownState.drag.offset.y,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
|
||||
@ -2909,6 +2929,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
const [originDragX, originDragY] = getGridPoint(
|
||||
pointerDownState.origin.x - pointerDownState.drag.offset.x,
|
||||
pointerDownState.origin.y - pointerDownState.drag.offset.y,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
mutateElement(duplicatedElement, {
|
||||
@ -3565,6 +3586,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
const [gridX, gridY] = getGridPoint(
|
||||
pointerCoords.x,
|
||||
pointerCoords.y,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
dragNewElement(
|
||||
@ -3603,6 +3625,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
||||
const [resizeX, resizeY] = getGridPoint(
|
||||
pointerCoords.x - pointerDownState.resize.offset.x,
|
||||
pointerCoords.y - pointerDownState.resize.offset.y,
|
||||
this.state.showGrid,
|
||||
this.state.gridSize,
|
||||
);
|
||||
if (
|
||||
|
@ -24,6 +24,7 @@ const getStorageSizes = debounce((cb: (sizes: StorageSizes) => void) => {
|
||||
}, 500);
|
||||
|
||||
export const Stats = (props: {
|
||||
setAppState: React.Component<any, AppState>["setState"];
|
||||
appState: AppState;
|
||||
elements: readonly NonDeletedExcalidrawElement[];
|
||||
onClose: () => void;
|
||||
@ -46,6 +47,12 @@ export const Stats = (props: {
|
||||
const selectedElements = getTargetElements(props.elements, props.appState);
|
||||
const selectedBoundingBox = getCommonBounds(selectedElements);
|
||||
|
||||
const onGridSizeChange = () => {
|
||||
props.setAppState({
|
||||
gridSize: ((props.appState.gridSize - 5) % 50) + 10,
|
||||
});
|
||||
};
|
||||
|
||||
if (isMobile && props.appState.openMenu) {
|
||||
return null;
|
||||
}
|
||||
@ -156,6 +163,17 @@ export const Stats = (props: {
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{props.appState.showGrid && (
|
||||
<>
|
||||
<tr>
|
||||
<th colSpan={2}>{"Misc"}</th>
|
||||
</tr>
|
||||
<tr onClick={onGridSizeChange} style={{ cursor: "pointer" }}>
|
||||
<td>{"Grid size"}</td>
|
||||
<td>{props.appState.gridSize}</td>
|
||||
</tr>
|
||||
</>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</Island>
|
||||
|
@ -102,6 +102,7 @@ export class LinearElementEditor {
|
||||
element,
|
||||
scenePointerX - editingLinearElement.pointerOffset.x,
|
||||
scenePointerY - editingLinearElement.pointerOffset.y,
|
||||
appState.showGrid,
|
||||
appState.gridSize,
|
||||
);
|
||||
LinearElementEditor.movePoint(element, activePointIndex, newPoint);
|
||||
@ -198,6 +199,7 @@ export class LinearElementEditor {
|
||||
element,
|
||||
scenePointer.x,
|
||||
scenePointer.y,
|
||||
appState.showGrid,
|
||||
appState.gridSize,
|
||||
),
|
||||
],
|
||||
@ -282,7 +284,8 @@ export class LinearElementEditor {
|
||||
scenePointerX: number,
|
||||
scenePointerY: number,
|
||||
editingLinearElement: LinearElementEditor,
|
||||
gridSize: number | null,
|
||||
isGridOn: boolean,
|
||||
gridSize: number,
|
||||
): LinearElementEditor {
|
||||
const { elementId, lastUncommittedPoint } = editingLinearElement;
|
||||
const element = LinearElementEditor.getElement(elementId);
|
||||
@ -304,6 +307,7 @@ export class LinearElementEditor {
|
||||
element,
|
||||
scenePointerX - editingLinearElement.pointerOffset.x,
|
||||
scenePointerY - editingLinearElement.pointerOffset.y,
|
||||
isGridOn,
|
||||
gridSize,
|
||||
);
|
||||
|
||||
@ -398,9 +402,15 @@ export class LinearElementEditor {
|
||||
element: NonDeleted<ExcalidrawLinearElement>,
|
||||
scenePointerX: number,
|
||||
scenePointerY: number,
|
||||
gridSize: number | null,
|
||||
isGridOn: boolean,
|
||||
gridSize: number,
|
||||
): Point {
|
||||
const pointerOnGrid = getGridPoint(scenePointerX, scenePointerY, gridSize);
|
||||
const pointerOnGrid = getGridPoint(
|
||||
scenePointerX,
|
||||
scenePointerY,
|
||||
isGridOn,
|
||||
gridSize,
|
||||
);
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||
const cx = (x1 + x2) / 2;
|
||||
const cy = (y1 + y2) / 2;
|
||||
|
@ -249,9 +249,10 @@ const doSegmentsIntersect = (p1: Point, q1: Point, p2: Point, q2: Point) => {
|
||||
export const getGridPoint = (
|
||||
x: number,
|
||||
y: number,
|
||||
gridSize: number | null,
|
||||
isGridOn: boolean,
|
||||
gridSize: number,
|
||||
): [number, number] => {
|
||||
if (gridSize) {
|
||||
if (isGridOn) {
|
||||
return [
|
||||
Math.round(x / gridSize) * gridSize,
|
||||
Math.round(y / gridSize) * gridSize,
|
||||
|
@ -74,7 +74,7 @@ const excalidrawDiagram = {
|
||||
],
|
||||
appState: {
|
||||
viewBackgroundColor: "#ffffff",
|
||||
gridSize: null,
|
||||
gridSize: 20,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -233,7 +233,7 @@ export const renderScene = (
|
||||
context.scale(sceneState.zoom.value, sceneState.zoom.value);
|
||||
|
||||
// Grid
|
||||
if (renderGrid && appState.gridSize) {
|
||||
if (renderGrid && appState.showGrid) {
|
||||
strokeGrid(
|
||||
context,
|
||||
appState.gridSize,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -84,7 +84,8 @@ export type AppState = {
|
||||
toastMessage: string | null;
|
||||
zenModeEnabled: boolean;
|
||||
appearance: "light" | "dark";
|
||||
gridSize: number | null;
|
||||
gridSize: number;
|
||||
showGrid: boolean;
|
||||
viewModeEnabled: boolean;
|
||||
|
||||
/** top-most selected groups (i.e. does not include nested groups) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user