feat: create new text with width (#8038)

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
Ryan Di 2024-05-28 21:53:52 +08:00 committed by GitHub
parent 4eb9463f26
commit 860308eb27
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 178 additions and 33 deletions

View file

@ -47,13 +47,18 @@ import {
getNormalizedCanvasDimensions,
} from "./helpers";
import oc from "open-color";
import { isFrameLikeElement, isLinearElement } from "../element/typeChecks";
import {
isFrameLikeElement,
isLinearElement,
isTextElement,
} from "../element/typeChecks";
import type {
ElementsMap,
ExcalidrawBindableElement,
ExcalidrawElement,
ExcalidrawFrameLikeElement,
ExcalidrawLinearElement,
ExcalidrawTextElement,
GroupId,
NonDeleted,
} from "../element/types";
@ -303,7 +308,6 @@ const renderSelectionBorder = (
cy: number;
activeEmbeddable: boolean;
},
padding = DEFAULT_TRANSFORM_HANDLE_SPACING * 2,
) => {
const {
angle,
@ -320,6 +324,8 @@ const renderSelectionBorder = (
const elementWidth = elementX2 - elementX1;
const elementHeight = elementY2 - elementY1;
const padding = DEFAULT_TRANSFORM_HANDLE_SPACING * 2;
const linePadding = padding / appState.zoom.value;
const lineWidth = 8 / appState.zoom.value;
const spaceWidth = 4 / appState.zoom.value;
@ -570,11 +576,34 @@ const renderTransformHandles = (
});
};
const renderTextBox = (
text: NonDeleted<ExcalidrawTextElement>,
context: CanvasRenderingContext2D,
appState: InteractiveCanvasAppState,
selectionColor: InteractiveCanvasRenderConfig["selectionColor"],
) => {
context.save();
const padding = (DEFAULT_TRANSFORM_HANDLE_SPACING * 2) / appState.zoom.value;
const width = text.width + padding * 2;
const height = text.height + padding * 2;
const cx = text.x + width / 2;
const cy = text.y + height / 2;
const shiftX = -(width / 2 + padding);
const shiftY = -(height / 2 + padding);
context.translate(cx + appState.scrollX, cy + appState.scrollY);
context.rotate(text.angle);
context.lineWidth = 1 / appState.zoom.value;
context.strokeStyle = selectionColor;
context.strokeRect(shiftX, shiftY, width, height);
context.restore();
};
const _renderInteractiveScene = ({
canvas,
elementsMap,
visibleElements,
selectedElements,
allElementsMap,
scale,
appState,
renderConfig,
@ -626,12 +655,31 @@ const _renderInteractiveScene = ({
// Paint selection element
if (appState.selectionElement) {
try {
renderSelectionElement(appState.selectionElement, context, appState);
renderSelectionElement(
appState.selectionElement,
context,
appState,
renderConfig.selectionColor,
);
} catch (error: any) {
console.error(error);
}
}
if (appState.editingElement && isTextElement(appState.editingElement)) {
const textElement = allElementsMap.get(appState.editingElement.id) as
| ExcalidrawTextElement
| undefined;
if (textElement && !textElement.autoResize) {
renderTextBox(
textElement,
context,
appState,
renderConfig.selectionColor,
);
}
}
if (appState.isBindingEnabled) {
appState.suggestedBindings
.filter((binding) => binding != null)
@ -810,7 +858,12 @@ const _renderInteractiveScene = ({
"mouse", // when we render we don't know which pointer type so use mouse,
getOmitSidesForDevice(device),
);
if (!appState.viewModeEnabled && showBoundingBox) {
if (
!appState.viewModeEnabled &&
showBoundingBox &&
// do not show transform handles when text is being edited
!isTextElement(appState.editingElement)
) {
renderTransformHandles(
context,
renderConfig,

View file

@ -24,6 +24,7 @@ import type { RoughCanvas } from "roughjs/bin/canvas";
import type {
StaticCanvasRenderConfig,
RenderableElementsMap,
InteractiveCanvasRenderConfig,
} from "../scene/types";
import { distance, getFontString, isRTL } from "../utils";
import { getCornerRadius, isRightAngle } from "../math";
@ -618,6 +619,7 @@ export const renderSelectionElement = (
element: NonDeletedExcalidrawElement,
context: CanvasRenderingContext2D,
appState: InteractiveCanvasAppState,
selectionColor: InteractiveCanvasRenderConfig["selectionColor"],
) => {
context.save();
context.translate(element.x + appState.scrollX, element.y + appState.scrollY);
@ -631,7 +633,7 @@ export const renderSelectionElement = (
context.fillRect(offset, offset, element.width, element.height);
context.lineWidth = 1 / appState.zoom.value;
context.strokeStyle = " rgb(105, 101, 219)";
context.strokeStyle = selectionColor;
context.strokeRect(offset, offset, element.width, element.height);
context.restore();