import type {PossibleVector2, SignalValue, Vector2Signal} from '@revideo/core'; import {QuadBezierSegment} from '../curves'; import type {PolynomialSegment} from '../curves/PolynomialSegment'; import {computed, vector2Signal} from '../decorators'; import {lineTo, moveTo, quadraticCurveTo} from '../utils'; import type {BezierOverlayInfo} from './Bezier'; import {Bezier} from './Bezier'; import type {CurveProps} from './Curve'; export interface QuadBezierProps extends CurveProps { p0?: SignalValue; p0X?: SignalValue; p0Y?: SignalValue; p1?: SignalValue; p1X?: SignalValue; p1Y?: SignalValue; p2?: SignalValue; p2X?: SignalValue; p2Y?: SignalValue; } /** * A node for drawing a quadratic Bézier curve. * * @preview * ```tsx editor * import {makeScene2D, QuadBezier} from '@revideo/2d'; * import {createRef} from '@revideo/core'; * * export default makeScene2D(function* (view) { * const bezier = createRef(); * * view.add( * * ); * * yield* bezier().end(1, 1); * yield* bezier().start(1, 1).to(0, 1); * }); * ``` */ export class QuadBezier extends Bezier { /** * The start point of the Bézier curve. */ @vector2Signal('p0') public declare readonly p0: Vector2Signal; /** * The control point of the Bézier curve. */ @vector2Signal('p1') public declare readonly p1: Vector2Signal; /** * The end point of the Bézier curve. */ @vector2Signal('p2') public declare readonly p2: Vector2Signal; public constructor(props: QuadBezierProps) { super(props); } @computed() protected segment(): PolynomialSegment { return new QuadBezierSegment(this.p0(), this.p1(), this.p2()); } protected overlayInfo(matrix: DOMMatrix): BezierOverlayInfo { const [p0, p1, p2] = this.segment().transformPoints(matrix); const curvePath = new Path2D(); moveTo(curvePath, p0); quadraticCurveTo(curvePath, p1, p2); const handleLinesPath = new Path2D(); moveTo(handleLinesPath, p0); lineTo(handleLinesPath, p1); lineTo(handleLinesPath, p2); return { curve: curvePath, startPoint: p0, endPoint: p2, controlPoints: [p1], handleLines: handleLinesPath, }; } }