mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-18 11:44:23 +01:00
fix: Arrow with angle jittering
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
@@ -1569,7 +1569,9 @@ export class LinearElementEditor {
|
|||||||
const updatedOriginPoint =
|
const updatedOriginPoint =
|
||||||
pointUpdates.get(0)?.point ?? pointFrom<LocalPoint>(0, 0);
|
pointUpdates.get(0)?.point ?? pointFrom<LocalPoint>(0, 0);
|
||||||
|
|
||||||
const [offsetX, offsetY] = updatedOriginPoint;
|
// Handle non-normalized points
|
||||||
|
const offsetX = element.points[0][0] - updatedOriginPoint[0];
|
||||||
|
const offsetY = element.points[0][1] - updatedOriginPoint[1];
|
||||||
|
|
||||||
const nextPoints = isElbowArrow(element)
|
const nextPoints = isElbowArrow(element)
|
||||||
? [
|
? [
|
||||||
@@ -1586,7 +1588,14 @@ export class LinearElementEditor {
|
|||||||
idx !== points.length - 1 &&
|
idx !== points.length - 1 &&
|
||||||
!pointUpdates.has(idx)
|
!pointUpdates.has(idx)
|
||||||
) {
|
) {
|
||||||
return pointFrom<LocalPoint>(current[0], current[1]);
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we're subtracting the offset coming from the first point
|
||||||
|
// from all other points, we need to skip the first point here to avoid
|
||||||
|
// double-subtracting the offset.
|
||||||
|
if (idx === 0) {
|
||||||
|
return pointFrom<LocalPoint>(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pointFrom<LocalPoint>(
|
return pointFrom<LocalPoint>(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import throttle from "lodash.throttle";
|
|||||||
import { useEffect, useMemo, useState, memo } from "react";
|
import { useEffect, useMemo, useState, memo } from "react";
|
||||||
|
|
||||||
import { STATS_PANELS } from "@excalidraw/common";
|
import { STATS_PANELS } from "@excalidraw/common";
|
||||||
import { getCommonBounds, isBindingElement } from "@excalidraw/element";
|
import { getCommonBounds } from "@excalidraw/element";
|
||||||
import { getUncroppedWidthAndHeight } from "@excalidraw/element";
|
import { getUncroppedWidthAndHeight } from "@excalidraw/element";
|
||||||
import { isImageElement } from "@excalidraw/element";
|
import { isImageElement } from "@excalidraw/element";
|
||||||
|
|
||||||
@@ -333,16 +333,14 @@ export const StatsInner = memo(
|
|||||||
appState={appState}
|
appState={appState}
|
||||||
/>
|
/>
|
||||||
</StatsRow>
|
</StatsRow>
|
||||||
{!isBindingElement(singleElement) && (
|
<StatsRow>
|
||||||
<StatsRow>
|
<Angle
|
||||||
<Angle
|
property="angle"
|
||||||
property="angle"
|
element={singleElement}
|
||||||
element={singleElement}
|
scene={scene}
|
||||||
scene={scene}
|
appState={appState}
|
||||||
appState={appState}
|
/>
|
||||||
/>
|
</StatsRow>
|
||||||
</StatsRow>
|
|
||||||
)}
|
|
||||||
<StatsRow>
|
<StatsRow>
|
||||||
<FontSize
|
<FontSize
|
||||||
property="fontSize"
|
property="fontSize"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isFiniteNumber, pointFrom, pointRotateRads } from "@excalidraw/math";
|
import { isFiniteNumber, pointFrom } from "@excalidraw/math";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_FONT_FAMILY,
|
DEFAULT_FONT_FAMILY,
|
||||||
@@ -20,7 +20,6 @@ import {
|
|||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
import {
|
import {
|
||||||
calculateFixedPointForNonElbowArrowBinding,
|
calculateFixedPointForNonElbowArrowBinding,
|
||||||
elementCenterPoint,
|
|
||||||
getNonDeletedElements,
|
getNonDeletedElements,
|
||||||
isPointInElement,
|
isPointInElement,
|
||||||
isValidPolygon,
|
isValidPolygon,
|
||||||
@@ -393,35 +392,14 @@ export const restoreElement = (
|
|||||||
...getSizeFromPoints(points),
|
...getSizeFromPoints(points),
|
||||||
});
|
});
|
||||||
case "arrow": {
|
case "arrow": {
|
||||||
const {
|
const { startArrowhead = null, endArrowhead = "arrow" } = element;
|
||||||
startArrowhead = null,
|
|
||||||
endArrowhead = "arrow",
|
|
||||||
angle = 0,
|
|
||||||
} = element;
|
|
||||||
const x: number | undefined = element.x;
|
const x: number | undefined = element.x;
|
||||||
const y: number | undefined = element.y;
|
const y: number | undefined = element.y;
|
||||||
let points: readonly LocalPoint[] | undefined = // migrate old arrow model to new one
|
const points: readonly LocalPoint[] | undefined = // migrate old arrow model to new one
|
||||||
!Array.isArray(element.points) || element.points.length < 2
|
!Array.isArray(element.points) || element.points.length < 2
|
||||||
? [pointFrom(0, 0), pointFrom(element.width, element.height)]
|
? [pointFrom(0, 0), pointFrom(element.width, element.height)]
|
||||||
: element.points;
|
: element.points;
|
||||||
|
|
||||||
if (angle !== 0) {
|
|
||||||
points = LinearElementEditor.getPointsGlobalCoordinates(
|
|
||||||
element,
|
|
||||||
elementsMap,
|
|
||||||
).map((point) =>
|
|
||||||
LinearElementEditor.pointFromAbsoluteCoords(
|
|
||||||
element as ExcalidrawArrowElement,
|
|
||||||
pointRotateRads(
|
|
||||||
point,
|
|
||||||
elementCenterPoint(element, elementsMap),
|
|
||||||
angle,
|
|
||||||
),
|
|
||||||
elementsMap,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const base = {
|
const base = {
|
||||||
type: element.type,
|
type: element.type,
|
||||||
startBinding: repairBinding(
|
startBinding: repairBinding(
|
||||||
@@ -443,7 +421,6 @@ export const restoreElement = (
|
|||||||
y,
|
y,
|
||||||
elbowed: (element as ExcalidrawArrowElement).elbowed,
|
elbowed: (element as ExcalidrawArrowElement).elbowed,
|
||||||
...getSizeFromPoints(points),
|
...getSizeFromPoints(points),
|
||||||
angle: 0 as Radians,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Separate arrow from linear element
|
// TODO: Separate arrow from linear element
|
||||||
|
|||||||
Reference in New Issue
Block a user