Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ef8bcbe1f8 | |||
| 02d5cc4174 | |||
| 2f4d051ea1 | |||
| 0b0846bd8e | |||
| 330b3a0530 | |||
| cd195374bc | |||
| 8971d06655 | |||
| 1e4e37b87f | |||
| 189a557ed6 | |||
| bff2f9178d | |||
| 9b5715623a | |||
| 3487f0ab26 | |||
| 76910828c2 | |||
| fde521ef4d | |||
| bcb45f7cf6 |
@@ -33,6 +33,9 @@ export const actionFinalize = register({
|
||||
endBindingElement,
|
||||
);
|
||||
}
|
||||
const selectedLinearElement = appState.selectedLinearElement
|
||||
? new LinearElementEditor(element, scene, appState)
|
||||
: null;
|
||||
return {
|
||||
elements:
|
||||
element.points.length < 2 || isInvisiblySmallElement(element)
|
||||
@@ -42,6 +45,7 @@ export const actionFinalize = register({
|
||||
...appState,
|
||||
cursorButton: "up",
|
||||
editingLinearElement: null,
|
||||
selectedLinearElement,
|
||||
},
|
||||
commitToHistory: true,
|
||||
};
|
||||
@@ -184,7 +188,7 @@ export const actionFinalize = register({
|
||||
// To select the linear element when user has finished mutipoint editing
|
||||
selectedLinearElement:
|
||||
multiPointElement && isLinearElement(multiPointElement)
|
||||
? new LinearElementEditor(multiPointElement, scene)
|
||||
? new LinearElementEditor(multiPointElement, scene, appState)
|
||||
: appState.selectedLinearElement,
|
||||
pendingImageElementId: null,
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ export const actionSelectAll = register({
|
||||
// single linear element selected
|
||||
Object.keys(selectedElementIds).length === 1 &&
|
||||
isLinearElement(elements[0])
|
||||
? new LinearElementEditor(elements[0], app.scene)
|
||||
? new LinearElementEditor(elements[0], app.scene, appState)
|
||||
: null,
|
||||
editingGroupId: null,
|
||||
selectedElementIds,
|
||||
|
||||
+16
-3
@@ -1907,6 +1907,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||
editingLinearElement: new LinearElementEditor(
|
||||
selectedElements[0],
|
||||
this.scene,
|
||||
this.state,
|
||||
true,
|
||||
),
|
||||
});
|
||||
}
|
||||
@@ -2399,6 +2401,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const element = existingTextElement
|
||||
? existingTextElement
|
||||
: newTextElement({
|
||||
@@ -2484,6 +2487,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||
editingLinearElement: new LinearElementEditor(
|
||||
selectedElements[0],
|
||||
this.scene,
|
||||
this.state,
|
||||
true,
|
||||
),
|
||||
});
|
||||
}
|
||||
@@ -3070,7 +3075,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
])
|
||||
) {
|
||||
hoverPointIndex = LinearElementEditor.getPointIndexUnderCursor(
|
||||
element,
|
||||
this.state.selectedLinearElement,
|
||||
this.state.zoom,
|
||||
scenePointerX,
|
||||
scenePointerY,
|
||||
@@ -4487,6 +4492,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
? new LinearElementEditor(
|
||||
elementsWithinSelection[0],
|
||||
this.scene,
|
||||
this.state,
|
||||
)
|
||||
: null,
|
||||
},
|
||||
@@ -4751,6 +4757,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
selectedLinearElement: new LinearElementEditor(
|
||||
draggingElement,
|
||||
this.scene,
|
||||
this.state,
|
||||
),
|
||||
}));
|
||||
} else {
|
||||
@@ -4818,6 +4825,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
selectedLinearElement: new LinearElementEditor(
|
||||
hitElement,
|
||||
this.scene,
|
||||
this.state,
|
||||
),
|
||||
});
|
||||
}
|
||||
@@ -4920,6 +4928,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
? new LinearElementEditor(
|
||||
newSelectedElements[0],
|
||||
this.scene,
|
||||
this.state,
|
||||
)
|
||||
: prevState.selectedLinearElement,
|
||||
},
|
||||
@@ -4948,7 +4957,11 @@ class App extends React.Component<AppProps, AppState> {
|
||||
// Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.
|
||||
// Future we should update the API to take care of setting the correct `hoverPointIndex` when initialized
|
||||
prevState.selectedLinearElement?.elementId !== hitElement.id
|
||||
? new LinearElementEditor(hitElement, this.scene)
|
||||
? new LinearElementEditor(
|
||||
hitElement,
|
||||
this.scene,
|
||||
this.state,
|
||||
)
|
||||
: prevState.selectedLinearElement,
|
||||
},
|
||||
this.scene.getNonDeletedElements(),
|
||||
@@ -5708,7 +5721,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
...this.state,
|
||||
selectedElementIds: { [element.id]: true },
|
||||
selectedLinearElement: isLinearElement(element)
|
||||
? new LinearElementEditor(element, this.scene)
|
||||
? new LinearElementEditor(element, this.scene, this.state)
|
||||
: null,
|
||||
},
|
||||
this.scene.getNonDeletedElements(),
|
||||
|
||||
@@ -40,6 +40,11 @@ const editorMidPointsCache: {
|
||||
zoom: number | null;
|
||||
} = { version: null, points: [], zoom: null };
|
||||
|
||||
const visiblePointIndexesCache: {
|
||||
points: number[];
|
||||
zoom: number | null;
|
||||
isEditingLinearElement: boolean;
|
||||
} = { points: [], zoom: null, isEditingLinearElement: false };
|
||||
export class LinearElementEditor {
|
||||
public readonly elementId: ExcalidrawElement["id"] & {
|
||||
_brand: "excalidrawLinearElementId";
|
||||
@@ -65,7 +70,12 @@ export class LinearElementEditor {
|
||||
public readonly hoverPointIndex: number;
|
||||
public readonly segmentMidPointHoveredCoords: Point | null;
|
||||
|
||||
constructor(element: NonDeleted<ExcalidrawLinearElement>, scene: Scene) {
|
||||
constructor(
|
||||
element: NonDeleted<ExcalidrawLinearElement>,
|
||||
scene: Scene,
|
||||
appState: AppState,
|
||||
editingLinearElement = false,
|
||||
) {
|
||||
this.elementId = element.id as string & {
|
||||
_brand: "excalidrawLinearElementId";
|
||||
};
|
||||
@@ -433,7 +443,7 @@ export class LinearElementEditor {
|
||||
return null;
|
||||
}
|
||||
const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(
|
||||
element,
|
||||
appState.selectedLinearElement,
|
||||
appState.zoom,
|
||||
scenePointer.x,
|
||||
scenePointer.y,
|
||||
@@ -560,6 +570,59 @@ export class LinearElementEditor {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static getVisiblePointIndexes(
|
||||
element: NonDeleted<ExcalidrawLinearElement>,
|
||||
appState: AppState,
|
||||
): typeof visiblePointIndexesCache["points"] {
|
||||
const isEditingLinearElement = !!appState.editingLinearElement;
|
||||
if (appState.editingLinearElement) {
|
||||
// So that when we exit the editor the points are calculated again
|
||||
visiblePointIndexesCache.isEditingLinearElement = true;
|
||||
return element.points.map((_, index) => index);
|
||||
}
|
||||
|
||||
if (
|
||||
visiblePointIndexesCache.points &&
|
||||
visiblePointIndexesCache.zoom === appState.zoom.value &&
|
||||
isEditingLinearElement === visiblePointIndexesCache.isEditingLinearElement
|
||||
) {
|
||||
return visiblePointIndexesCache.points;
|
||||
}
|
||||
|
||||
LinearElementEditor.updateVisiblePointIndexesCache(element, appState);
|
||||
return visiblePointIndexesCache.points;
|
||||
}
|
||||
|
||||
static updateVisiblePointIndexesCache(
|
||||
element: NonDeleted<ExcalidrawLinearElement>,
|
||||
appState: AppState,
|
||||
) {
|
||||
const visiblePointIndexes: number[] = [];
|
||||
let previousPoint: Point | null = null;
|
||||
element.points.forEach((point, index) => {
|
||||
let distance = Infinity;
|
||||
if (previousPoint) {
|
||||
distance =
|
||||
distance2d(point[0], point[1], previousPoint[0], previousPoint[1]) *
|
||||
appState.zoom.value;
|
||||
}
|
||||
const isExtremePoint = index === 0 || index === element.points.length - 1;
|
||||
const threshold = 2 * LinearElementEditor.POINT_HANDLE_SIZE;
|
||||
if (isExtremePoint || distance >= threshold) {
|
||||
// hide n-1 point if distance is less than threshold
|
||||
if (isExtremePoint && distance < threshold) {
|
||||
visiblePointIndexes.pop();
|
||||
}
|
||||
visiblePointIndexes.push(index);
|
||||
previousPoint = point;
|
||||
}
|
||||
});
|
||||
visiblePointIndexesCache.points = visiblePointIndexes;
|
||||
visiblePointIndexesCache.zoom = appState.zoom.value;
|
||||
visiblePointIndexesCache.isEditingLinearElement =
|
||||
!!appState.editingLinearElement;
|
||||
}
|
||||
|
||||
static handlePointerDown(
|
||||
event: React.PointerEvent<HTMLCanvasElement>,
|
||||
appState: AppState,
|
||||
@@ -617,15 +680,6 @@ export class LinearElementEditor {
|
||||
|
||||
ret.didAddPoint = true;
|
||||
ret.isMidPoint = true;
|
||||
ret.linearElementEditor = {
|
||||
...linearElementEditor,
|
||||
selectedPointsIndices: element.points[1],
|
||||
pointerDownState: {
|
||||
prevSelectedPointsIndices: linearElementEditor.selectedPointsIndices,
|
||||
lastClickedPoint: -1,
|
||||
},
|
||||
lastUncommittedPoint: null,
|
||||
};
|
||||
}
|
||||
if (event.altKey && appState.editingLinearElement) {
|
||||
if (linearElementEditor.lastUncommittedPoint == null) {
|
||||
@@ -662,7 +716,7 @@ export class LinearElementEditor {
|
||||
}
|
||||
|
||||
const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(
|
||||
element,
|
||||
appState.selectedLinearElement,
|
||||
appState.zoom,
|
||||
scenePointer.x,
|
||||
scenePointer.y,
|
||||
@@ -725,7 +779,11 @@ export class LinearElementEditor {
|
||||
}
|
||||
: { x: 0, y: 0 },
|
||||
};
|
||||
|
||||
if (ret.didAddPoint) {
|
||||
ret.linearElementEditor = {
|
||||
...ret.linearElementEditor,
|
||||
};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -873,25 +931,37 @@ export class LinearElementEditor {
|
||||
}
|
||||
|
||||
static getPointIndexUnderCursor(
|
||||
element: NonDeleted<ExcalidrawLinearElement>,
|
||||
linearElementEditor: LinearElementEditor | null,
|
||||
zoom: AppState["zoom"],
|
||||
x: number,
|
||||
y: number,
|
||||
) {
|
||||
if (!linearElementEditor) {
|
||||
return -1;
|
||||
}
|
||||
const element = LinearElementEditor.getElement(
|
||||
linearElementEditor.elementId,
|
||||
);
|
||||
if (!element) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const pointHandles =
|
||||
LinearElementEditor.getPointsGlobalCoordinates(element);
|
||||
let idx = pointHandles.length;
|
||||
let counter = visiblePointIndexesCache.points.length;
|
||||
|
||||
// loop from right to left because points on the right are rendered over
|
||||
// points on the left, thus should take precedence when clicking, if they
|
||||
// overlap
|
||||
while (--idx > -1) {
|
||||
const point = pointHandles[idx];
|
||||
while (--counter >= 0) {
|
||||
const index = visiblePointIndexesCache.points[counter];
|
||||
const point = pointHandles[index];
|
||||
if (
|
||||
distance2d(x, y, point[0], point[1]) * zoom.value <
|
||||
// +1px to account for outline stroke
|
||||
LinearElementEditor.POINT_HANDLE_SIZE + 1
|
||||
) {
|
||||
return idx;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
@@ -21,12 +21,7 @@ import { AppState } from "../types";
|
||||
import { getElementAbsoluteCoords } from ".";
|
||||
import { adjustXYWithRotation } from "../math";
|
||||
import { getResizedElementAbsoluteCoords } from "./bounds";
|
||||
import {
|
||||
getContainerElement,
|
||||
getContainerDims,
|
||||
measureText,
|
||||
wrapText,
|
||||
} from "./textElement";
|
||||
import { getContainerElement, measureText, wrapText } from "./textElement";
|
||||
import { BOUND_TEXT_PADDING, VERTICAL_ALIGN } from "../constants";
|
||||
|
||||
type ElementConstructorOpts = MarkOptional<
|
||||
@@ -169,9 +164,7 @@ const getAdjustedDimensions = (
|
||||
let maxWidth = null;
|
||||
const container = getContainerElement(element);
|
||||
if (container) {
|
||||
const containerDims = getContainerDims(container);
|
||||
|
||||
maxWidth = containerDims.width - BOUND_TEXT_PADDING * 2;
|
||||
maxWidth = container.width - BOUND_TEXT_PADDING * 2;
|
||||
}
|
||||
const {
|
||||
width: nextWidth,
|
||||
@@ -231,21 +224,16 @@ const getAdjustedDimensions = (
|
||||
// make sure container dimensions are set properly when
|
||||
// text editor overflows beyond viewport dimensions
|
||||
if (container) {
|
||||
const containerDims = getContainerDims(container);
|
||||
let { width, height } = containerDims;
|
||||
let height = container.height;
|
||||
let width = container.width;
|
||||
if (nextHeight > height - BOUND_TEXT_PADDING * 2) {
|
||||
height = nextHeight + BOUND_TEXT_PADDING * 2;
|
||||
}
|
||||
if (nextWidth > width - BOUND_TEXT_PADDING * 2) {
|
||||
width = nextWidth + BOUND_TEXT_PADDING * 2;
|
||||
}
|
||||
if (height !== containerDims.height || width !== containerDims.height) {
|
||||
const diffHeight = height - containerDims.height;
|
||||
const diffWidth = width - containerDims.width;
|
||||
mutateElement(container, {
|
||||
height: container.height + diffHeight,
|
||||
width: container.width + diffWidth,
|
||||
});
|
||||
if (height !== container.height || width !== container.width) {
|
||||
mutateElement(container, { height, width });
|
||||
}
|
||||
}
|
||||
return {
|
||||
@@ -271,11 +259,7 @@ export const updateTextElement = (
|
||||
): ExcalidrawTextElement => {
|
||||
const container = getContainerElement(element);
|
||||
if (container) {
|
||||
text = wrapText(
|
||||
text,
|
||||
getFontString(element),
|
||||
getContainerDims(container).width,
|
||||
);
|
||||
text = wrapText(text, getFontString(element), container.width);
|
||||
}
|
||||
const dimensions = getAdjustedDimensions(element, text);
|
||||
return newElementWith(element, {
|
||||
|
||||
+12
-47
@@ -16,20 +16,16 @@ export const redrawTextBoundingBox = (
|
||||
element: ExcalidrawTextElement,
|
||||
container: ExcalidrawElement | null,
|
||||
) => {
|
||||
let containerDims;
|
||||
if (container) {
|
||||
containerDims = getContainerDims(container);
|
||||
}
|
||||
const maxWidth = containerDims
|
||||
? containerDims.width - BOUND_TEXT_PADDING * 2
|
||||
const maxWidth = container
|
||||
? container.width - BOUND_TEXT_PADDING * 2
|
||||
: undefined;
|
||||
let text = element.text;
|
||||
|
||||
if (containerDims) {
|
||||
if (container) {
|
||||
text = wrapText(
|
||||
element.originalText,
|
||||
getFontString(element),
|
||||
containerDims.width,
|
||||
container.width,
|
||||
);
|
||||
}
|
||||
const metrics = measureText(
|
||||
@@ -41,24 +37,18 @@ export const redrawTextBoundingBox = (
|
||||
let coordX = element.x;
|
||||
// Resize container and vertically center align the text
|
||||
if (container) {
|
||||
const containerDims = getContainerDims(container);
|
||||
const containerCoords = getBoundTextContainerCoords(container);
|
||||
let nextHeight = containerDims.height;
|
||||
coordX = containerCoords.x + BOUND_TEXT_PADDING;
|
||||
let nextHeight = container.height;
|
||||
coordX = container.x + BOUND_TEXT_PADDING;
|
||||
if (element.verticalAlign === VERTICAL_ALIGN.TOP) {
|
||||
coordY = containerCoords.y + BOUND_TEXT_PADDING;
|
||||
coordY = container.y + BOUND_TEXT_PADDING;
|
||||
} else if (element.verticalAlign === VERTICAL_ALIGN.BOTTOM) {
|
||||
coordY =
|
||||
containerCoords.y +
|
||||
containerDims.height -
|
||||
metrics.height -
|
||||
BOUND_TEXT_PADDING;
|
||||
container.y + container.height - metrics.height - BOUND_TEXT_PADDING;
|
||||
} else {
|
||||
coordY =
|
||||
containerCoords.y + containerDims.height / 2 - metrics.height / 2;
|
||||
if (metrics.height > containerDims.height - BOUND_TEXT_PADDING * 2) {
|
||||
coordY = container.y + container.height / 2 - metrics.height / 2;
|
||||
if (metrics.height > container.height - BOUND_TEXT_PADDING * 2) {
|
||||
nextHeight = metrics.height + BOUND_TEXT_PADDING * 2;
|
||||
coordY = containerCoords.y + nextHeight / 2 - metrics.height / 2;
|
||||
coordY = container.y + nextHeight / 2 - metrics.height / 2;
|
||||
}
|
||||
}
|
||||
mutateElement(container, { height: nextHeight });
|
||||
@@ -131,7 +121,7 @@ export const handleBindTextResize = (
|
||||
text = wrapText(
|
||||
textElement.originalText,
|
||||
getFontString(textElement),
|
||||
getContainerDims(element).width,
|
||||
element.width,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -484,28 +474,3 @@ export const getContainerElement = (
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getContainerDims = (element: ExcalidrawElement) => {
|
||||
if (element.type === "ellipse") {
|
||||
return {
|
||||
width: Math.round((element.width / 2) * Math.sqrt(2)),
|
||||
height: Math.round((element.height / 2) * Math.sqrt(2)),
|
||||
};
|
||||
}
|
||||
return { width: element.width, height: element.height };
|
||||
};
|
||||
|
||||
export const getBoundTextContainerCoords = (container: ExcalidrawElement) => {
|
||||
if (container.type === "ellipse") {
|
||||
const offsetX = (container.width / 2) * (1 - Math.sqrt(2) / 2);
|
||||
const offsetY = (container.height / 2) * (1 - Math.sqrt(2) / 2);
|
||||
return {
|
||||
x: container.x + offsetX,
|
||||
y: container.y + offsetY,
|
||||
};
|
||||
}
|
||||
return {
|
||||
x: container.x,
|
||||
y: container.y,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,9 +19,7 @@ import {
|
||||
getApproxLineHeight,
|
||||
getBoundTextElementId,
|
||||
getContainerElement,
|
||||
getContainerDims,
|
||||
wrapText,
|
||||
getBoundTextContainerCoords,
|
||||
} from "./textElement";
|
||||
import {
|
||||
actionDecreaseFontSize,
|
||||
@@ -128,28 +126,26 @@ export const textWysiwyg = ({
|
||||
updatedElement,
|
||||
editable,
|
||||
);
|
||||
const containerDims = getContainerDims(container);
|
||||
// using editor.style.height to get the accurate height of text editor
|
||||
const editorHeight = Number(editable.style.height.slice(0, -2));
|
||||
if (editorHeight > 0) {
|
||||
height = editorHeight;
|
||||
}
|
||||
if (propertiesUpdated) {
|
||||
originalContainerHeight = containerDims.height;
|
||||
originalContainerHeight = container.height;
|
||||
|
||||
// update height of the editor after properties updated
|
||||
height = updatedElement.height;
|
||||
}
|
||||
if (!originalContainerHeight) {
|
||||
originalContainerHeight = containerDims.height;
|
||||
originalContainerHeight = container.height;
|
||||
}
|
||||
maxWidth = containerDims.width - BOUND_TEXT_PADDING * 2;
|
||||
maxHeight = containerDims.height - BOUND_TEXT_PADDING * 2;
|
||||
maxWidth = container.width - BOUND_TEXT_PADDING * 2;
|
||||
maxHeight = container.height - BOUND_TEXT_PADDING * 2;
|
||||
width = maxWidth;
|
||||
const boundTextCoords = getBoundTextContainerCoords(container);
|
||||
// The coordinates of text box set a distance of
|
||||
// 5px to preserve padding
|
||||
coordX = boundTextCoords.x + BOUND_TEXT_PADDING;
|
||||
coordX = container.x + BOUND_TEXT_PADDING;
|
||||
// autogrow container height if text exceeds
|
||||
if (height > maxHeight) {
|
||||
const diff = Math.min(height - maxHeight, approxLineHeight);
|
||||
@@ -158,7 +154,7 @@ export const textWysiwyg = ({
|
||||
} else if (
|
||||
// autoshrink container height until original container height
|
||||
// is reached when text is removed
|
||||
containerDims.height > originalContainerHeight &&
|
||||
container.height > originalContainerHeight &&
|
||||
height < maxHeight
|
||||
) {
|
||||
const diff = Math.min(maxHeight - height, approxLineHeight);
|
||||
@@ -169,14 +165,11 @@ export const textWysiwyg = ({
|
||||
else {
|
||||
// vertically center align the text
|
||||
if (verticalAlign === VERTICAL_ALIGN.MIDDLE) {
|
||||
coordY = boundTextCoords.y + containerDims.height / 2 - height / 2;
|
||||
coordY = container.y + container.height / 2 - height / 2;
|
||||
}
|
||||
if (verticalAlign === VERTICAL_ALIGN.BOTTOM) {
|
||||
coordY =
|
||||
boundTextCoords.y +
|
||||
containerDims.height -
|
||||
height -
|
||||
BOUND_TEXT_PADDING;
|
||||
container.y + container.height - height - BOUND_TEXT_PADDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,7 +303,7 @@ export const textWysiwyg = ({
|
||||
const actualLineCount = wrapText(
|
||||
editable.value,
|
||||
font,
|
||||
getContainerDims(container!).width,
|
||||
container!.width,
|
||||
).split("\n").length;
|
||||
// This is browser behaviour when setting height to "auto"
|
||||
// It sets the height needed for 2 lines even if actual
|
||||
|
||||
+29
-16
@@ -159,13 +159,15 @@ const strokeGrid = (
|
||||
|
||||
const renderSingleLinearPoint = (
|
||||
context: CanvasRenderingContext2D,
|
||||
appState: AppState,
|
||||
renderConfig: RenderConfig,
|
||||
point: Point,
|
||||
radius: number,
|
||||
isSelected: boolean,
|
||||
isPhantomPoint = false,
|
||||
) => {
|
||||
if (!point) {
|
||||
return;
|
||||
}
|
||||
context.strokeStyle = "#5e5ad8";
|
||||
context.setLineDash([]);
|
||||
context.fillStyle = "rgba(255, 255, 255, 0.9)";
|
||||
@@ -202,18 +204,16 @@ const renderLinearPointHandles = (
|
||||
const radius = appState.editingLinearElement
|
||||
? POINT_HANDLE_SIZE
|
||||
: POINT_HANDLE_SIZE / 2;
|
||||
points.forEach((point, idx) => {
|
||||
const isSelected =
|
||||
!!appState.editingLinearElement?.selectedPointsIndices?.includes(idx);
|
||||
|
||||
renderSingleLinearPoint(
|
||||
context,
|
||||
appState,
|
||||
renderConfig,
|
||||
point,
|
||||
radius,
|
||||
isSelected,
|
||||
);
|
||||
const visiblePointIndexes = LinearElementEditor.getVisiblePointIndexes(
|
||||
element,
|
||||
appState,
|
||||
);
|
||||
visiblePointIndexes.forEach((index) => {
|
||||
const isSelected =
|
||||
!!appState.editingLinearElement?.selectedPointsIndices?.includes(index);
|
||||
const point = points[index];
|
||||
renderSingleLinearPoint(context, renderConfig, point, radius, isSelected);
|
||||
});
|
||||
|
||||
//Rendering segment mid points
|
||||
@@ -237,7 +237,6 @@ const renderLinearPointHandles = (
|
||||
if (appState.editingLinearElement) {
|
||||
renderSingleLinearPoint(
|
||||
context,
|
||||
appState,
|
||||
renderConfig,
|
||||
segmentMidPoint,
|
||||
radius,
|
||||
@@ -248,7 +247,7 @@ const renderLinearPointHandles = (
|
||||
highlightPoint(segmentMidPoint, context, renderConfig);
|
||||
renderSingleLinearPoint(
|
||||
context,
|
||||
appState,
|
||||
|
||||
renderConfig,
|
||||
segmentMidPoint,
|
||||
radius,
|
||||
@@ -258,7 +257,6 @@ const renderLinearPointHandles = (
|
||||
} else if (appState.editingLinearElement || points.length === 2) {
|
||||
renderSingleLinearPoint(
|
||||
context,
|
||||
appState,
|
||||
renderConfig,
|
||||
segmentMidPoint,
|
||||
POINT_HANDLE_SIZE / 2,
|
||||
@@ -450,7 +448,22 @@ export const _renderScene = ({
|
||||
appState.selectedLinearElement &&
|
||||
appState.selectedLinearElement.hoverPointIndex >= 0
|
||||
) {
|
||||
renderLinearElementPointHighlight(context, appState, renderConfig);
|
||||
const element = LinearElementEditor.getElement(
|
||||
appState.selectedLinearElement.elementId,
|
||||
);
|
||||
if (element) {
|
||||
const visiblePointIndexes = LinearElementEditor.getVisiblePointIndexes(
|
||||
element,
|
||||
appState,
|
||||
);
|
||||
if (
|
||||
visiblePointIndexes.includes(
|
||||
appState.selectedLinearElement.hoverPointIndex,
|
||||
)
|
||||
) {
|
||||
renderLinearElementPointHighlight(context, appState, renderConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Paint selected elements
|
||||
if (
|
||||
|
||||
@@ -10993,6 +10993,9 @@ Object {
|
||||
"segmentMidPointHoveredCoords": null,
|
||||
"selectedPointsIndices": null,
|
||||
"startBindingElement": "keep",
|
||||
"visiblePointIndexes": Array [
|
||||
1,
|
||||
],
|
||||
},
|
||||
"selectionElement": null,
|
||||
"shouldCacheIgnoreZoom": false,
|
||||
@@ -11219,6 +11222,9 @@ Object {
|
||||
"segmentMidPointHoveredCoords": null,
|
||||
"selectedPointsIndices": null,
|
||||
"startBindingElement": "keep",
|
||||
"visiblePointIndexes": Array [
|
||||
1,
|
||||
],
|
||||
},
|
||||
"selectionElement": null,
|
||||
"shouldCacheIgnoreZoom": false,
|
||||
@@ -11672,6 +11678,9 @@ Object {
|
||||
"segmentMidPointHoveredCoords": null,
|
||||
"selectedPointsIndices": null,
|
||||
"startBindingElement": "keep",
|
||||
"visiblePointIndexes": Array [
|
||||
1,
|
||||
],
|
||||
},
|
||||
"selectionElement": null,
|
||||
"shouldCacheIgnoreZoom": false,
|
||||
@@ -12077,6 +12086,9 @@ Object {
|
||||
"segmentMidPointHoveredCoords": null,
|
||||
"selectedPointsIndices": null,
|
||||
"startBindingElement": "keep",
|
||||
"visiblePointIndexes": Array [
|
||||
1,
|
||||
],
|
||||
},
|
||||
"selectionElement": null,
|
||||
"shouldCacheIgnoreZoom": false,
|
||||
|
||||
Reference in New Issue
Block a user