mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-25 16:38:11 +08:00
Implement functions to create a Bezier that goes through 3 specified points (#687)
* Implement quadratic and cubic from points * Catch edge cases and integrate `t` slider * Add 2 sliders for cubic * Create utils file for bezier-rs and address other PR comments * Rename variable and remove unnecessary ids * Update rustdoc comments and rename variables * Remove unnecessary file and refactor options for drawing beziers * Address PR comments * Update quadratic_through_points description * Add wasm-pack to dependencies and change from spaces to tabs for indents * Change strut to midpoint_separation, adjust sliders and section name * Minor refactor
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Point, WasmBezierInstance } from "@/utils/types";
|
||||
import { BezierStyleConfig, Point, WasmBezierInstance } from "@/utils/types";
|
||||
|
||||
const HANDLE_RADIUS_FACTOR = 2 / 3;
|
||||
const DEFAULT_ENDPOINT_RADIUS = 5;
|
||||
@@ -16,7 +16,9 @@ export const COLORS = {
|
||||
},
|
||||
};
|
||||
|
||||
export const getPointSizeByIndex = (index: number, numPoints: number, radius = DEFAULT_ENDPOINT_RADIUS): number => (index === 0 || index === numPoints - 1 ? radius : radius * HANDLE_RADIUS_FACTOR);
|
||||
export const isIndexFirstOrLast = (index: number, arrayLength: number): boolean => index === 0 || index === arrayLength - 1;
|
||||
|
||||
export const getPointSizeByIndex = (index: number, numPoints: number, radius = DEFAULT_ENDPOINT_RADIUS): number => (isIndexFirstOrLast(index, numPoints) ? radius : radius * HANDLE_RADIUS_FACTOR);
|
||||
|
||||
export const getContextFromCanvas = (canvas: HTMLCanvasElement): CanvasRenderingContext2D => {
|
||||
const ctx = canvas.getContext("2d");
|
||||
@@ -57,12 +59,28 @@ export const drawText = (ctx: CanvasRenderingContext2D, text: string, x: number,
|
||||
ctx.fillText(text, x, y);
|
||||
};
|
||||
|
||||
export const drawBezierHelper = (ctx: CanvasRenderingContext2D, bezier: WasmBezierInstance, strokeColor = COLORS.INTERACTIVE.STROKE_1, radius = DEFAULT_ENDPOINT_RADIUS): void => {
|
||||
export const drawBezierHelper = (ctx: CanvasRenderingContext2D, bezier: WasmBezierInstance, bezierStyleConfig: Partial<BezierStyleConfig> = {}): void => {
|
||||
const points = bezier.get_points().map((p: string) => JSON.parse(p));
|
||||
drawBezier(ctx, points, null, strokeColor, radius);
|
||||
drawBezier(ctx, points, null, bezierStyleConfig);
|
||||
};
|
||||
|
||||
export const drawBezier = (ctx: CanvasRenderingContext2D, points: Point[], dragIndex: number | null = null, strokeColor = COLORS.INTERACTIVE.STROKE_1, radius = DEFAULT_ENDPOINT_RADIUS): void => {
|
||||
export const drawBezier = (ctx: CanvasRenderingContext2D, points: Point[], dragIndex: number | null = null, bezierStyleConfig: Partial<BezierStyleConfig> = {}): void => {
|
||||
const styleConfig: BezierStyleConfig = {
|
||||
curveStrokeColor: COLORS.INTERACTIVE.STROKE_1,
|
||||
handleStrokeColor: COLORS.INTERACTIVE.STROKE_1,
|
||||
handleLineStrokeColor: COLORS.INTERACTIVE.STROKE_1,
|
||||
radius: DEFAULT_ENDPOINT_RADIUS,
|
||||
...bezierStyleConfig,
|
||||
};
|
||||
// if the handle or handle line colors are not specified, use the same colour as the rest of the curve
|
||||
if (bezierStyleConfig.curveStrokeColor) {
|
||||
if (!bezierStyleConfig.handleStrokeColor) {
|
||||
styleConfig.handleStrokeColor = bezierStyleConfig.curveStrokeColor;
|
||||
}
|
||||
if (!bezierStyleConfig.handleLineStrokeColor) {
|
||||
styleConfig.handleLineStrokeColor = bezierStyleConfig.curveStrokeColor;
|
||||
}
|
||||
}
|
||||
// Points passed to drawBezier are interpreted as follows
|
||||
// points[0] = start point
|
||||
// points[1] = handle start
|
||||
@@ -82,7 +100,7 @@ export const drawBezier = (ctx: CanvasRenderingContext2D, points: Point[], dragI
|
||||
end = points[2];
|
||||
}
|
||||
|
||||
ctx.strokeStyle = strokeColor;
|
||||
ctx.strokeStyle = styleConfig.curveStrokeColor;
|
||||
ctx.lineWidth = 2;
|
||||
|
||||
ctx.beginPath();
|
||||
@@ -94,10 +112,11 @@ export const drawBezier = (ctx: CanvasRenderingContext2D, points: Point[], dragI
|
||||
}
|
||||
ctx.stroke();
|
||||
|
||||
drawLine(ctx, start, handleStart, strokeColor);
|
||||
drawLine(ctx, end, handleEnd, strokeColor);
|
||||
drawLine(ctx, start, handleStart, styleConfig.handleLineStrokeColor);
|
||||
drawLine(ctx, end, handleEnd, styleConfig.handleLineStrokeColor);
|
||||
|
||||
points.forEach((point, index) => {
|
||||
drawPoint(ctx, point, getPointSizeByIndex(index, points.length, radius), index === dragIndex ? COLORS.INTERACTIVE.SELECTED : strokeColor);
|
||||
const strokeColor = isIndexFirstOrLast(index, points.length) ? styleConfig.curveStrokeColor : styleConfig.handleStrokeColor;
|
||||
drawPoint(ctx, point, getPointSizeByIndex(index, points.length, styleConfig.radius), index === dragIndex ? COLORS.INTERACTIVE.SELECTED : strokeColor);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -14,6 +14,10 @@ export type SliderOption = {
|
||||
variable: string;
|
||||
};
|
||||
|
||||
export type TemplateOption = {
|
||||
sliders: SliderOption[];
|
||||
};
|
||||
|
||||
export type Point = {
|
||||
x: number;
|
||||
y: number;
|
||||
@@ -22,3 +26,10 @@ export type Point = {
|
||||
export type BezierPoint = Point & {
|
||||
mutator: WasmBezierMutatorKey;
|
||||
};
|
||||
|
||||
export type BezierStyleConfig = {
|
||||
curveStrokeColor: string;
|
||||
handleStrokeColor: string;
|
||||
handleLineStrokeColor: string;
|
||||
radius: number;
|
||||
};
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export type WasmRawInstance = typeof import("../../wasm/pkg");
|
||||
export type WasmBezierInstance = InstanceType<WasmRawInstance["WasmBezier"]>;
|
||||
Reference in New Issue
Block a user