Skip to content

packages/core/src/lib/components/circle.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 type { RenderingContext2D, SystemStyle } from '../types.js';
8 import type { PibblPhysics2DPropExtension } from '../types.js';
9 import {
10   resolveLocalOffset,
11   stripLayoutParticipation,
12 } from '../style/resolve-built-in.js';
13 import { registerOpaqueStyleProperties } from '../style/resolve-dispatch.js';
14 import type {
15   BoxStyle,
16   CursorStyle,
17   LayoutItemStyle,
18   Length,
19   PaintStyle,
20   ResolvedDrawingStyle,
21 } from '../style/types.js';
22 import {
23   circularPercentageBasis,
24   resolveNonnegativeShapeLength,
25 } from './shape-style.js';
26 import { renderPath } from './path.js';
27 import { createCirclePath } from '../geometry/circle.js';
28 
29 /**
30  * Authored inputs for Circle, including the declared data and presentation options.
31  *
32  * @see {@link PibblEventHandlers}
33  * @see {@link PibblEventParticipationOptions}
34  * @see {@link PibblPhysics2DPropExtension}
35  * @see {@link Circle}
36  */
37 export interface CircleProps extends PibblEventHandlers, PibblEventFocusOptions, PibblEventParticipationOptions, PibblPhysics2DPropExtension {}
38 
39 /**
40  * Supported geometry and presentation properties for Circle.
41  *
42  * @see {@link SystemStyle}
43  * @see {@link PaintStyle}
44  * @see {@link CursorStyle}
45  * @see {@link BoxStyle}
46  * @see {@link LayoutItemStyle}
47  * @see {@link Length}
48  * @see {@link Circle}
49  */
50 export interface CircleStyle
51   extends SystemStyle, PaintStyle, CursorStyle, BoxStyle, LayoutItemStyle {
52   /** Radius in the coordinate system of this geometry or effect. See {@link Length}. */
53   radius: Exclude<Length, 'auto'>;
54   /** Horizontal coordinate of the center. See {@link Length}. */
55   cx?: Exclude<Length, 'auto'>;
56   /** Vertical coordinate of the center. See {@link Length}. */
57   cy?: Exclude<Length, 'auto'>;
58   /**
59    * Width used for line hit testing independently of the visible stroke width. See
60    * {@link CircleStyle}.
61    */
62   lineInteractionWidth?: number;
63 }
64 
65 type ResolvedCircleStyle = ResolvedDrawingStyle<CircleStyle> & {
66   radius: number;
67   cx: number;
68   cy: number;
69 };
70 
71 function renderCircle(
72   props: CircleProps,
73   style: Readonly<ResolvedCircleStyle>,
74   ctx: RenderingContext2D,
75 ) {
76   const { cx, cy, radius, ...pathStyle } = style;
77   const path = createCirclePath({ cx, cy, radius });
78 
79   return renderPath({
80     ...props,
81     keyboardNavigationBounds: props.keyboardNavigationBounds ?? {
82       x: cx - radius,
83       y: cy - radius,
84       width: radius * 2,
85       height: radius * 2,
86     },
87   }, {
88     ...pathStyle,
89     d: path,
90   }, ctx);
91 }
92 
93 /**
94  * Describes a circle primitive for JSX or createElement authoring.
95  *
96  * @param props - Authored component inputs, supplied through JSX or createElement. See the linked
97  * props and style types.
98  * @throws When called directly; Pibbl mounts this component through JSX or createElement.
99  *
100  * @see {@link CircleProps}
101  * @see {@link CircleStyle}
102  */
103 export const Circle = definePrimitive<
104   CircleProps,
105   CircleStyle,
106   CircleStyle,
107   ResolvedCircleStyle
108 >(renderCircle, {
109   resolveStyle: (style, context) => ({
110     ...stripLayoutParticipation(style),
111     cx: resolveLocalOffset(style.cx, context.percentageBasis.width, 'cx', context),
112     cy: resolveLocalOffset(style.cy, context.percentageBasis.height, 'cy', context),
113     radius: resolveNonnegativeShapeLength(
114       style.radius,
115       circularPercentageBasis(context),
116       'radius',
117       context,
118     ),
119   }) as ResolvedCircleStyle,
120 });
121 registerOpaqueStyleProperties(Circle, ['fill', 'stroke', 'cursor']);
122 

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