@cntrl-site/sdk-nextjs 1.9.77 → 1.9.79

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 (145) hide show
  1. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/sdk-nextjs.iml +12 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/LICENSE +21 -21
  6. package/README.md +4 -4
  7. package/TODO.md +1 -1
  8. package/eslint.config.mjs +35 -35
  9. package/jest.config.js +6 -6
  10. package/lib/common/useItemFXData.js +5 -5
  11. package/lib/components/Article.js +5 -5
  12. package/lib/components/LayoutStyle.js +4 -4
  13. package/lib/components/Section/Section.js +27 -27
  14. package/lib/components/StructuredBlockItem/StructuredBlockItem.js +13 -13
  15. package/lib/components/StructuredBlockItem/StructuredComponent/StructuredComponent.js +12 -12
  16. package/lib/components/StructuredContent/StructuredContent.js +11 -11
  17. package/lib/components/items/CodeEmbedItem/CodeEmbedItem.js +36 -36
  18. package/lib/components/items/ComponentItem/ComponentItem.js +13 -13
  19. package/lib/components/items/CompoundItem/CompoundChild.js +20 -20
  20. package/lib/components/items/CompoundItem/CompoundItem.js +14 -14
  21. package/lib/components/items/CustomItem/CustomItem.js +9 -9
  22. package/lib/components/items/EmbedVideoItem/VimeoEmbed.js +24 -24
  23. package/lib/components/items/EmbedVideoItem/YoutubeEmbed.js +27 -27
  24. package/lib/components/items/FileItem/ImageItem.js +40 -40
  25. package/lib/components/items/FileItem/VideoItem.js +64 -64
  26. package/lib/components/items/GroupItem/GroupItem.js +14 -14
  27. package/lib/components/items/Item.js +30 -30
  28. package/lib/components/items/RectangleItem/RectangleItem.js +27 -27
  29. package/lib/components/items/RichTextItem/RichTextItem.js +22 -22
  30. package/lib/utils/RichTextConverter/RichTextConverter.js +21 -21
  31. package/package.json +62 -62
  32. package/src/ItemGeometry/CSSPropertyNameMap.ts +37 -37
  33. package/src/ItemGeometry/GenericGeometryController.ts +59 -59
  34. package/src/ItemGeometry/ItemGeometryContext.ts +4 -4
  35. package/src/ItemGeometry/ItemGeometryController.ts +22 -22
  36. package/src/ItemGeometry/ItemGeometryService.ts +34 -34
  37. package/src/ItemGeometry/RichTextGeometryController.ts +166 -166
  38. package/src/ItemGeometry/useItemGeometry.ts +25 -25
  39. package/src/common/useCurrentLayout.ts +52 -52
  40. package/src/common/useExemplary.ts +9 -9
  41. package/src/common/useItemFXData.ts +63 -63
  42. package/src/common/useKeyframeValue.ts +85 -85
  43. package/src/common/useRegisterResize.ts +16 -16
  44. package/src/components/Article.tsx +69 -69
  45. package/src/components/ArticleWrapper.tsx +21 -21
  46. package/src/components/Head.tsx +95 -95
  47. package/src/components/LayoutStyle.tsx +21 -21
  48. package/src/components/Page.tsx +47 -47
  49. package/src/components/ScrollPlaybackVideo.tsx +75 -75
  50. package/src/components/Section/Section.tsx +162 -162
  51. package/src/components/Section/SectionImage.tsx +48 -48
  52. package/src/components/Section/SectionVideo.tsx +144 -144
  53. package/src/components/Section/useSectionColor.ts +19 -19
  54. package/src/components/Section/useSectionHeightMap.ts +19 -19
  55. package/src/components/StructuredBlockItem/StructuredBlockItem.tsx +69 -69
  56. package/src/components/StructuredBlockItem/StructuredComponent/StructuredComponent.tsx +66 -66
  57. package/src/components/StructuredContent/StructuredContent.tsx +42 -42
  58. package/src/components/items/CodeEmbedItem/CodeEmbedItem.tsx +148 -148
  59. package/src/components/items/CodeEmbedItem/useCodeEmbedItem.ts +36 -36
  60. package/src/components/items/ComponentItem/ComponentItem.tsx +85 -85
  61. package/src/components/items/ComponentItem/useComponentItem.ts +35 -35
  62. package/src/components/items/CompoundItem/CompoundChild.tsx +151 -151
  63. package/src/components/items/CompoundItem/CompoundItem.tsx +88 -88
  64. package/src/components/items/CompoundItem/useCompoundItem.ts +21 -21
  65. package/src/components/items/CustomItem/CustomItem.tsx +50 -50
  66. package/src/components/items/EmbedVideoItem/VimeoEmbed.tsx +217 -217
  67. package/src/components/items/EmbedVideoItem/YoutubeEmbed.tsx +201 -201
  68. package/src/components/items/EmbedVideoItem/useEmbedVideoItem.ts +46 -46
  69. package/src/components/items/FileItem/ImageItem.tsx +166 -166
  70. package/src/components/items/FileItem/VideoItem.tsx +287 -287
  71. package/src/components/items/FileItem/useFileItem.ts +81 -81
  72. package/src/components/items/GroupItem/GroupItem.tsx +99 -99
  73. package/src/components/items/GroupItem/useGroupItem.ts +34 -34
  74. package/src/components/items/Item.tsx +268 -268
  75. package/src/components/items/LinkWrapper.tsx +39 -39
  76. package/src/components/items/RectangleItem/RectangleItem.tsx +177 -177
  77. package/src/components/items/RectangleItem/useRectangleItem.ts +89 -89
  78. package/src/components/items/RichTextItem/RichTextItem.tsx +113 -113
  79. package/src/components/items/RichTextItem/useRichTextItem.ts +12 -12
  80. package/src/components/items/RichTextWrapper.tsx +15 -15
  81. package/src/components/items/itemsMap.ts +28 -28
  82. package/src/components/items/useDraggable.ts +252 -252
  83. package/src/components/items/useItemAngle.ts +13 -13
  84. package/src/components/items/useItemArea.ts +35 -35
  85. package/src/components/items/useItemPointerEvents.ts +23 -23
  86. package/src/components/items/useItemScale.ts +17 -17
  87. package/src/components/items/useItemTriggers.ts +15 -15
  88. package/src/components/items/useRichTextItemValues.ts +66 -66
  89. package/src/components/items/useSizing.ts +25 -25
  90. package/src/components/items/useStickyItemTop.ts +21 -21
  91. package/src/components/useLayoutContext.ts +7 -7
  92. package/src/index.ts +25 -25
  93. package/src/interactions/InteractionsRegistry.ts +513 -513
  94. package/src/interactions/ItemInteractionCtrl.ts +78 -78
  95. package/src/interactions/getTransition.ts +27 -27
  96. package/src/interactions/types.ts +36 -36
  97. package/src/interactions/useItemInteractionCtrl.ts +18 -18
  98. package/src/provider/ArticleRectContext.ts +4 -4
  99. package/src/provider/CntrlContext.ts +5 -5
  100. package/src/provider/CntrlProvider.tsx +11 -11
  101. package/src/provider/CntrlSdkContext.ts +113 -113
  102. package/src/provider/CustomItemRegistry.ts +14 -14
  103. package/src/provider/CustomItemTypes.ts +3 -3
  104. package/src/provider/CustomSectionRegistry.ts +25 -25
  105. package/src/provider/InteractionsContext.tsx +73 -73
  106. package/src/provider/Keyframes.ts +11 -11
  107. package/src/provider/KeyframesContext.ts +5 -5
  108. package/src/provider/LayoutContext.ts +3 -3
  109. package/src/provider/WebGLContextManagerContext.tsx +4 -4
  110. package/src/provider/defaultContext.ts +8 -8
  111. package/src/provider/useCntrlContext.ts +8 -8
  112. package/src/styled-jsx.d.ts +1 -1
  113. package/src/types/components-utils.d.ts +7 -7
  114. package/src/utils/Animator/Animator.ts +570 -570
  115. package/src/utils/ArticleRectManager/ArticleRectObserver.ts +93 -93
  116. package/src/utils/ArticleRectManager/useArticleRectObserver.ts +17 -17
  117. package/src/utils/ArticleRectManager/useSectionRegistry.ts +11 -11
  118. package/src/utils/CSSNumeric.ts +19 -19
  119. package/src/utils/EventEmitter.ts +41 -41
  120. package/src/utils/RichTextConverter/RichTextConverter.tsx +342 -342
  121. package/src/utils/ScaleAnchorMap.ts +13 -13
  122. package/src/utils/StickyManager/StickyManager.ts +23 -23
  123. package/src/utils/Youtube/YouTubeIframeApiLoader.ts +58 -58
  124. package/src/utils/Youtube/YoutubeIframeApi.ts +101 -101
  125. package/src/utils/Youtube/useYouTubeIframeApi.ts +12 -12
  126. package/src/utils/areFillsVisible/areFillsVisible.test.ts +63 -63
  127. package/src/utils/areFillsVisible/areFillsVisible.ts +37 -37
  128. package/src/utils/binSearchInsertAt.ts +33 -33
  129. package/src/utils/castObject.ts +10 -10
  130. package/src/utils/checkOverflowClipSupport.ts +13 -13
  131. package/src/utils/domDfs.ts +11 -11
  132. package/src/utils/effects/useImageFx.ts +154 -154
  133. package/src/utils/effects/useVideoFx.ts +156 -156
  134. package/src/utils/evaluateComponentBundle.ts +83 -83
  135. package/src/utils/getAnchoredItemTop.ts +12 -12
  136. package/src/utils/getCompoundBoundaryStyles.ts +60 -60
  137. package/src/utils/getFill.ts +46 -46
  138. package/src/utils/getFontFamilyValue.ts +3 -3
  139. package/src/utils/getInvertedRanges.ts +43 -43
  140. package/src/utils/getItemTopStyle.ts +39 -39
  141. package/src/utils/getStyleFromItemStateAndParams.ts +8 -8
  142. package/src/utils/getValidYoutubeUrl.ts +29 -29
  143. package/src/utils/isItemType.ts +5 -5
  144. package/src/utils/rangeMap.ts +13 -13
  145. package/src/utils/useElementRect.ts +23 -23
@@ -1,166 +1,166 @@
1
- import { measureFont, Rect } from '@cntrl-site/sdk';
2
- import { ItemGeometryController } from './ItemGeometryController';
3
- import { domDfs } from '../utils/domDfs';
4
- import { formatCSSNumber, parseCSSNumber } from '../utils/CSSNumeric';
5
-
6
- export enum SizingType {
7
- Auto = 'auto',
8
- Manual = 'manual',
9
- }
10
-
11
- interface RichTextGeometryOptions {
12
- xSizing: SizingType;
13
- }
14
-
15
- type GeomtryRegistry = {
16
- getControllerById: (itemId: string) => ItemGeometryController;
17
- };
18
-
19
- export class RichTextGeometryController implements ItemGeometryController {
20
- private scale: number = 1;
21
- private angle: number = 0;
22
- private options!: RichTextGeometryOptions;
23
- private parentId?: string;
24
- private registry: GeomtryRegistry | undefined;
25
- static parseCssValue(value: string) {
26
- const parsedLs = Number.parseInt(value);
27
- return Number.isNaN(parsedLs) ? 0 : parsedLs;
28
- }
29
-
30
- constructor(
31
- private container: HTMLElement
32
- ) { }
33
-
34
- setRegistry(registry: GeomtryRegistry) {
35
- this.registry = registry;
36
- }
37
-
38
- getBoundary(isRotatedBoundary?: boolean): Rect {
39
- const rect = this.container.getBoundingClientRect();
40
- if (isRotatedBoundary) {
41
- return Rect.fromObject(rect);
42
- }
43
- const angle = this.getAngle();
44
- if (angle === 0) return Rect.fromObject(rect);
45
- const styles = getComputedStyle(this.container);
46
- const ratio = Number.parseInt(styles.width) / Number.parseInt(styles.height);
47
- return Rect.getOriginRectFromBoundary(rect, angle, ratio);
48
- }
49
-
50
- getContentGuides(): [boundary: Rect, xs: number[], ys: number[]] {
51
- const boundary = this.getBoundary();
52
- const contentXs: Set<number> = new Set();
53
- const { xSizing } = this.options;
54
- const contentYs: Set<number> = new Set();
55
- domDfs(Array.from(this.container.children), (el) => {
56
- if (el.children.length !== 0) return;
57
- const rects = el.getClientRects();
58
- const styles = window.getComputedStyle(el);
59
- const ls = RichTextGeometryController.parseCssValue(styles.letterSpacing);
60
- const metrics = measureFont(this.getFontStr(styles), el.textContent?.trim() ?? '');
61
- const {
62
- capHeight,
63
- baseline,
64
- fontBoxHeight,
65
- xHeight,
66
- leftMargin,
67
- rightMargin
68
- } = metrics;
69
- for (let i = 0; i <= rects.length - 1; i += 1) {
70
- const rect = rects[i];
71
- const halfLead = (rect.height - fontBoxHeight) / 2;
72
- contentXs.add(rect.left + leftMargin - boundary.left);
73
- contentXs.add(rect.right - rightMargin - ls - boundary.left);
74
- contentYs.add(rect.top + halfLead + baseline - boundary.top); // baseline
75
- if (i === 0) {
76
- contentYs.add(rect.top + halfLead + baseline - capHeight - boundary.top); // cap height
77
- }
78
- if (rects.length === 1) {
79
- contentYs.add(rect.top + halfLead + baseline - xHeight - boundary.top); // x-height
80
- }
81
- }
82
- });
83
- const left = xSizing === SizingType.Auto ? Math.min(...contentXs.values()) : 0;
84
- const right = xSizing === SizingType.Auto ? Math.max(...contentXs.values()) : boundary.width;
85
- const center = left + (right - left) / 2;
86
- return [
87
- boundary,
88
- [left, center, right],
89
- [...Array.from(contentYs.values(), y => y)]
90
- ];
91
- }
92
-
93
- setParentId(parentId?: string) {
94
- this.parentId = parentId;
95
- }
96
-
97
- getParentId(): string | undefined {
98
- return this.parentId;
99
- }
100
-
101
- setScale(scale: number) {
102
- this.scale = scale;
103
- }
104
-
105
- setAngle(angle: number) {
106
- this.angle = angle;
107
- }
108
-
109
- getContentBoundary(): Rect {
110
- if (this.getAngle() !== 0) {
111
- return this.getBoundary(true);
112
- }
113
- const [boundary, xs, ys] = this.getContentGuides();
114
- const left = Math.min(...xs);
115
- const right = Math.max(...xs);
116
-
117
- const top = Math.min(...ys);
118
- const bottom = Math.max(...ys);
119
- const content = new Rect(
120
- boundary.left + left,
121
- boundary.top + top,
122
- right - left,
123
- bottom - top
124
- );
125
- return content;
126
- }
127
-
128
- private getFontStr(styles: CSSStyleDeclaration) {
129
- const fontSize = parseCSSNumber(styles.fontSize);
130
- const lineHeight = parseCSSNumber(styles.lineHeight);
131
- const scaledFontSize = formatCSSNumber({
132
- value: fontSize.value * this.getScale(),
133
- unit: fontSize.unit
134
- });
135
- const scaledLineHeight = formatCSSNumber({
136
- value: lineHeight.value * this.getScale(),
137
- unit: lineHeight.unit
138
- });
139
- return `${scaledFontSize} / ${scaledLineHeight} ${styles.fontFamily}`;
140
- }
141
-
142
- setOptions(options?: RichTextGeometryOptions) {
143
- if (!options) return;
144
- this.options = options;
145
- }
146
-
147
- getAngle(): number {
148
- return this.angle + this.getParentAngle();
149
- }
150
-
151
- getScale() {
152
- return this.scale * this.getParentScale();
153
- }
154
-
155
- private getParentAngle() {
156
- if (!this.registry || !this.parentId) return 0;
157
- const parentController = this.registry.getControllerById(this.parentId);
158
- return parentController.getAngle();
159
- }
160
-
161
- getParentScale(): number {
162
- if (!this.registry || !this.parentId) return 1;
163
- const parentController = this.registry.getControllerById(this.parentId);
164
- return parentController.getScale();
165
- }
166
- }
1
+ import { measureFont, Rect } from '@cntrl-site/sdk';
2
+ import { ItemGeometryController } from './ItemGeometryController';
3
+ import { domDfs } from '../utils/domDfs';
4
+ import { formatCSSNumber, parseCSSNumber } from '../utils/CSSNumeric';
5
+
6
+ export enum SizingType {
7
+ Auto = 'auto',
8
+ Manual = 'manual',
9
+ }
10
+
11
+ interface RichTextGeometryOptions {
12
+ xSizing: SizingType;
13
+ }
14
+
15
+ type GeomtryRegistry = {
16
+ getControllerById: (itemId: string) => ItemGeometryController;
17
+ };
18
+
19
+ export class RichTextGeometryController implements ItemGeometryController {
20
+ private scale: number = 1;
21
+ private angle: number = 0;
22
+ private options!: RichTextGeometryOptions;
23
+ private parentId?: string;
24
+ private registry: GeomtryRegistry | undefined;
25
+ static parseCssValue(value: string) {
26
+ const parsedLs = Number.parseInt(value);
27
+ return Number.isNaN(parsedLs) ? 0 : parsedLs;
28
+ }
29
+
30
+ constructor(
31
+ private container: HTMLElement
32
+ ) { }
33
+
34
+ setRegistry(registry: GeomtryRegistry) {
35
+ this.registry = registry;
36
+ }
37
+
38
+ getBoundary(isRotatedBoundary?: boolean): Rect {
39
+ const rect = this.container.getBoundingClientRect();
40
+ if (isRotatedBoundary) {
41
+ return Rect.fromObject(rect);
42
+ }
43
+ const angle = this.getAngle();
44
+ if (angle === 0) return Rect.fromObject(rect);
45
+ const styles = getComputedStyle(this.container);
46
+ const ratio = Number.parseInt(styles.width) / Number.parseInt(styles.height);
47
+ return Rect.getOriginRectFromBoundary(rect, angle, ratio);
48
+ }
49
+
50
+ getContentGuides(): [boundary: Rect, xs: number[], ys: number[]] {
51
+ const boundary = this.getBoundary();
52
+ const contentXs: Set<number> = new Set();
53
+ const { xSizing } = this.options;
54
+ const contentYs: Set<number> = new Set();
55
+ domDfs(Array.from(this.container.children), (el) => {
56
+ if (el.children.length !== 0) return;
57
+ const rects = el.getClientRects();
58
+ const styles = window.getComputedStyle(el);
59
+ const ls = RichTextGeometryController.parseCssValue(styles.letterSpacing);
60
+ const metrics = measureFont(this.getFontStr(styles), el.textContent?.trim() ?? '');
61
+ const {
62
+ capHeight,
63
+ baseline,
64
+ fontBoxHeight,
65
+ xHeight,
66
+ leftMargin,
67
+ rightMargin
68
+ } = metrics;
69
+ for (let i = 0; i <= rects.length - 1; i += 1) {
70
+ const rect = rects[i];
71
+ const halfLead = (rect.height - fontBoxHeight) / 2;
72
+ contentXs.add(rect.left + leftMargin - boundary.left);
73
+ contentXs.add(rect.right - rightMargin - ls - boundary.left);
74
+ contentYs.add(rect.top + halfLead + baseline - boundary.top); // baseline
75
+ if (i === 0) {
76
+ contentYs.add(rect.top + halfLead + baseline - capHeight - boundary.top); // cap height
77
+ }
78
+ if (rects.length === 1) {
79
+ contentYs.add(rect.top + halfLead + baseline - xHeight - boundary.top); // x-height
80
+ }
81
+ }
82
+ });
83
+ const left = xSizing === SizingType.Auto ? Math.min(...contentXs.values()) : 0;
84
+ const right = xSizing === SizingType.Auto ? Math.max(...contentXs.values()) : boundary.width;
85
+ const center = left + (right - left) / 2;
86
+ return [
87
+ boundary,
88
+ [left, center, right],
89
+ [...Array.from(contentYs.values(), y => y)]
90
+ ];
91
+ }
92
+
93
+ setParentId(parentId?: string) {
94
+ this.parentId = parentId;
95
+ }
96
+
97
+ getParentId(): string | undefined {
98
+ return this.parentId;
99
+ }
100
+
101
+ setScale(scale: number) {
102
+ this.scale = scale;
103
+ }
104
+
105
+ setAngle(angle: number) {
106
+ this.angle = angle;
107
+ }
108
+
109
+ getContentBoundary(): Rect {
110
+ if (this.getAngle() !== 0) {
111
+ return this.getBoundary(true);
112
+ }
113
+ const [boundary, xs, ys] = this.getContentGuides();
114
+ const left = Math.min(...xs);
115
+ const right = Math.max(...xs);
116
+
117
+ const top = Math.min(...ys);
118
+ const bottom = Math.max(...ys);
119
+ const content = new Rect(
120
+ boundary.left + left,
121
+ boundary.top + top,
122
+ right - left,
123
+ bottom - top
124
+ );
125
+ return content;
126
+ }
127
+
128
+ private getFontStr(styles: CSSStyleDeclaration) {
129
+ const fontSize = parseCSSNumber(styles.fontSize);
130
+ const lineHeight = parseCSSNumber(styles.lineHeight);
131
+ const scaledFontSize = formatCSSNumber({
132
+ value: fontSize.value * this.getScale(),
133
+ unit: fontSize.unit
134
+ });
135
+ const scaledLineHeight = formatCSSNumber({
136
+ value: lineHeight.value * this.getScale(),
137
+ unit: lineHeight.unit
138
+ });
139
+ return `${scaledFontSize} / ${scaledLineHeight} ${styles.fontFamily}`;
140
+ }
141
+
142
+ setOptions(options?: RichTextGeometryOptions) {
143
+ if (!options) return;
144
+ this.options = options;
145
+ }
146
+
147
+ getAngle(): number {
148
+ return this.angle + this.getParentAngle();
149
+ }
150
+
151
+ getScale() {
152
+ return this.scale * this.getParentScale();
153
+ }
154
+
155
+ private getParentAngle() {
156
+ if (!this.registry || !this.parentId) return 0;
157
+ const parentController = this.registry.getControllerById(this.parentId);
158
+ return parentController.getAngle();
159
+ }
160
+
161
+ getParentScale(): number {
162
+ if (!this.registry || !this.parentId) return 1;
163
+ const parentController = this.registry.getControllerById(this.parentId);
164
+ return parentController.getScale();
165
+ }
166
+ }
@@ -1,25 +1,25 @@
1
- import { useContext, useEffect, useMemo } from 'react';
2
- import { GenericGeometryController } from './GenericGeometryController';
3
- import { GeometryControllerCtor } from './ItemGeometryController';
4
- import { ItemGeometryContext } from './ItemGeometryContext';
5
-
6
- export function useItemGeometry<T extends GeometryControllerCtor = typeof GenericGeometryController>(
7
- itemId: string,
8
- element?: HTMLElement | null,
9
- // @ts-ignore
10
- controllerCtor: T = GenericGeometryController,
11
- options?: any
12
- ): InstanceType<T> | undefined {
13
- const itemGeometryService = useContext(ItemGeometryContext);
14
- const controller = useMemo(() => {
15
- if (!element) return undefined;
16
- return new controllerCtor(element);
17
- }, [element, controllerCtor]);
18
- useEffect(() => {
19
- if (!controller) return;
20
- controller.setOptions(options);
21
- return itemGeometryService.register(itemId, controller);
22
- }, [itemGeometryService, itemId, controller]);
23
- // @ts-ignore
24
- return controller;
25
- }
1
+ import { useContext, useEffect, useMemo } from 'react';
2
+ import { GenericGeometryController } from './GenericGeometryController';
3
+ import { GeometryControllerCtor } from './ItemGeometryController';
4
+ import { ItemGeometryContext } from './ItemGeometryContext';
5
+
6
+ export function useItemGeometry<T extends GeometryControllerCtor = typeof GenericGeometryController>(
7
+ itemId: string,
8
+ element?: HTMLElement | null,
9
+ // @ts-ignore
10
+ controllerCtor: T = GenericGeometryController,
11
+ options?: any
12
+ ): InstanceType<T> | undefined {
13
+ const itemGeometryService = useContext(ItemGeometryContext);
14
+ const controller = useMemo(() => {
15
+ if (!element) return undefined;
16
+ return new controllerCtor(element);
17
+ }, [element, controllerCtor]);
18
+ useEffect(() => {
19
+ if (!controller) return;
20
+ controller.setOptions(options);
21
+ return itemGeometryService.register(itemId, controller);
22
+ }, [itemGeometryService, itemId, controller]);
23
+ // @ts-ignore
24
+ return controller;
25
+ }
@@ -1,52 +1,52 @@
1
- import { useCntrlContext } from '../provider/useCntrlContext';
2
- import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
3
- import { ArticleRectContext } from '../provider/ArticleRectContext';
4
-
5
- interface LayoutData {
6
- layoutId: string;
7
- exemplary: number;
8
- start: number;
9
- end: number;
10
- }
11
-
12
- type UseCurrentLayoutReturn = {
13
- layoutId: string | undefined;
14
- layoutDeviation: number;
15
- };
16
-
17
- export function useCurrentLayout(): UseCurrentLayoutReturn {
18
- const { layouts } = useCntrlContext();
19
- const articleRectObserver = useContext(ArticleRectContext);
20
- const layoutRanges = useMemo(() => {
21
- const sorted = layouts.slice().sort((la, lb) => la.startsWith - lb.startsWith);
22
- return sorted.reduce<LayoutData[]>((acc, layout, i, layouts) => {
23
- const next = layouts[i + 1];
24
- return [
25
- ...acc,
26
- {
27
- layoutId: layout.id,
28
- exemplary: layout.exemplary,
29
- start: layout.startsWith,
30
- end: next ? next.startsWith : Number.MAX_SAFE_INTEGER
31
- }
32
- ];
33
- }, []);
34
- }, [layouts]);
35
- const getCurrentLayout = useCallback((articleWidth: number) => {
36
- const range = layoutRanges.find(l => articleWidth >= l.start && articleWidth < l.end);
37
- return range;
38
- }, [layoutRanges]);
39
- const [layoutId, setLayoutId] = useState<string | undefined>(undefined);
40
- const [deviation, setDeviation] = useState(1);
41
- useEffect(() => {
42
- if (!articleRectObserver) return;
43
- return articleRectObserver.on('resize', () => {
44
- const articleWidth = articleRectObserver.width;
45
- const { layoutId, exemplary } = getCurrentLayout(articleWidth)!;
46
- setLayoutId(layoutId);
47
- setDeviation(articleWidth / exemplary);
48
- });
49
- }, [articleRectObserver, getCurrentLayout]);
50
-
51
- return { layoutId, layoutDeviation: deviation };
52
- }
1
+ import { useCntrlContext } from '../provider/useCntrlContext';
2
+ import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
3
+ import { ArticleRectContext } from '../provider/ArticleRectContext';
4
+
5
+ interface LayoutData {
6
+ layoutId: string;
7
+ exemplary: number;
8
+ start: number;
9
+ end: number;
10
+ }
11
+
12
+ type UseCurrentLayoutReturn = {
13
+ layoutId: string | undefined;
14
+ layoutDeviation: number;
15
+ };
16
+
17
+ export function useCurrentLayout(): UseCurrentLayoutReturn {
18
+ const { layouts } = useCntrlContext();
19
+ const articleRectObserver = useContext(ArticleRectContext);
20
+ const layoutRanges = useMemo(() => {
21
+ const sorted = layouts.slice().sort((la, lb) => la.startsWith - lb.startsWith);
22
+ return sorted.reduce<LayoutData[]>((acc, layout, i, layouts) => {
23
+ const next = layouts[i + 1];
24
+ return [
25
+ ...acc,
26
+ {
27
+ layoutId: layout.id,
28
+ exemplary: layout.exemplary,
29
+ start: layout.startsWith,
30
+ end: next ? next.startsWith : Number.MAX_SAFE_INTEGER
31
+ }
32
+ ];
33
+ }, []);
34
+ }, [layouts]);
35
+ const getCurrentLayout = useCallback((articleWidth: number) => {
36
+ const range = layoutRanges.find(l => articleWidth >= l.start && articleWidth < l.end);
37
+ return range;
38
+ }, [layoutRanges]);
39
+ const [layoutId, setLayoutId] = useState<string | undefined>(undefined);
40
+ const [deviation, setDeviation] = useState(1);
41
+ useEffect(() => {
42
+ if (!articleRectObserver) return;
43
+ return articleRectObserver.on('resize', () => {
44
+ const articleWidth = articleRectObserver.width;
45
+ const { layoutId, exemplary } = getCurrentLayout(articleWidth)!;
46
+ setLayoutId(layoutId);
47
+ setDeviation(articleWidth / exemplary);
48
+ });
49
+ }, [articleRectObserver, getCurrentLayout]);
50
+
51
+ return { layoutId, layoutDeviation: deviation };
52
+ }
@@ -1,9 +1,9 @@
1
- import { useCntrlContext } from "../provider/useCntrlContext";
2
- import { useLayoutContext } from "../components/useLayoutContext";
3
-
4
- export const useExemplary = () => {
5
- const { layouts } = useCntrlContext();
6
- const layout = useLayoutContext();
7
- const exemplary = layouts.find(l => l.id === layout)?.exemplary ?? 1;
8
- return exemplary;
9
- };
1
+ import { useCntrlContext } from "../provider/useCntrlContext";
2
+ import { useLayoutContext } from "../components/useLayoutContext";
3
+
4
+ export const useExemplary = () => {
5
+ const { layouts } = useCntrlContext();
6
+ const layout = useLayoutContext();
7
+ const exemplary = layouts.find(l => l.id === layout)?.exemplary ?? 1;
8
+ return exemplary;
9
+ };
@@ -1,63 +1,63 @@
1
- import { ImageItem, KeyframeType, VideoItem } from '@cntrl-site/sdk';
2
- import { useKeyframeValue } from './useKeyframeValue';
3
- import { useMemo } from 'react';
4
-
5
- const baseVariables = `precision mediump float;
6
- uniform sampler2D u_image;
7
- uniform vec2 u_imgDimensions;
8
- uniform float u_time;
9
- uniform vec2 u_cursor;
10
- varying vec2 v_texCoord;`;
11
-
12
- export function useItemFXData(item: ImageItem | VideoItem, sectionId: string): FXData {
13
- const { fragmentShader: shaderBody, FXControls, FXTextures } = item.commonParams;
14
- const controls = FXControls ?? [];
15
- const texturesUrls: string[] = useMemo(() => (FXTextures ?? []), [FXTextures]);
16
- const controlsVariables = controls.map((c) => `uniform ${c.type} ${c.shaderParam};`)
17
- .join('\n');
18
- const patternsVariables = texturesUrls
19
- .map((_, i) => `uniform sampler2D ${mediaEffectPatternUniformNames(i).tex};\nuniform vec2 ${mediaEffectPatternUniformNames(i).dim};`)
20
- .join('\n');
21
- const fragmentShader = `${baseVariables}\n${controlsVariables}\n${patternsVariables}\n${shaderBody}`;
22
- const controlsValues = useKeyframeValue(
23
- item,
24
- KeyframeType.FXParams,
25
- () => {
26
- const defaultValue = controls.reduce<Record<string, ControlValue>>((acc, control) => {
27
- if (Array.isArray(control.value)) {
28
- acc[control.shaderParam] = control.value[0];
29
- } else {
30
- acc[control.shaderParam] = control.value;
31
- }
32
- return acc;
33
- }, {});
34
- return defaultValue;
35
- },
36
- (animator, scroll, value) => animator.getFXParams(value, scroll),
37
- sectionId,
38
- );
39
- return {
40
- fragmentShader,
41
- controlsValues,
42
- texturesUrls
43
- };
44
- }
45
-
46
- function mediaEffectPatternUniformNames(slotIndex: number): {
47
- tex: string;
48
- dim: string;
49
- } {
50
- if (slotIndex === 0) {
51
- return { tex: 'u_pattern', dim: 'u_patternDimensions' };
52
- }
53
- const n = slotIndex + 1;
54
- return { tex: `u_pattern${n}`, dim: `u_pattern${n}Dimensions` };
55
- }
56
-
57
- type FXData = {
58
- fragmentShader: string;
59
- controlsValues: Record<string, ControlValue>;
60
- texturesUrls: string[];
61
- }
62
-
63
- type ControlValue = number;
1
+ import { ImageItem, KeyframeType, VideoItem } from '@cntrl-site/sdk';
2
+ import { useKeyframeValue } from './useKeyframeValue';
3
+ import { useMemo } from 'react';
4
+
5
+ const baseVariables = `precision mediump float;
6
+ uniform sampler2D u_image;
7
+ uniform vec2 u_imgDimensions;
8
+ uniform float u_time;
9
+ uniform vec2 u_cursor;
10
+ varying vec2 v_texCoord;`;
11
+
12
+ export function useItemFXData(item: ImageItem | VideoItem, sectionId: string): FXData {
13
+ const { fragmentShader: shaderBody, FXControls, FXTextures } = item.commonParams;
14
+ const controls = FXControls ?? [];
15
+ const texturesUrls: string[] = useMemo(() => (FXTextures ?? []), [FXTextures]);
16
+ const controlsVariables = controls.map((c) => `uniform ${c.type} ${c.shaderParam};`)
17
+ .join('\n');
18
+ const patternsVariables = texturesUrls
19
+ .map((_, i) => `uniform sampler2D ${mediaEffectPatternUniformNames(i).tex};\nuniform vec2 ${mediaEffectPatternUniformNames(i).dim};`)
20
+ .join('\n');
21
+ const fragmentShader = `${baseVariables}\n${controlsVariables}\n${patternsVariables}\n${shaderBody}`;
22
+ const controlsValues = useKeyframeValue(
23
+ item,
24
+ KeyframeType.FXParams,
25
+ () => {
26
+ const defaultValue = controls.reduce<Record<string, ControlValue>>((acc, control) => {
27
+ if (Array.isArray(control.value)) {
28
+ acc[control.shaderParam] = control.value[0];
29
+ } else {
30
+ acc[control.shaderParam] = control.value;
31
+ }
32
+ return acc;
33
+ }, {});
34
+ return defaultValue;
35
+ },
36
+ (animator, scroll, value) => animator.getFXParams(value, scroll),
37
+ sectionId,
38
+ );
39
+ return {
40
+ fragmentShader,
41
+ controlsValues,
42
+ texturesUrls
43
+ };
44
+ }
45
+
46
+ function mediaEffectPatternUniformNames(slotIndex: number): {
47
+ tex: string;
48
+ dim: string;
49
+ } {
50
+ if (slotIndex === 0) {
51
+ return { tex: 'u_pattern', dim: 'u_patternDimensions' };
52
+ }
53
+ const n = slotIndex + 1;
54
+ return { tex: `u_pattern${n}`, dim: `u_pattern${n}Dimensions` };
55
+ }
56
+
57
+ type FXData = {
58
+ fragmentShader: string;
59
+ controlsValues: Record<string, ControlValue>;
60
+ texturesUrls: string[];
61
+ }
62
+
63
+ type ControlValue = number;