Skip to content

packages/core/src/lib/components/wedge.ts

Read as Markdown

This is the source snapshot used to build these API details. View this revision on GitHub.

Back to reference

1 import { definePrimitive } from "../define-primitive.js";
2 import type {
3   PibblEventFocusOptions,
4   PibblEventHandlers,
5   PibblEventParticipationOptions,
6 } from "../events/types.js";
7 import {
8   resolveLocalOffset,
9   stripLayoutParticipation,
10 } from "../style/resolve-built-in.js";
11 import { registerOpaqueStyleProperties } from "../style/resolve-dispatch.js";
12 import type {
13   BoxStyle,
14   CursorStyle,
15   LayoutItemStyle,
16   Length,
17   PaintStyle,
18   ResolvedDrawingStyle,
19 } from "../style/types.js";
20 import type { RenderingContext2D, SystemStyle } from "../types.js";
21 import type { PibblPhysics2DPropExtension } from "../types.js";
22 import { wedgeBounds } from "./arc-geometry.js";
23 import {
24   createWedgePath,
25   resolveCircularSweep,
26 } from "../geometry/circular-sweep.js";
27 import { renderPath } from "./path.js";
28 import {
29   circularPercentageBasis,
30   resolveFiniteShapeNumber,
31   resolveNonnegativeShapeLength,
32 } from "./shape-style.js";
33 
34 /**
35  * Authored inputs for Wedge, including the declared data and presentation options.
36  *
37  * @see {@link PibblEventHandlers}
38  * @see {@link PibblEventParticipationOptions}
39  * @see {@link PibblPhysics2DPropExtension}
40  * @see {@link Wedge}
41  */
42 export interface WedgeProps extends PibblEventHandlers, PibblEventFocusOptions, PibblEventParticipationOptions, PibblPhysics2DPropExtension {}
43 
44 /**
45  * Supported geometry and presentation properties for Wedge.
46  *
47  * @see {@link SystemStyle}
48  * @see {@link PaintStyle}
49  * @see {@link CursorStyle}
50  * @see {@link BoxStyle}
51  * @see {@link LayoutItemStyle}
52  * @see {@link Length}
53  * @see {@link Wedge}
54  */
55 export interface WedgeStyle
56   extends SystemStyle, PaintStyle, CursorStyle, BoxStyle, LayoutItemStyle {
57   /** Radius in the coordinate system of this geometry or effect. See {@link Length}. */
58   radius: Exclude<Length, "auto">;
59   /** Angle at which the arc or slice begins. See {@link WedgeStyle}. */
60   startAngle: number;
61   /** Angle at which the arc or slice ends. See {@link WedgeStyle}. */
62   endAngle: number;
63   /** Horizontal coordinate of the center. See {@link Length}. */
64   cx?: Exclude<Length, "auto">;
65   /** Vertical coordinate of the center. See {@link Length}. */
66   cy?: Exclude<Length, "auto">;
67   /** Whether the arc follows the counterclockwise direction. See {@link WedgeStyle}. */
68   counterclockwise?: boolean;
69   /**
70    * Width used for line hit testing independently of the visible stroke width. See
71    * {@link WedgeStyle}.
72    */
73   lineInteractionWidth?: number;
74 }
75 
76 type ResolvedWedgeStyle = ResolvedDrawingStyle<WedgeStyle> & {
77   radius: number;
78   startAngle: number;
79   endAngle: number;
80   cx: number;
81   cy: number;
82   counterclockwise: boolean;
83 };
84 
85 function renderWedge(
86   props: WedgeProps,
87   style: Readonly<ResolvedWedgeStyle>,
88   ctx: RenderingContext2D,
89 ) {
90   const {
91     cx,
92     cy,
93     radius,
94     startAngle,
95     endAngle,
96     counterclockwise,
97     fill,
98     stroke,
99     strokeWidth,
100     opacity,
101     cursor,
102     lineInteractionWidth,
103   } = style;
104   const sweep = resolveCircularSweep(startAngle, endAngle, counterclockwise);
105   const path = createWedgePath({
106     cx,
107     cy,
108     radius,
109     startAngle,
110     endAngle,
111     counterclockwise,
112   });
113 
114   return renderPath(
115     {
116       ...props,
117       keyboardNavigationBounds:
118         props.keyboardNavigationBounds ?? wedgeBounds(cx, cy, radius, sweep),
119     },
120     {
121       d: path,
122       fill,
123       stroke,
124       strokeWidth,
125       opacity,
126       cursor,
127       lineInteractionWidth,
128     },
129     ctx,
130   );
131 }
132 
133 /**
134  * Describes a center-closed circular wedge primitive for JSX or createElement authoring.
135  *
136  * @param props - Authored component inputs, supplied through JSX or createElement. See the linked
137  * props and style types.
138  * @throws When called directly; Pibbl mounts this component through JSX or createElement.
139  *
140  * @see {@link WedgeProps}
141  * @see {@link WedgeStyle}
142  */
143 export const Wedge = definePrimitive<
144   WedgeProps,
145   WedgeStyle,
146   WedgeStyle,
147   ResolvedWedgeStyle
148 >(renderWedge, {
149   resolveStyle: (style, context) =>
150     ({
151       ...stripLayoutParticipation(style),
152       cx: resolveLocalOffset(
153         style.cx,
154         context.percentageBasis.width,
155         "cx",
156         context,
157       ),
158       cy: resolveLocalOffset(
159         style.cy,
160         context.percentageBasis.height,
161         "cy",
162         context,
163       ),
164       radius: resolveNonnegativeShapeLength(
165         style.radius,
166         circularPercentageBasis(context),
167         "radius",
168         context,
169       ),
170       startAngle: resolveFiniteShapeNumber(
171         style.startAngle,
172         "startAngle",
173         context,
174       ),
175       endAngle: resolveFiniteShapeNumber(style.endAngle, "endAngle", context),
176       counterclockwise: style.counterclockwise ?? false,
177     }) as ResolvedWedgeStyle,
178 });
179 registerOpaqueStyleProperties(Wedge, ["fill", "stroke", "cursor"]);
180 

Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.