Compare commits

...

9 Commits

Author SHA1 Message Date
Panayiotis Lipiridis
8802ea62ca Grid 2021-02-03 13:59:40 +02:00
Panayiotis Lipiridis
3c86b014de Merge 2021-02-03 13:54:48 +02:00
Panayiotis Lipiridis
c6f06dd1fc Merge 2021-01-11 12:23:43 +02:00
Panayiotis Lipiridis
922e28a198 Update the state properly 2020-12-24 23:15:15 +02:00
Panayiotis Lipiridis
49363afac1 Tests 2020-12-24 20:34:12 +02:00
Panayiotis Lipiridis
28a1b9a787 order 2020-12-24 17:55:44 +02:00
Panayiotis Lipiridis
9cfab40343 cleanup 2020-12-24 17:52:41 +02:00
Panayiotis Lipiridis
1d7c5705b2 More 2020-12-24 17:51:26 +02:00
Panayiotis Lipiridis
40cd4caeec feat: Change grid size 2020-12-24 16:45:42 +02:00
11 changed files with 210 additions and 88 deletions

View File

@ -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,

View File

@ -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,
});

View File

@ -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 },

View File

@ -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 (

View File

@ -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>

View File

@ -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;

View File

@ -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,

View File

@ -74,7 +74,7 @@ const excalidrawDiagram = {
],
appState: {
viewBackgroundColor: "#ffffff",
gridSize: null,
gridSize: 20,
},
};

View File

@ -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

View File

@ -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) */