mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Add cubic bezier curve visual debug
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
77ea537c69
commit
028c397c0a
4 changed files with 85 additions and 8 deletions
|
@ -12,9 +12,10 @@ import {
|
||||||
TrashIcon,
|
TrashIcon,
|
||||||
} from "../../packages/excalidraw/components/icons";
|
} from "../../packages/excalidraw/components/icons";
|
||||||
import { STORAGE_KEYS } from "../app_constants";
|
import { STORAGE_KEYS } from "../app_constants";
|
||||||
import type { Arc } from "../../packages/math";
|
import type { Arc, CubicBezier } from "../../packages/math";
|
||||||
import {
|
import {
|
||||||
isArc,
|
isArc,
|
||||||
|
isBezier,
|
||||||
isSegment,
|
isSegment,
|
||||||
type GlobalPoint,
|
type GlobalPoint,
|
||||||
type Segment,
|
type Segment,
|
||||||
|
@ -35,6 +36,28 @@ const renderLine = (
|
||||||
context.restore();
|
context.restore();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const renderCubicBezier = (
|
||||||
|
context: CanvasRenderingContext2D,
|
||||||
|
zoom: number,
|
||||||
|
{ start, control1, control2, end }: CubicBezier<GlobalPoint>,
|
||||||
|
color: string,
|
||||||
|
) => {
|
||||||
|
context.save();
|
||||||
|
context.strokeStyle = color;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(start[0] * zoom, start[1] * zoom);
|
||||||
|
context.bezierCurveTo(
|
||||||
|
control1[0] * zoom,
|
||||||
|
control1[1] * zoom,
|
||||||
|
control2[0] * zoom,
|
||||||
|
control2[1] * zoom,
|
||||||
|
end[0] * zoom,
|
||||||
|
end[1] * zoom,
|
||||||
|
);
|
||||||
|
context.stroke();
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
|
||||||
const renderArc = (
|
const renderArc = (
|
||||||
context: CanvasRenderingContext2D,
|
context: CanvasRenderingContext2D,
|
||||||
zoom: number,
|
zoom: number,
|
||||||
|
@ -90,6 +113,16 @@ const render = (
|
||||||
el.color,
|
el.color,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case isBezier(el.data):
|
||||||
|
renderCubicBezier(
|
||||||
|
context,
|
||||||
|
appState.zoom.value,
|
||||||
|
el.data as CubicBezier<GlobalPoint>,
|
||||||
|
el.color,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error("Unknown element type");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { Arc, Segment } from "../math";
|
import type { Arc, CubicBezier, Segment } from "../math";
|
||||||
import { isSegment, segment, pointFrom, type GlobalPoint } from "../math";
|
import { isSegment, segment, pointFrom, type GlobalPoint } from "../math";
|
||||||
import { isBounds } from "./element/typeChecks";
|
import { isBounds } from "./element/typeChecks";
|
||||||
import type { Bounds } from "./element/types";
|
import type { Bounds } from "./element/types";
|
||||||
|
@ -15,10 +15,24 @@ declare global {
|
||||||
|
|
||||||
export type DebugElement = {
|
export type DebugElement = {
|
||||||
color: string;
|
color: string;
|
||||||
data: Segment<GlobalPoint> | Arc<GlobalPoint>;
|
data: Segment<GlobalPoint> | Arc<GlobalPoint> | CubicBezier<GlobalPoint>;
|
||||||
permanent: boolean;
|
permanent: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const debugDrawCubicBezier = (
|
||||||
|
c: CubicBezier<GlobalPoint>,
|
||||||
|
opts?: {
|
||||||
|
color?: string;
|
||||||
|
permanent?: boolean;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
addToCurrentFrame({
|
||||||
|
color: opts?.color ?? "purple",
|
||||||
|
permanent: !!opts?.permanent,
|
||||||
|
data: c,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const debugDrawArc = (
|
export const debugDrawArc = (
|
||||||
a: Arc<GlobalPoint>,
|
a: Arc<GlobalPoint>,
|
||||||
opts?: {
|
opts?: {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { pointFrom, pointRotateRads } from "./point";
|
import { isPoint, pointFrom, pointRotateRads } from "./point";
|
||||||
import type { Curve, GenericPoint, Radians } from "./types";
|
import type { CubicBezier, Curve, GenericPoint, Radians } from "./types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -221,3 +221,20 @@ const findClosestParameter = <Point extends GenericPoint>(
|
||||||
|
|
||||||
return closestT;
|
return closestT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isBezier = <Point extends GenericPoint>(
|
||||||
|
c: unknown,
|
||||||
|
): c is CubicBezier<Point> => {
|
||||||
|
return (
|
||||||
|
c != null &&
|
||||||
|
typeof c === "object" &&
|
||||||
|
Object.hasOwn(c, "start") &&
|
||||||
|
Object.hasOwn(c, "end") &&
|
||||||
|
Object.hasOwn(c, "control1") &&
|
||||||
|
Object.hasOwn(c, "control2") &&
|
||||||
|
isPoint((c as CubicBezier<Point>).start) &&
|
||||||
|
isPoint((c as CubicBezier<Point>).end) &&
|
||||||
|
isPoint((c as CubicBezier<Point>).control1) &&
|
||||||
|
isPoint((c as CubicBezier<Point>).control2)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -132,9 +132,11 @@ export type Extent = {
|
||||||
_brand: "excalimath_extent";
|
_brand: "excalimath_extent";
|
||||||
};
|
};
|
||||||
|
|
||||||
// an ellipse is specified by its center, angle, and its major and minor axes
|
/**
|
||||||
// but for the sake of simplicity, we've used halfWidth and halfHeight instead
|
An ellipse is specified by its center, angle, and its major and minor axes
|
||||||
// in replace of semi major and semi minor axes
|
but for the sake of simplicity, we've used halfWidth and halfHeight instead
|
||||||
|
in replace of semi major and semi minor axes
|
||||||
|
*/
|
||||||
export type Ellipse<Point extends GenericPoint> = {
|
export type Ellipse<Point extends GenericPoint> = {
|
||||||
center: Point;
|
center: Point;
|
||||||
halfWidth: number;
|
halfWidth: number;
|
||||||
|
@ -142,3 +144,14 @@ export type Ellipse<Point extends GenericPoint> = {
|
||||||
} & {
|
} & {
|
||||||
_brand: "excalimath_ellipse";
|
_brand: "excalimath_ellipse";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a cubic bezier with 2 control points on the point space of your
|
||||||
|
* choosing.
|
||||||
|
*/
|
||||||
|
export type CubicBezier<P extends GenericPoint> = {
|
||||||
|
start: P;
|
||||||
|
end: P;
|
||||||
|
control1: P;
|
||||||
|
control2: P;
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue