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:
Hannah Li
2022-06-29 20:52:09 -04:00
committed by GitHub
parent 79944b54c8
commit ee98908d88
13 changed files with 19471 additions and 19055 deletions
@@ -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"]>;