feat: bind text to container when clicked on filled shape or element stroke
This commit is contained in:
parent
0d7ee891e0
commit
4d1b31a171
@ -226,6 +226,7 @@ import {
|
||||
setEraserCursor,
|
||||
updateActiveTool,
|
||||
getShortcutKey,
|
||||
isTransparent,
|
||||
} from "../utils";
|
||||
import {
|
||||
ContextMenu,
|
||||
@ -264,6 +265,7 @@ import {
|
||||
getContainerCenter,
|
||||
getContainerDims,
|
||||
getTextBindableContainerAtPosition,
|
||||
isHittingContainerStroke,
|
||||
isValidTextContainer,
|
||||
} from "../element/textElement";
|
||||
import { isHittingElementNotConsideringBoundingBox } from "../element/collision";
|
||||
@ -2762,7 +2764,19 @@ class App extends React.Component<AppProps, AppState> {
|
||||
sceneY,
|
||||
);
|
||||
if (container) {
|
||||
if (isArrowElement(container) || hasBoundTextElement(container)) {
|
||||
if (
|
||||
isArrowElement(container) ||
|
||||
hasBoundTextElement(container) ||
|
||||
!isTransparent(
|
||||
(container as ExcalidrawTextContainer).backgroundColor,
|
||||
) ||
|
||||
isHittingContainerStroke(
|
||||
sceneX,
|
||||
sceneY,
|
||||
container,
|
||||
this.state.zoom.value,
|
||||
)
|
||||
) {
|
||||
const midPoint = getContainerCenter(container, this.state);
|
||||
|
||||
sceneX = midPoint.x;
|
||||
|
@ -11,7 +11,7 @@ import { mutateElement } from "./mutateElement";
|
||||
import { BOUND_TEXT_PADDING, TEXT_ALIGN, VERTICAL_ALIGN } from "../constants";
|
||||
import { MaybeTransformHandleType } from "./transformHandles";
|
||||
import Scene from "../scene/Scene";
|
||||
import { isTextElement } from ".";
|
||||
import { getElementBounds, isTextElement } from ".";
|
||||
import { getMaxContainerHeight, getMaxContainerWidth } from "./newElement";
|
||||
import {
|
||||
isBoundToContainer,
|
||||
@ -723,3 +723,62 @@ export const isValidTextContainer = (element: ExcalidrawElement) => {
|
||||
isArrowElement(element)
|
||||
);
|
||||
};
|
||||
|
||||
export const isHittingContainerStroke = (
|
||||
x: number,
|
||||
y: number,
|
||||
container: ExcalidrawTextContainer,
|
||||
zoom: number,
|
||||
) => {
|
||||
const threshold = 10 / zoom;
|
||||
const bounds = getElementBounds(container);
|
||||
const topLeft = [bounds[0], bounds[1]];
|
||||
const topRight = [bounds[2], bounds[1]];
|
||||
const bottomLeft = [bounds[0], bounds[3]];
|
||||
const bottomRight = [bounds[2], bounds[3]];
|
||||
|
||||
const strokeWidth = container.strokeWidth;
|
||||
if (container.type === "ellipse") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Left Stroke
|
||||
if (
|
||||
x >= topLeft[0] - threshold &&
|
||||
x <= topLeft[0] + strokeWidth + threshold &&
|
||||
y >= topLeft[1] - threshold &&
|
||||
y <= bottomRight[1] + threshold
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// Top stroke
|
||||
if (
|
||||
x >= topLeft[0] - threshold &&
|
||||
x <= topRight[0] + threshold &&
|
||||
y >= topLeft[1] - threshold &&
|
||||
y <= topLeft[1] + threshold + strokeWidth
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Right stroke
|
||||
if (
|
||||
x >= topRight[0] - threshold - strokeWidth &&
|
||||
x <= topRight[0] + threshold &&
|
||||
y >= topRight[1] - threshold &&
|
||||
y <= bottomRight[1] + threshold
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Bottom Stroke
|
||||
if (
|
||||
x >= bottomLeft[0] - threshold &&
|
||||
x <= bottomRight[0] + threshold &&
|
||||
y >= bottomLeft[1] - threshold - strokeWidth &&
|
||||
y <= bottomLeft[1] + threshold
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user