mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: Support labels for arrow 🔥 (#5723)
* feat: support arrow with text * render arrow -> clear rect-> render text * move bound text when linear elements move * fix centering cursor when linear element rotated * fix y coord when new line added and container has 3 points * update text position when 2nd point moved * support adding label on top of 2nd point when 3 points are present * change linear element editor shortcut to cmd+enter and fix tests * scale bound text points when resizing via bounding box * ohh yeah rotation works :) * fix coords when updating text properties * calculate new position after rotation always from original position * rotate the bound text by same angle as parent * don't rotate text and make sure dimensions and coords are always calculated from original point * hardcoding the text width for now * Move the linear element when bound text hit * Rotation working yaay * consider text element angle when editing * refactor * update x2 coords if needed when text updated * simplify * consider bound text to be part of bounding box when hit * show bounding box correctly when multiple element selected * fix typo * support rotating multiple elements * support multiple element resizing * shift bound text to mid point when odd points * Always render linear element handles inside editor after element rendered so point is visible for bound text * Delete bound text when point attached to it deleted * move bound to mid segement mid point when points are even * shift bound text when points nearby deleted and handle segment deletion * Resize working :) * more resize fixes * don't update cache-its breaking delete points, look for better soln * update mid point cache for bound elements when updated * introduce wrapping when resizing * wrap when resize for 2 pointer linear elements * support adding text for linear elements with more than 3 points * export to svg working :) * clip from nearest enclosing element with non transparent color if present when exporting and fill with correct color in canvas * fix snap * use visible elements * Make export to svg work with Mask :) * remove id * mask canvas linear element area where label is added * decide the position of bound text during render * fix coords when editing * fix multiple resize * update cache when bound text version changes * fix masking when rotated * render text in correct position in preview * remove unnecessary code * fix masking when rotating linear element * fix masking with zoom * fix mask in preview for export * fix offsets in export view * fix coords on svg export * fix mask when element rotated in svg * enable double-click to enter text * fix hint * Position cursor correctly and text dimensiosn when height of element is negative * don't allow 2 pointer linear element with bound text width to go beyond min width * code cleanup * fix freedraw * Add padding * don't show vertical align action for linear element containers * Add specs for getBoundTextElementPosition * more specs * move some utils to linearElementEditor.ts * remove only :p * check absoulte coods in test * Add test to hide vertical align for linear eleemnt with bound text * improve export preview * support labels only for arrows * spec * fix large texts * fix tests * fix zooming * enter line editor with cmd+double click * Allow points to move beyond min width/height for 2 pointer arrow with bound text * fix hint for line editing * attempt to fix arrow getting deselected * fix hint and shortcut * Add padding of 5px when creating bound text and add spec * Wrap bound text when arrow binding containers moved * Add spec * remove * set boundTextElementVersion to null if not present * dont use cache when version mismatch * Add a padding of 5px vertically when creating text * Add box sizing content box * Set bound elements when text element created to fix the padding * fix zooming in editor * fix zoom in export * remove globalCompositeOperation and use clearRect instead of fillRect
This commit is contained in:
parent
1933116261
commit
760fd7b3a6
25 changed files with 1668 additions and 363 deletions
|
@ -348,7 +348,6 @@ export const _renderScene = ({
|
|||
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
context.save();
|
||||
context.scale(scale, scale);
|
||||
|
||||
// When doing calculations based on canvas width we should used normalized one
|
||||
const normalizedCanvasWidth = canvas.width / scale;
|
||||
const normalizedCanvasHeight = canvas.height / scale;
|
||||
|
@ -410,7 +409,7 @@ export const _renderScene = ({
|
|||
undefined;
|
||||
visibleElements.forEach((element) => {
|
||||
try {
|
||||
renderElement(element, rc, context, renderConfig);
|
||||
renderElement(element, rc, context, renderConfig, appState);
|
||||
// Getting the element using LinearElementEditor during collab mismatches version - being one head of visible elements due to
|
||||
// ShapeCache returns empty hence making sure that we get the
|
||||
// correct element from visible elements
|
||||
|
@ -440,7 +439,13 @@ export const _renderScene = ({
|
|||
// Paint selection element
|
||||
if (appState.selectionElement) {
|
||||
try {
|
||||
renderElement(appState.selectionElement, rc, context, renderConfig);
|
||||
renderElement(
|
||||
appState.selectionElement,
|
||||
rc,
|
||||
context,
|
||||
renderConfig,
|
||||
appState,
|
||||
);
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
}
|
||||
|
@ -453,6 +458,22 @@ export const _renderScene = ({
|
|||
renderBindingHighlight(context, renderConfig, suggestedBinding!);
|
||||
});
|
||||
}
|
||||
const locallySelectedElements = getSelectedElements(elements, appState);
|
||||
|
||||
// Getting the element using LinearElementEditor during collab mismatches version - being one head of visible elements due to
|
||||
// ShapeCache returns empty hence making sure that we get the
|
||||
// correct element from visible elements
|
||||
if (
|
||||
locallySelectedElements.length === 1 &&
|
||||
appState.editingLinearElement?.elementId === locallySelectedElements[0].id
|
||||
) {
|
||||
renderLinearPointHandles(
|
||||
context,
|
||||
appState,
|
||||
renderConfig,
|
||||
locallySelectedElements[0] as NonDeleted<ExcalidrawLinearElement>,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
appState.selectedLinearElement &&
|
||||
|
@ -466,7 +487,6 @@ export const _renderScene = ({
|
|||
!appState.multiElement &&
|
||||
!appState.editingLinearElement
|
||||
) {
|
||||
const locallySelectedElements = getSelectedElements(elements, appState);
|
||||
const showBoundingBox = shouldShowBoundingBox(
|
||||
locallySelectedElements,
|
||||
appState,
|
||||
|
@ -515,8 +535,8 @@ export const _renderScene = ({
|
|||
}
|
||||
|
||||
if (selectionColors.length) {
|
||||
const [elementX1, elementY1, elementX2, elementY2] =
|
||||
getElementAbsoluteCoords(element);
|
||||
const [elementX1, elementY1, elementX2, elementY2, cx, cy] =
|
||||
getElementAbsoluteCoords(element, true);
|
||||
acc.push({
|
||||
angle: element.angle,
|
||||
elementX1,
|
||||
|
@ -525,10 +545,12 @@ export const _renderScene = ({
|
|||
elementY2,
|
||||
selectionColors,
|
||||
dashed: !!renderConfig.remoteSelectedElementIds[element.id],
|
||||
cx,
|
||||
cy,
|
||||
});
|
||||
}
|
||||
return acc;
|
||||
}, [] as { angle: number; elementX1: number; elementY1: number; elementX2: number; elementY2: number; selectionColors: string[]; dashed?: boolean }[]);
|
||||
}, [] as { angle: number; elementX1: number; elementY1: number; elementX2: number; elementY2: number; selectionColors: string[]; dashed?: boolean; cx: number; cy: number }[]);
|
||||
|
||||
const addSelectionForGroupId = (groupId: GroupId) => {
|
||||
const groupElements = getElementsInGroup(elements, groupId);
|
||||
|
@ -540,8 +562,10 @@ export const _renderScene = ({
|
|||
elementX2,
|
||||
elementY1,
|
||||
elementY2,
|
||||
selectionColors: [selectionColor],
|
||||
selectionColors: [oc.black],
|
||||
dashed: true,
|
||||
cx: elementX1 + (elementX2 - elementX1) / 2,
|
||||
cy: elementY1 + (elementY2 - elementY1) / 2,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -600,7 +624,7 @@ export const _renderScene = ({
|
|||
context.lineWidth = lineWidth;
|
||||
context.setLineDash(initialLineDash);
|
||||
const transformHandles = getTransformHandlesFromCoords(
|
||||
[x1, y1, x2, y2],
|
||||
[x1, y1, x2, y2, (x1 + x2) / 2, (y1 + y2) / 2],
|
||||
0,
|
||||
renderConfig.zoom,
|
||||
"mouse",
|
||||
|
@ -861,6 +885,8 @@ const renderSelectionBorder = (
|
|||
elementY2: number;
|
||||
selectionColors: string[];
|
||||
dashed?: boolean;
|
||||
cx: number;
|
||||
cy: number;
|
||||
},
|
||||
padding = DEFAULT_SPACING * 2,
|
||||
) => {
|
||||
|
@ -871,6 +897,8 @@ const renderSelectionBorder = (
|
|||
elementX2,
|
||||
elementY2,
|
||||
selectionColors,
|
||||
cx,
|
||||
cy,
|
||||
dashed,
|
||||
} = elementProperties;
|
||||
const elementWidth = elementX2 - elementX1;
|
||||
|
@ -900,8 +928,8 @@ const renderSelectionBorder = (
|
|||
elementY1 - linePadding,
|
||||
elementWidth + linePadding * 2,
|
||||
elementHeight + linePadding * 2,
|
||||
elementX1 + elementWidth / 2,
|
||||
elementY1 + elementHeight / 2,
|
||||
cx,
|
||||
cy,
|
||||
angle,
|
||||
);
|
||||
}
|
||||
|
@ -1117,7 +1145,7 @@ export const renderSceneToSvg = (
|
|||
return;
|
||||
}
|
||||
// render elements
|
||||
elements.forEach((element) => {
|
||||
elements.forEach((element, index) => {
|
||||
if (!element.isDeleted) {
|
||||
try {
|
||||
renderElementToSvg(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue