mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Merge remote-tracking branch 'origin/release' into danieljgeiger-mathjax
This commit is contained in:
commit
12c651af6d
93 changed files with 3292 additions and 958 deletions
|
@ -128,7 +128,11 @@ import {
|
|||
} from "../element/binding";
|
||||
import { LinearElementEditor } from "../element/linearElementEditor";
|
||||
import { mutateElement, newElementWith } from "../element/mutateElement";
|
||||
import { deepCopyElement, newFreeDrawElement } from "../element/newElement";
|
||||
import {
|
||||
deepCopyElement,
|
||||
duplicateElements,
|
||||
newFreeDrawElement,
|
||||
} from "../element/newElement";
|
||||
import {
|
||||
hasBoundTextElement,
|
||||
isArrowElement,
|
||||
|
@ -300,7 +304,7 @@ import {
|
|||
} from "../actions/actionCanvas";
|
||||
import { jotaiStore } from "../jotai";
|
||||
import { activeConfirmDialogAtom } from "./ActiveConfirmDialog";
|
||||
import { actionCreateContainerFromText } from "../actions/actionBoundText";
|
||||
import { actionWrapTextInContainer } from "../actions/actionBoundText";
|
||||
import BraveMeasureTextError from "./BraveMeasureTextError";
|
||||
|
||||
const deviceContextInitialValue = {
|
||||
|
@ -1686,35 +1690,22 @@ class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
const dx = x - elementsCenterX;
|
||||
const dy = y - elementsCenterY;
|
||||
const groupIdMap = new Map();
|
||||
|
||||
const [gridX, gridY] = getGridPoint(dx, dy, this.state.gridSize);
|
||||
|
||||
const oldIdToDuplicatedId = new Map();
|
||||
const newElements = elements.map((element) => {
|
||||
const newElement = duplicateElement(
|
||||
this.state.editingGroupId,
|
||||
groupIdMap,
|
||||
element,
|
||||
{
|
||||
const newElements = duplicateElements(
|
||||
elements.map((element) => {
|
||||
return newElementWith(element, {
|
||||
x: element.x + gridX - minX,
|
||||
y: element.y + gridY - minY,
|
||||
},
|
||||
);
|
||||
oldIdToDuplicatedId.set(element.id, newElement.id);
|
||||
return newElement;
|
||||
});
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
bindTextToShapeAfterDuplication(newElements, elements, oldIdToDuplicatedId);
|
||||
const nextElements = [
|
||||
...this.scene.getElementsIncludingDeleted(),
|
||||
...newElements,
|
||||
];
|
||||
fixBindingsAfterDuplication(nextElements, elements, oldIdToDuplicatedId);
|
||||
|
||||
if (opts.files) {
|
||||
this.files = { ...this.files, ...opts.files };
|
||||
}
|
||||
|
||||
this.scene.replaceAllElements(nextElements);
|
||||
|
||||
|
@ -1725,6 +1716,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
});
|
||||
|
||||
if (opts.files) {
|
||||
this.files = { ...this.files, ...opts.files };
|
||||
}
|
||||
|
||||
this.history.resumeRecording();
|
||||
|
||||
this.setState(
|
||||
|
@ -2799,7 +2794,6 @@ class App extends React.Component<AppProps, AppState> {
|
|||
strokeStyle: this.state.currentItemStrokeStyle,
|
||||
roughness: this.state.currentItemRoughness,
|
||||
opacity: this.state.currentItemOpacity,
|
||||
roundness: null,
|
||||
text: "",
|
||||
fontSize,
|
||||
fontFamily,
|
||||
|
@ -2812,8 +2806,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||
...selectSubtype(this.state, "text"),
|
||||
containerId: shouldBindToContainer ? container?.id : undefined,
|
||||
groupIds: container?.groupIds ?? [],
|
||||
locked: false,
|
||||
lineHeight,
|
||||
angle: container?.angle ?? 0,
|
||||
});
|
||||
|
||||
if (!existingTextElement && shouldBindToContainer && container) {
|
||||
|
@ -3563,6 +3557,43 @@ class App extends React.Component<AppProps, AppState> {
|
|||
this.setState({ contextMenu: null });
|
||||
}
|
||||
|
||||
this.updateGestureOnPointerDown(event);
|
||||
|
||||
// if dragging element is freedraw and another pointerdown event occurs
|
||||
// a second finger is on the screen
|
||||
// discard the freedraw element if it is very short because it is likely
|
||||
// just a spike, otherwise finalize the freedraw element when the second
|
||||
// finger is lifted
|
||||
if (
|
||||
event.pointerType === "touch" &&
|
||||
this.state.draggingElement &&
|
||||
this.state.draggingElement.type === "freedraw"
|
||||
) {
|
||||
const element = this.state.draggingElement as ExcalidrawFreeDrawElement;
|
||||
this.updateScene({
|
||||
...(element.points.length < 10
|
||||
? {
|
||||
elements: this.scene
|
||||
.getElementsIncludingDeleted()
|
||||
.filter((el) => el.id !== element.id),
|
||||
}
|
||||
: {}),
|
||||
appState: {
|
||||
draggingElement: null,
|
||||
editingElement: null,
|
||||
startBoundElement: null,
|
||||
suggestedBindings: [],
|
||||
selectedElementIds: Object.keys(this.state.selectedElementIds)
|
||||
.filter((key) => key !== element.id)
|
||||
.reduce((obj: { [id: string]: boolean }, key) => {
|
||||
obj[key] = this.state.selectedElementIds[key];
|
||||
return obj;
|
||||
}, {}),
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// remove any active selection when we start to interact with canvas
|
||||
// (mainly, we care about removing selection outside the component which
|
||||
// would prevent our copy handling otherwise)
|
||||
|
@ -3602,8 +3633,6 @@ class App extends React.Component<AppProps, AppState> {
|
|||
});
|
||||
this.savePointer(event.clientX, event.clientY, "down");
|
||||
|
||||
this.updateGestureOnPointerDown(event);
|
||||
|
||||
if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {
|
||||
return;
|
||||
}
|
||||
|
@ -6425,7 +6454,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
actionGroup,
|
||||
actionUnbindText,
|
||||
actionBindText,
|
||||
actionCreateContainerFromText,
|
||||
actionWrapTextInContainer,
|
||||
actionUngroup,
|
||||
CONTEXT_MENU_SEPARATOR,
|
||||
actionAddToLibrary,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue