Merge branch 'master' into make-elements-immutable

This commit is contained in:
Gasim Gasimzada 2020-01-09 15:44:45 +04:00
commit 0f3d659d18
3 changed files with 81 additions and 12 deletions

27
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,27 @@
# Contributing
## Setup
### Option 1 - Manual
1. Fork and clone the repo
1. Run `npm install` to install dependencies
1. Create a branch for your PR with `git checkout -b your-branch-name`
> To keep `master` branch pointing to remote repository and make
> pull requests from branches on your fork. To do this, run:
>
> ```sh
> git remote add upstream https://github.com/excalidraw/excalidraw.git
> git fetch upstream
> git branch --set-upstream-to=upstream/master master
> ```
### Option 2 - Codesandbox
1. Go to https://codesandbox.io/s/github/excalidraw/excalidraw
1. Connect your Github account
1. Go to Git tab on left side
1. Tap on `Fork Sandbox`
1. Write your code
1. Commit and PR automatically

View file

@ -10,7 +10,8 @@ import {
duplicateElement, duplicateElement,
resizeTest, resizeTest,
isTextElement, isTextElement,
textWysiwyg textWysiwyg,
getElementAbsoluteCoords
} from "./element"; } from "./element";
import { import {
clearSelection, clearSelection,
@ -115,6 +116,7 @@ export class App extends React.Component<{}, AppState> {
public componentDidMount() { public componentDidMount() {
document.addEventListener("keydown", this.onKeyDown, false); document.addEventListener("keydown", this.onKeyDown, false);
document.addEventListener("mousemove", this.getCurrentCursorPosition);
window.addEventListener("resize", this.onResize, false); window.addEventListener("resize", this.onResize, false);
const { elements: newElements, appState } = restoreFromLocalStorage(); const { elements: newElements, appState } = restoreFromLocalStorage();
@ -132,6 +134,11 @@ export class App extends React.Component<{}, AppState> {
public componentWillUnmount() { public componentWillUnmount() {
document.removeEventListener("keydown", this.onKeyDown, false); document.removeEventListener("keydown", this.onKeyDown, false);
document.removeEventListener(
"mousemove",
this.getCurrentCursorPosition,
false
);
window.removeEventListener("resize", this.onResize, false); window.removeEventListener("resize", this.onResize, false);
} }
@ -146,6 +153,8 @@ export class App extends React.Component<{}, AppState> {
viewBackgroundColor: "#ffffff", viewBackgroundColor: "#ffffff",
scrollX: 0, scrollX: 0,
scrollY: 0, scrollY: 0,
cursorX: 0,
cursorY: 0,
name: DEFAULT_PROJECT_NAME name: DEFAULT_PROJECT_NAME
}; };
@ -153,6 +162,10 @@ export class App extends React.Component<{}, AppState> {
this.forceUpdate(); this.forceUpdate();
}; };
private getCurrentCursorPosition = (e: MouseEvent) => {
this.setState({ cursorX: e.x, cursorY: e.y });
};
private onKeyDown = (event: KeyboardEvent) => { private onKeyDown = (event: KeyboardEvent) => {
if (isInputLike(event.target)) return; if (isInputLike(event.target)) return;
@ -367,11 +380,11 @@ export class App extends React.Component<{}, AppState> {
} }
}; };
private pasteFromClipboard = (x?: number, y?: number) => { private pasteFromClipboard = () => {
if (navigator.clipboard) { if (navigator.clipboard) {
navigator.clipboard navigator.clipboard
.readText() .readText()
.then(text => this.addElementsFromPaste(text, x, y)); .then(text => this.addElementsFromPaste(text));
} }
}; };
@ -660,7 +673,7 @@ export class App extends React.Component<{}, AppState> {
options: [ options: [
navigator.clipboard && { navigator.clipboard && {
label: "Paste", label: "Paste",
action: () => this.pasteFromClipboard(x, y) action: () => this.pasteFromClipboard()
} }
], ],
top: e.clientY, top: e.clientY,
@ -683,7 +696,7 @@ export class App extends React.Component<{}, AppState> {
}, },
navigator.clipboard && { navigator.clipboard && {
label: "Paste", label: "Paste",
action: () => this.pasteFromClipboard(x, y) action: () => this.pasteFromClipboard()
}, },
{ label: "Copy Styles", action: this.copyStyles }, { label: "Copy Styles", action: this.copyStyles },
{ label: "Paste Styles", action: this.pasteStyles }, { label: "Paste Styles", action: this.pasteStyles },
@ -1159,7 +1172,7 @@ export class App extends React.Component<{}, AppState> {
})); }));
}; };
private addElementsFromPaste = (paste: string, x?: number, y?: number) => { private addElementsFromPaste = (paste: string) => {
let parsedElements; let parsedElements;
try { try {
parsedElements = JSON.parse(paste); parsedElements = JSON.parse(paste);
@ -1171,12 +1184,39 @@ export class App extends React.Component<{}, AppState> {
) { ) {
elements = clearSelection(elements); elements = clearSelection(elements);
if (x == null) x = 10 - this.state.scrollX; let subCanvasX1 = Infinity;
if (y == null) y = 10 - this.state.scrollY; let subCanvasX2 = 0;
const minX = Math.min(...parsedElements.map(element => element.x)); let subCanvasY1 = Infinity;
const minY = Math.min(...parsedElements.map(element => element.y)); let subCanvasY2 = 0;
const dx = x - minX;
const dy = y - minY; //const minX = Math.min(parsedElements.map(element => element.x));
//const minY = Math.min(parsedElements.map(element => element.y));
const distance = (x: number, y: number) => {
return Math.abs(x > y ? x - y : y - x);
};
parsedElements.forEach(parsedElement => {
const [x1, y1, x2, y2] = getElementAbsoluteCoords(parsedElement);
subCanvasX1 = Math.min(subCanvasX1, x1);
subCanvasY1 = Math.min(subCanvasY1, y1);
subCanvasX2 = Math.max(subCanvasX2, x2);
subCanvasY2 = Math.max(subCanvasY2, y2);
});
const elementsCenterX = distance(subCanvasX1, subCanvasX2) / 2;
const elementsCenterY = distance(subCanvasY1, subCanvasY2) / 2;
const dx =
this.state.cursorX -
this.state.scrollX -
CANVAS_WINDOW_OFFSET_LEFT -
elementsCenterX;
const dy =
this.state.cursorY -
this.state.scrollY -
CANVAS_WINDOW_OFFSET_TOP -
elementsCenterY;
elements = [ elements = [
...elements, ...elements,

View file

@ -11,5 +11,7 @@ export type AppState = {
viewBackgroundColor: string; viewBackgroundColor: string;
scrollX: number; scrollX: number;
scrollY: number; scrollY: number;
cursorX: number;
cursorY: number;
name: string; name: string;
}; };