@blinkorb/rcx 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/components/canvas/context.d.ts +11 -0
  2. package/components/canvas/context.js +4 -0
  3. package/components/canvas/context.js.map +1 -0
  4. package/components/canvas/index.d.ts +7 -0
  5. package/components/canvas/index.js +62 -0
  6. package/components/canvas/index.js.map +1 -0
  7. package/components/index.js +6 -0
  8. package/components/index.js.map +1 -0
  9. package/components/paths/arc-to.d.ts +12 -0
  10. package/components/paths/arc-to.js +24 -0
  11. package/components/paths/arc-to.js.map +1 -0
  12. package/components/paths/clip.d.ts +6 -0
  13. package/components/paths/clip.js +19 -0
  14. package/components/paths/clip.js.map +1 -0
  15. package/components/paths/index.js +6 -0
  16. package/components/paths/index.js.map +1 -0
  17. package/components/paths/line.d.ts +11 -0
  18. package/components/paths/line.js +25 -0
  19. package/components/paths/line.js.map +1 -0
  20. package/components/paths/path.d.ts +8 -0
  21. package/components/paths/path.js +33 -0
  22. package/components/paths/path.js.map +1 -0
  23. package/components/paths/point.d.ts +7 -0
  24. package/components/paths/point.js +15 -0
  25. package/components/paths/point.js.map +1 -0
  26. package/components/shapes/circle.d.ts +14 -0
  27. package/components/shapes/circle.js +8 -0
  28. package/components/shapes/circle.js.map +1 -0
  29. package/components/shapes/ellipse.d.ts +15 -0
  30. package/components/shapes/ellipse.js +24 -0
  31. package/components/shapes/ellipse.js.map +1 -0
  32. package/components/shapes/index.js +4 -0
  33. package/components/shapes/index.js.map +1 -0
  34. package/components/shapes/rectangle.d.ts +10 -0
  35. package/components/shapes/rectangle.js +20 -0
  36. package/components/shapes/rectangle.js.map +1 -0
  37. package/components/text/index.js +2 -0
  38. package/components/text/index.js.map +1 -0
  39. package/components/text/text.d.ts +13 -0
  40. package/components/text/text.js +78 -0
  41. package/components/text/text.js.map +1 -0
  42. package/components/transform/index.js +4 -0
  43. package/components/transform/index.js.map +1 -0
  44. package/components/transform/rotate.d.ts +5 -0
  45. package/components/transform/rotate.js +14 -0
  46. package/components/transform/rotate.js.map +1 -0
  47. package/components/transform/scale.d.ts +11 -0
  48. package/components/transform/scale.js +14 -0
  49. package/components/transform/scale.js.map +1 -0
  50. package/components/transform/translate.d.ts +6 -0
  51. package/components/transform/translate.js +14 -0
  52. package/components/transform/translate.js.map +1 -0
  53. package/context/create-context.d.ts +9 -0
  54. package/context/create-context.js +29 -0
  55. package/context/create-context.js.map +1 -0
  56. package/context/index.js +2 -0
  57. package/context/index.js.map +1 -0
  58. package/hooks/index.js +9 -0
  59. package/hooks/index.js.map +1 -0
  60. package/hooks/use-canvas-context.d.ts +1 -0
  61. package/hooks/use-canvas-context.js +9 -0
  62. package/hooks/use-canvas-context.js.map +1 -0
  63. package/hooks/use-linear-gradient.d.ts +9 -0
  64. package/hooks/use-linear-gradient.js +13 -0
  65. package/hooks/use-linear-gradient.js.map +1 -0
  66. package/hooks/use-loop.d.ts +1 -0
  67. package/hooks/use-loop.js +9 -0
  68. package/hooks/use-loop.js.map +1 -0
  69. package/hooks/use-on.d.ts +2 -0
  70. package/hooks/use-on.js +16 -0
  71. package/hooks/use-on.js.map +1 -0
  72. package/hooks/use-radial-gradient.d.ts +11 -0
  73. package/hooks/use-radial-gradient.js +13 -0
  74. package/hooks/use-radial-gradient.js.map +1 -0
  75. package/hooks/use-render.d.ts +3 -0
  76. package/hooks/use-render.js +8 -0
  77. package/hooks/use-render.js.map +1 -0
  78. package/hooks/use-state.d.ts +3 -0
  79. package/hooks/use-state.js +5 -0
  80. package/hooks/use-state.js.map +1 -0
  81. package/hooks/use-window-size.d.ts +4 -0
  82. package/hooks/use-window-size.js +20 -0
  83. package/hooks/use-window-size.js.map +1 -0
  84. package/index.js +7 -0
  85. package/index.js.map +1 -0
  86. package/internal/emitter.d.ts +15 -0
  87. package/internal/emitter.js +19 -0
  88. package/internal/emitter.js.map +1 -0
  89. package/internal/global.d.ts +2 -0
  90. package/internal/global.js +4 -0
  91. package/internal/global.js.map +1 -0
  92. package/internal/hooks.d.ts +2 -0
  93. package/internal/hooks.js +17 -0
  94. package/internal/hooks.js.map +1 -0
  95. package/internal/reactive.d.ts +2 -0
  96. package/internal/reactive.js +16 -0
  97. package/internal/reactive.js.map +1 -0
  98. package/jsx-runtime.d.ts +4 -0
  99. package/jsx-runtime.js +8 -0
  100. package/jsx-runtime.js.map +1 -0
  101. package/package.json +11 -23
  102. package/render.d.ts +4 -0
  103. package/render.js +198 -0
  104. package/render.js.map +1 -0
  105. package/types.d.ts +108 -0
  106. package/types.js +1 -0
  107. package/types.js.map +1 -0
  108. package/utils/apply-fill-and-stroke-style.d.ts +2 -0
  109. package/utils/apply-fill-and-stroke-style.js +24 -0
  110. package/utils/apply-fill-and-stroke-style.js.map +1 -0
  111. package/utils/get-recommended-pixel-ratio.d.ts +1 -0
  112. package/utils/get-recommended-pixel-ratio.js +2 -0
  113. package/utils/get-recommended-pixel-ratio.js.map +1 -0
  114. package/utils/index.js +9 -0
  115. package/utils/index.js.map +1 -0
  116. package/utils/is-own-property-of.d.ts +2 -0
  117. package/utils/is-own-property-of.js +2 -0
  118. package/utils/is-own-property-of.js.map +1 -0
  119. package/utils/is-valid-fill-or-stroke-style.d.ts +1 -0
  120. package/utils/is-valid-fill-or-stroke-style.js +3 -0
  121. package/utils/is-valid-fill-or-stroke-style.js.map +1 -0
  122. package/utils/is-valid-stroke-cap.d.ts +1 -0
  123. package/utils/is-valid-stroke-cap.js +8 -0
  124. package/utils/is-valid-stroke-cap.js.map +1 -0
  125. package/utils/is-valid-stroke-join.d.ts +1 -0
  126. package/utils/is-valid-stroke-join.js +8 -0
  127. package/utils/is-valid-stroke-join.js.map +1 -0
  128. package/utils/resolve-styles.d.ts +2 -0
  129. package/utils/resolve-styles.js +16 -0
  130. package/utils/resolve-styles.js.map +1 -0
  131. package/utils/type-guards.d.ts +2 -0
  132. package/utils/type-guards.js +2 -0
  133. package/utils/type-guards.js.map +1 -0
  134. package/utils/with-px.d.ts +1 -0
  135. package/utils/with-px.js +2 -0
  136. package/utils/with-px.js.map +1 -0
  137. package/.eslintignore +0 -4
  138. package/.eslintrc.json +0 -286
  139. package/.gitattributes +0 -2
  140. package/.github/CODEOWNERS +0 -1
  141. package/.github/workflows/ci.yml +0 -19
  142. package/.nvmrc +0 -1
  143. package/.prettierignore +0 -28
  144. package/.prettierrc.json +0 -4
  145. package/demo/index.html +0 -29
  146. package/demo/index.tsx +0 -316
  147. package/demo/tsconfig.json +0 -12
  148. package/jest.config.ts +0 -21
  149. package/scripts/prep-package.js +0 -29
  150. package/src/components/canvas/context.ts +0 -6
  151. package/src/components/canvas/index.ts +0 -98
  152. package/src/components/paths/arc-to.ts +0 -66
  153. package/src/components/paths/clip.ts +0 -32
  154. package/src/components/paths/line.ts +0 -53
  155. package/src/components/paths/path.ts +0 -59
  156. package/src/components/paths/point.ts +0 -24
  157. package/src/components/shapes/circle.tsx +0 -32
  158. package/src/components/shapes/ellipse.ts +0 -75
  159. package/src/components/shapes/rectangle.ts +0 -45
  160. package/src/components/text/text.ts +0 -137
  161. package/src/components/transform/rotate.ts +0 -26
  162. package/src/components/transform/scale.ts +0 -34
  163. package/src/components/transform/translate.ts +0 -27
  164. package/src/context/create-context.ts +0 -49
  165. package/src/hooks/use-canvas-context.ts +0 -11
  166. package/src/hooks/use-linear-gradient.ts +0 -39
  167. package/src/hooks/use-loop.ts +0 -11
  168. package/src/hooks/use-on.ts +0 -18
  169. package/src/hooks/use-radial-gradient.ts +0 -45
  170. package/src/hooks/use-render.ts +0 -14
  171. package/src/hooks/use-state.ts +0 -9
  172. package/src/hooks/use-window-size.ts +0 -24
  173. package/src/internal/emitter.ts +0 -39
  174. package/src/internal/global.ts +0 -5
  175. package/src/internal/hooks.ts +0 -32
  176. package/src/internal/reactive.test.ts +0 -20
  177. package/src/internal/reactive.ts +0 -20
  178. package/src/jsx-runtime.ts +0 -21
  179. package/src/render.ts +0 -299
  180. package/src/types.ts +0 -151
  181. package/src/utils/apply-fill-and-stroke-style.ts +0 -33
  182. package/src/utils/get-recommended-pixel-ratio.ts +0 -2
  183. package/src/utils/is-own-property-of.ts +0 -6
  184. package/src/utils/is-valid-fill-or-stroke-style.ts +0 -5
  185. package/src/utils/is-valid-stroke-cap.ts +0 -10
  186. package/src/utils/is-valid-stroke-join.ts +0 -10
  187. package/src/utils/resolve-styles.ts +0 -21
  188. package/src/utils/type-guards.ts +0 -4
  189. package/src/utils/with-px.ts +0 -4
  190. package/tsb.config.ts +0 -11
  191. package/tsconfig.dist.json +0 -13
  192. package/tsconfig.json +0 -25
  193. /package/{src/components/index.ts → components/index.d.ts} +0 -0
  194. /package/{src/components/paths/index.ts → components/paths/index.d.ts} +0 -0
  195. /package/{src/components/shapes/index.ts → components/shapes/index.d.ts} +0 -0
  196. /package/{src/components/text/index.ts → components/text/index.d.ts} +0 -0
  197. /package/{src/components/transform/index.ts → components/transform/index.d.ts} +0 -0
  198. /package/{src/context/index.ts → context/index.d.ts} +0 -0
  199. /package/{src/hooks/index.ts → hooks/index.d.ts} +0 -0
  200. /package/{src/index.ts → index.d.ts} +0 -0
  201. /package/{src/utils/index.ts → utils/index.d.ts} +0 -0
package/jest.config.ts DELETED
@@ -1,21 +0,0 @@
1
- import type { Config } from 'jest';
2
-
3
- const config = {
4
- preset: 'ts-jest/presets/default-esm',
5
- testMatch: ['<rootDir>/src/**/*.(spec|test).{js,jsx,ts,tsx}'],
6
- collectCoverageFrom: ['src/**/*.(js|jsx|ts|tsx)'],
7
- // coverageThreshold: {
8
- // global: {
9
- // branches: 100,
10
- // functions: 100,
11
- // lines: 100,
12
- // statements: 100,
13
- // },
14
- // },
15
- moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
16
- moduleNameMapper: {
17
- '(.+)\\.js$': '$1',
18
- },
19
- } satisfies Config;
20
-
21
- export default config;
@@ -1,29 +0,0 @@
1
- import { writeFileSync } from 'node:fs';
2
- import { dirname, resolve } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
-
5
- import packageJson from '../package.json' with { type: 'json' };
6
-
7
- const cwd = dirname(fileURLToPath(import.meta.url));
8
-
9
- const modifiedJson = {
10
- ...packageJson,
11
- main: packageJson.main.replace('src/', '').replace('.ts', '.js'),
12
- exports: Object.fromEntries(
13
- Object.entries(packageJson.exports).map(([key, imports]) => [
14
- key,
15
- Object.fromEntries(
16
- Object.entries(imports).map(([path, actual]) => [
17
- path,
18
- actual.replace('src/', '').replace('.ts', '.js'),
19
- ])
20
- ),
21
- ])
22
- ),
23
- };
24
-
25
- writeFileSync(
26
- resolve(cwd, '../dist/package.json'),
27
- JSON.stringify(modifiedJson, null, 2),
28
- 'utf-8'
29
- );
@@ -1,6 +0,0 @@
1
- import { createContext } from '../../context/create-context.ts';
2
- import type { RCXCanvasContext, RCXRenderingContext } from '../../types.ts';
3
-
4
- export const canvasContext = createContext<RCXCanvasContext>();
5
-
6
- export const renderingContext = createContext<RCXRenderingContext>();
@@ -1,98 +0,0 @@
1
- import { useOnMount } from '../../hooks/use-on.ts';
2
- import { useRenderBeforeChildren } from '../../hooks/use-render.ts';
3
- import { useReactive, useUnreactive } from '../../hooks/use-state.ts';
4
- import type { RCXComponent, RCXPropsWithChildren } from '../../types.ts';
5
- import { getRecommendedPixelRatio } from '../../utils/get-recommended-pixel-ratio.ts';
6
- import { canvasContext, renderingContext } from './context.ts';
7
-
8
- export type CanvasProps = RCXPropsWithChildren<{
9
- width?: number | 'auto';
10
- height?: number | 'auto';
11
- pixelRatio?: number | 'auto';
12
- }>;
13
-
14
- const getValueOrAuto = (
15
- value: undefined | number | 'auto',
16
- autoValue: number
17
- ) => {
18
- if (typeof value === 'number') {
19
- return value;
20
- }
21
-
22
- return autoValue;
23
- };
24
-
25
- export const Canvas: RCXComponent<CanvasProps> = (props) => {
26
- const renderingContextStateRoot = renderingContext.useInject();
27
-
28
- if (!renderingContextStateRoot) {
29
- throw new Error('Canvas was rendered outside of an application');
30
- }
31
-
32
- const initialCanvasSize =
33
- renderingContextStateRoot.canvas.getBoundingClientRect();
34
- const canvasSize = useReactive({
35
- width: initialCanvasSize.width,
36
- height: initialCanvasSize.height,
37
- });
38
- const resizeObserver = useUnreactive(
39
- new ResizeObserver((entries) => {
40
- const canvasEntry = entries[0];
41
- if (typeof canvasEntry === 'undefined') {
42
- return;
43
- }
44
-
45
- const rect = canvasEntry.target.getBoundingClientRect();
46
- canvasSize.width = rect.width;
47
- canvasSize.height = rect.height;
48
- })
49
- );
50
-
51
- useOnMount(() => {
52
- resizeObserver.observe(renderingContextStateRoot.canvas);
53
-
54
- return () => {
55
- resizeObserver.disconnect();
56
- };
57
- });
58
-
59
- useRenderBeforeChildren((renderingContextState) => {
60
- const pixelRatio = getValueOrAuto(
61
- props.pixelRatio,
62
- getRecommendedPixelRatio()
63
- );
64
- const rect = renderingContextState.canvas.getBoundingClientRect();
65
- const width =
66
- getValueOrAuto(props.width, rect.width * pixelRatio) / pixelRatio;
67
- const height =
68
- getValueOrAuto(props.height, rect.height * pixelRatio) / pixelRatio;
69
-
70
- renderingContextState.canvas.width = width * pixelRatio;
71
- renderingContextState.canvas.height = height * pixelRatio;
72
- renderingContextState.ctx2d.scale(pixelRatio, pixelRatio);
73
- });
74
-
75
- const pixelRatio = getValueOrAuto(
76
- props.pixelRatio,
77
- getRecommendedPixelRatio()
78
- );
79
- const rect = renderingContextStateRoot.canvas.getBoundingClientRect();
80
- const width =
81
- getValueOrAuto(props.width, rect.width * pixelRatio) / pixelRatio;
82
- const height =
83
- getValueOrAuto(props.height, rect.height * pixelRatio) / pixelRatio;
84
-
85
- canvasContext.useProvide({
86
- ...renderingContextStateRoot,
87
- props,
88
- width,
89
- height,
90
- pixelRatio,
91
- actualWidth: width * pixelRatio,
92
- actualHeight: height * pixelRatio,
93
- });
94
-
95
- return props.children;
96
- };
97
-
98
- Canvas.displayName = 'Canvas';
@@ -1,66 +0,0 @@
1
- import {
2
- useRenderAfterChildren,
3
- useRenderBeforeChildren,
4
- } from '../../hooks/use-render.ts';
5
- import type {
6
- RCXComponent,
7
- RCXPropsWithChildren,
8
- RCXShapeStyle,
9
- RCXStyleProp,
10
- } from '../../types.ts';
11
- import { applyFillAndStrokeStyles } from '../../utils/apply-fill-and-stroke-style.ts';
12
- import { resolveStyles } from '../../utils/resolve-styles.ts';
13
-
14
- export type ArcToProps = RCXPropsWithChildren<{
15
- startControlX: number;
16
- startControlY: number;
17
- endControlX: number;
18
- endControlY: number;
19
- radius: number;
20
- style?: RCXStyleProp<RCXShapeStyle>;
21
- beginPath?: boolean;
22
- closePath?: boolean;
23
- }>;
24
-
25
- export const ArcTo: RCXComponent<ArcToProps> = (props) => {
26
- useRenderBeforeChildren((renderingContext) => {
27
- const {
28
- startControlX,
29
- startControlY,
30
- endControlX,
31
- endControlY,
32
- radius,
33
- beginPath = false,
34
- } = props;
35
-
36
- renderingContext.ctx2d.save();
37
-
38
- if (beginPath) {
39
- renderingContext.ctx2d.beginPath();
40
- }
41
-
42
- renderingContext.ctx2d.arcTo(
43
- startControlX,
44
- startControlY,
45
- endControlX,
46
- endControlY,
47
- radius
48
- );
49
- });
50
-
51
- useRenderAfterChildren((renderingContext) => {
52
- const { closePath = false } = props;
53
-
54
- if (closePath) {
55
- renderingContext.ctx2d.closePath();
56
- }
57
-
58
- applyFillAndStrokeStyles(renderingContext, resolveStyles(props.style));
59
-
60
- renderingContext.ctx2d.restore();
61
- });
62
-
63
- return props.children;
64
- };
65
-
66
- ArcTo.displayName = 'ArcTo';
@@ -1,32 +0,0 @@
1
- import {
2
- useRenderAfterChildren,
3
- useRenderBeforeChildren,
4
- } from '../../hooks/use-render.ts';
5
- import type { RCXComponent, RCXPropsWithChildren } from '../../types.ts';
6
-
7
- export type ClipProps = RCXPropsWithChildren<{
8
- path?: Path2D;
9
- fillRule?: CanvasFillRule;
10
- }>;
11
-
12
- export const Clip: RCXComponent<ClipProps> = (props) => {
13
- useRenderBeforeChildren((renderingContext) => {
14
- const { path, fillRule } = props;
15
-
16
- renderingContext.ctx2d.save();
17
-
18
- if (typeof path === 'undefined') {
19
- renderingContext.ctx2d.clip(fillRule);
20
- } else {
21
- renderingContext.ctx2d.clip(path, fillRule);
22
- }
23
- });
24
-
25
- useRenderAfterChildren((renderingContext) => {
26
- renderingContext.ctx2d.restore();
27
- });
28
-
29
- return props.children;
30
- };
31
-
32
- Clip.displayName = 'Clip';
@@ -1,53 +0,0 @@
1
- import {
2
- useRenderAfterChildren,
3
- useRenderBeforeChildren,
4
- } from '../../hooks/use-render.ts';
5
- import type {
6
- RCXComponent,
7
- RCXLineStyle,
8
- RCXPropsWithChildren,
9
- RCXStyleProp,
10
- } from '../../types.ts';
11
- import { applyFillAndStrokeStyles } from '../../utils/apply-fill-and-stroke-style.ts';
12
- import { resolveStyles } from '../../utils/resolve-styles.ts';
13
-
14
- export type LineProps = RCXPropsWithChildren<{
15
- startX: number;
16
- startY: number;
17
- endX: number;
18
- endY: number;
19
- beginPath?: boolean;
20
- closePath?: boolean;
21
- style?: RCXStyleProp<RCXLineStyle>;
22
- }>;
23
-
24
- export const Line: RCXComponent<LineProps> = (props) => {
25
- useRenderBeforeChildren((renderingContext) => {
26
- const { startX, startY, endX, endY, beginPath = true } = props;
27
-
28
- renderingContext.ctx2d.save();
29
-
30
- if (beginPath) {
31
- renderingContext.ctx2d.beginPath();
32
- }
33
-
34
- renderingContext.ctx2d.moveTo(startX, startY);
35
- renderingContext.ctx2d.lineTo(endX, endY);
36
- });
37
-
38
- useRenderAfterChildren((renderingContext) => {
39
- const { closePath = false } = props;
40
-
41
- if (closePath) {
42
- renderingContext.ctx2d.closePath();
43
- }
44
-
45
- applyFillAndStrokeStyles(renderingContext, resolveStyles(props.style));
46
-
47
- renderingContext.ctx2d.restore();
48
- });
49
-
50
- return props.children;
51
- };
52
-
53
- Line.displayName = 'Line';
@@ -1,59 +0,0 @@
1
- import {
2
- useRenderAfterChildren,
3
- useRenderBeforeChildren,
4
- } from '../../hooks/use-render.ts';
5
- import type {
6
- RCXComponent,
7
- RCXPoint,
8
- RCXPropsWithChildren,
9
- RCXShapeStyle,
10
- RCXStyleProp,
11
- } from '../../types.ts';
12
- import { applyFillAndStrokeStyles } from '../../utils/apply-fill-and-stroke-style.ts';
13
- import { resolveStyles } from '../../utils/resolve-styles.ts';
14
- import { isArray } from '../../utils/type-guards.ts';
15
-
16
- export type PathProps = RCXPropsWithChildren<{
17
- points?: readonly RCXPoint[];
18
- beginPath?: boolean;
19
- closePath?: boolean;
20
- style?: RCXStyleProp<RCXShapeStyle>;
21
- }>;
22
-
23
- export const Path: RCXComponent<PathProps> = (props) => {
24
- useRenderBeforeChildren((renderingContext) => {
25
- const { points, beginPath = true } = props;
26
-
27
- renderingContext.ctx2d.save();
28
-
29
- if (beginPath) {
30
- renderingContext.ctx2d.beginPath();
31
- }
32
-
33
- points?.forEach((point, index) => {
34
- const [x, y] = isArray(point) ? point : [point.x, point.y];
35
-
36
- if (index === 0) {
37
- renderingContext.ctx2d.moveTo(x, y);
38
- } else {
39
- renderingContext.ctx2d.lineTo(x, y);
40
- }
41
- });
42
- });
43
-
44
- useRenderAfterChildren((renderingContext) => {
45
- const { closePath = false } = props;
46
-
47
- if (closePath) {
48
- renderingContext.ctx2d.closePath();
49
- }
50
-
51
- applyFillAndStrokeStyles(renderingContext, resolveStyles(props.style));
52
-
53
- renderingContext.ctx2d.restore();
54
- });
55
-
56
- return props.children;
57
- };
58
-
59
- Path.displayName = 'Path';
@@ -1,24 +0,0 @@
1
- import { useRenderBeforeChildren } from '../../hooks/use-render.ts';
2
- import type { RCXComponent, RCXPropsWithChildren } from '../../types.ts';
3
-
4
- export type PointProps = RCXPropsWithChildren<{
5
- x: number;
6
- y: number;
7
- lineTo?: boolean;
8
- }>;
9
-
10
- export const Point: RCXComponent<PointProps> = (props) => {
11
- useRenderBeforeChildren((renderingContext) => {
12
- const { x, y, lineTo = true } = props;
13
-
14
- if (lineTo) {
15
- renderingContext.ctx2d.lineTo(x, y);
16
- } else {
17
- renderingContext.ctx2d.moveTo(x, y);
18
- }
19
- });
20
-
21
- return props.children;
22
- };
23
-
24
- Point.displayName = 'Point';
@@ -1,32 +0,0 @@
1
- import type {
2
- RCXComponent,
3
- RCXPropsWithChildren,
4
- RCXShapeStyle,
5
- RCXStyleProp,
6
- } from '../../types.ts';
7
- import { Ellipse } from './ellipse.ts';
8
-
9
- export type CircleProps = RCXPropsWithChildren<{
10
- x: number;
11
- y: number;
12
- radius: number;
13
- rotation?: number;
14
- startAngle?: number;
15
- endAngle?: number;
16
- counterClockwise?: boolean;
17
- beginPath?: boolean;
18
- closePath?: boolean;
19
- style?: RCXStyleProp<RCXShapeStyle>;
20
- }>;
21
-
22
- export const Circle: RCXComponent<CircleProps> = (props) => {
23
- const { radius, ...rest } = props;
24
-
25
- return (
26
- <Ellipse {...rest} radiusX={radius} radiusY={radius}>
27
- {props.children}
28
- </Ellipse>
29
- );
30
- };
31
-
32
- Circle.displayName = 'Circle';
@@ -1,75 +0,0 @@
1
- import {
2
- useRenderAfterChildren,
3
- useRenderBeforeChildren,
4
- } from '../../hooks/use-render.ts';
5
- import type {
6
- RCXComponent,
7
- RCXPropsWithChildren,
8
- RCXShapeStyle,
9
- RCXStyleProp,
10
- } from '../../types.ts';
11
- import { applyFillAndStrokeStyles } from '../../utils/apply-fill-and-stroke-style.ts';
12
- import { resolveStyles } from '../../utils/resolve-styles.ts';
13
-
14
- export type EllipseProps = RCXPropsWithChildren<{
15
- x: number;
16
- y: number;
17
- radiusX: number;
18
- radiusY: number;
19
- rotation?: number;
20
- startAngle?: number;
21
- endAngle?: number;
22
- counterClockwise?: boolean;
23
- beginPath?: boolean;
24
- closePath?: boolean;
25
- style?: RCXStyleProp<RCXShapeStyle>;
26
- }>;
27
-
28
- export const Ellipse: RCXComponent<EllipseProps> = (props) => {
29
- useRenderBeforeChildren((renderingContext) => {
30
- const {
31
- x,
32
- y,
33
- radiusX,
34
- radiusY,
35
- rotation = 0,
36
- startAngle = 0,
37
- endAngle = Math.PI * 2,
38
- counterClockwise = false,
39
- beginPath = true,
40
- } = props;
41
-
42
- renderingContext.ctx2d.save();
43
-
44
- if (beginPath) {
45
- renderingContext.ctx2d.beginPath();
46
- }
47
-
48
- renderingContext.ctx2d.ellipse(
49
- x,
50
- y,
51
- radiusX,
52
- radiusY,
53
- rotation,
54
- startAngle,
55
- endAngle,
56
- counterClockwise
57
- );
58
- });
59
-
60
- useRenderAfterChildren((renderingContext) => {
61
- const { closePath = true } = props;
62
-
63
- if (closePath) {
64
- renderingContext.ctx2d.closePath();
65
- }
66
-
67
- applyFillAndStrokeStyles(renderingContext, resolveStyles(props.style));
68
-
69
- renderingContext.ctx2d.restore();
70
- });
71
-
72
- return props.children;
73
- };
74
-
75
- Ellipse.displayName = 'Ellipse';
@@ -1,45 +0,0 @@
1
- import {
2
- useRenderAfterChildren,
3
- useRenderBeforeChildren,
4
- } from '../../hooks/use-render.ts';
5
- import type {
6
- RCXComponent,
7
- RCXPropsWithChildren,
8
- RCXShapeStyle,
9
- RCXStyleProp,
10
- } from '../../types.ts';
11
- import { applyFillAndStrokeStyles } from '../../utils/apply-fill-and-stroke-style.ts';
12
- import { resolveStyles } from '../../utils/resolve-styles.ts';
13
-
14
- export type RectangleProps = RCXPropsWithChildren<{
15
- x: number;
16
- y: number;
17
- width: number;
18
- height: number;
19
- beginPath?: boolean;
20
- style?: RCXStyleProp<RCXShapeStyle>;
21
- }>;
22
-
23
- export const Rectangle: RCXComponent<RectangleProps> = (props) => {
24
- useRenderBeforeChildren((renderingContext) => {
25
- const { x, y, width, height, beginPath = true } = props;
26
-
27
- renderingContext.ctx2d.save();
28
-
29
- if (beginPath) {
30
- renderingContext.ctx2d.beginPath();
31
- }
32
-
33
- renderingContext.ctx2d.rect(x, y, width, height);
34
- });
35
-
36
- useRenderAfterChildren((renderingContext) => {
37
- applyFillAndStrokeStyles(renderingContext, resolveStyles(props.style));
38
-
39
- renderingContext.ctx2d.restore();
40
- });
41
-
42
- return props.children;
43
- };
44
-
45
- Rectangle.displayName = 'Rectangle';
@@ -1,137 +0,0 @@
1
- import { useRenderBeforeChildren } from '../../hooks/use-render.ts';
2
- import type {
3
- RCXChildren,
4
- RCXComponent,
5
- RCXFontStyle,
6
- RCXPropsWithChildren,
7
- RCXShapeStyle,
8
- RCXStyleProp,
9
- } from '../../types.ts';
10
- import { isValidFillOrStrokeStyle } from '../../utils/is-valid-fill-or-stroke-style.ts';
11
- import { isValidStrokeCap } from '../../utils/is-valid-stroke-cap.ts';
12
- import { isValidStrokeJoin } from '../../utils/is-valid-stroke-join.ts';
13
- import { resolveStyles } from '../../utils/resolve-styles.ts';
14
- import { isArray } from '../../utils/type-guards.ts';
15
- import { withPx } from '../../utils/with-px.ts';
16
-
17
- export interface TextStyle extends RCXShapeStyle, RCXFontStyle {
18
- align?: CanvasTextAlign;
19
- baseline?: CanvasTextBaseline;
20
- }
21
-
22
- export type TextProps = RCXPropsWithChildren<{
23
- x: number;
24
- y: number;
25
- maxWidth?: number;
26
- children?: RCXChildren;
27
- style?: RCXStyleProp<TextStyle>;
28
- }>;
29
-
30
- const DEFAULT_FONT_STYLE = {
31
- // font string
32
- fontStyle: 'normal',
33
- fontWeight: 'normal',
34
- fontSize: 10,
35
- fontFamily: 'sans-serif',
36
- // other ctx2d properties
37
- fontStretch: 'normal',
38
- fontVariant: 'normal',
39
- fontKerning: 'normal',
40
- } satisfies Required<RCXFontStyle>;
41
-
42
- const getTextFromChildren = (children: RCXChildren): string => {
43
- if (
44
- children === null ||
45
- typeof children === 'boolean' ||
46
- typeof children === 'undefined'
47
- ) {
48
- return '';
49
- }
50
-
51
- if (typeof children === 'object') {
52
- if (isArray(children)) {
53
- return children.reduce<string>(
54
- (acc, child) => acc + getTextFromChildren(child),
55
- ''
56
- );
57
- }
58
-
59
- return getTextFromChildren(children.props.children);
60
- }
61
-
62
- return children.toString();
63
- };
64
-
65
- export const Text: RCXComponent<TextProps> = (props) => {
66
- useRenderBeforeChildren((renderingContext) => {
67
- const { x, y, maxWidth, children } = props;
68
- const {
69
- fill,
70
- stroke,
71
- strokeWidth,
72
- strokeCap,
73
- strokeJoin,
74
- align,
75
- baseline,
76
- fontStyle = DEFAULT_FONT_STYLE.fontStyle,
77
- fontWeight = DEFAULT_FONT_STYLE.fontWeight,
78
- fontSize = DEFAULT_FONT_STYLE.fontSize,
79
- fontFamily = DEFAULT_FONT_STYLE.fontFamily,
80
- // other ctx2d properties
81
- fontStretch = DEFAULT_FONT_STYLE.fontStretch,
82
- fontVariant = DEFAULT_FONT_STYLE.fontVariant,
83
- fontKerning = DEFAULT_FONT_STYLE.fontKerning,
84
- } = resolveStyles(props.style);
85
-
86
- const text = getTextFromChildren(children);
87
-
88
- renderingContext.ctx2d.save();
89
-
90
- if (typeof align === 'string') {
91
- renderingContext.ctx2d.textAlign = align;
92
- }
93
-
94
- if (typeof baseline === 'string') {
95
- renderingContext.ctx2d.textBaseline = baseline;
96
- }
97
-
98
- renderingContext.ctx2d.font = [
99
- fontStyle,
100
- fontWeight,
101
- withPx(fontSize),
102
- fontFamily,
103
- ].join(' ');
104
-
105
- renderingContext.ctx2d.fontStretch = fontStretch;
106
- renderingContext.ctx2d.fontVariantCaps = fontVariant;
107
- renderingContext.ctx2d.fontKerning = fontKerning;
108
-
109
- if (isValidFillOrStrokeStyle(fill)) {
110
- renderingContext.ctx2d.fillStyle = fill;
111
- renderingContext.ctx2d.fillText(text, x, y, maxWidth);
112
- }
113
-
114
- if (typeof strokeWidth === 'number') {
115
- renderingContext.ctx2d.lineWidth = strokeWidth;
116
- }
117
-
118
- if (isValidStrokeCap(strokeCap)) {
119
- renderingContext.ctx2d.lineCap = strokeCap;
120
- }
121
-
122
- if (isValidStrokeJoin(strokeJoin)) {
123
- renderingContext.ctx2d.lineJoin = strokeJoin;
124
- }
125
-
126
- if (isValidFillOrStrokeStyle(stroke)) {
127
- renderingContext.ctx2d.strokeStyle = stroke;
128
- renderingContext.ctx2d.strokeText(text, x, y, maxWidth);
129
- }
130
-
131
- renderingContext.ctx2d.restore();
132
- });
133
-
134
- return null;
135
- };
136
-
137
- Text.displayName = 'Text';