Beginnings of the bezier-rs math library (#662)

Co-authored-by: Thomas Cheng <35661641+Androxium@users.noreply.github.com>
Co-authored-by: Robert Nadal <Robnadal44@gmail.com>
Co-authored-by: ll2zheng <ll2zheng@uwaterloo.ca>
This commit is contained in:
Hannah Li
2022-06-16 17:50:58 -07:00
committed by Keavon Chambers
co-authored by Thomas Cheng Robert Nadal ll2zheng
parent 04d6bd9190
commit 7275119f6e
30 changed files with 20185 additions and 2 deletions
@@ -0,0 +1,81 @@
import { Point } from "@/utils/types";
export const getContextFromCanvas = (canvas: HTMLCanvasElement): CanvasRenderingContext2D => {
const ctx = canvas.getContext("2d");
if (ctx === null) {
throw Error("Failed to fetch context");
}
return ctx;
};
export const drawLine = (ctx: CanvasRenderingContext2D, p1: Point, p2: Point): void => {
ctx.strokeStyle = "grey";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.stroke();
};
export const drawPoint = (ctx: CanvasRenderingContext2D, p: Point, stroke = "black"): void => {
// Outline the point
ctx.strokeStyle = p.selected ? "blue" : stroke;
ctx.lineWidth = p.r / 3;
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, 2 * Math.PI, false);
ctx.stroke();
// Fill the point (hiding any overlapping lines)
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(p.x, p.y, p.r * (2 / 3), 0, 2 * Math.PI, false);
ctx.fill();
};
export const drawText = (ctx: CanvasRenderingContext2D, text: string, x: number, y: number): void => {
ctx.fillStyle = "black";
ctx.font = "16px Arial";
ctx.fillText(text, x, y);
};
export const drawBezier = (ctx: CanvasRenderingContext2D, points: Point[]): void => {
/* Until a bezier representation is finalized, treat the points as follows
points[0] = start point
points[1] = handle 1
points[2] = (optional) handle 2
points[3] = end point
*/
const start = points[0];
let end = null;
let handle1 = null;
let handle2 = null;
if (points.length === 4) {
handle1 = points[1];
handle2 = points[2];
end = points[3];
} else {
handle1 = points[1];
handle2 = handle1;
end = points[2];
}
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
if (points.length === 3) {
ctx.quadraticCurveTo(handle1.x, handle1.y, end.x, end.y);
} else {
ctx.bezierCurveTo(handle1.x, handle1.y, handle2.x, handle2.y, end.x, end.y);
}
ctx.stroke();
drawLine(ctx, start, handle1);
drawLine(ctx, end, handle2);
points.forEach((point) => {
drawPoint(ctx, point);
});
};
@@ -0,0 +1,15 @@
export type WasmRawInstance = typeof import("../../wasm/pkg");
export type WasmBezierInstance = InstanceType<WasmRawInstance["WasmBezier"]>;
export type WasmBezierKey = keyof WasmBezierInstance;
export type WasmBezierMutatorKey = "set_start" | "set_handle1" | "set_handle2" | "set_end";
export type BezierCallback = (canvas: HTMLCanvasElement, bezier: WasmBezierInstance, options: string) => void;
export type Point = {
x: number;
y: number;
r: number;
mutator: WasmBezierMutatorKey;
selected: boolean;
};
@@ -0,0 +1,2 @@
export type WasmRawInstance = typeof import("../../wasm/pkg");
export type WasmBezierInstance = InstanceType<WasmRawInstance["WasmBezier"]>;