packages/core/src/lib/components/circle.ts
This is the source snapshot used to build these API details. View this revision on GitHub.
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 version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.