zuljaman-banner-components 1.0.23 → 1.0.25

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 (117) hide show
  1. package/README.md +228 -131
  2. package/dist/components/BannerRenderer/BannerRenderer.d.ts +8 -0
  3. package/dist/components/BannerRenderer/BannerRenderer.d.ts.map +1 -0
  4. package/dist/components/BannerRenderer/BannerRenderer.js +325 -0
  5. package/dist/components/BannerRenderer/components/CopyElement.d.ts +62 -0
  6. package/dist/components/BannerRenderer/components/CopyElement.d.ts.map +1 -0
  7. package/dist/components/BannerRenderer/components/CopyElement.js +220 -0
  8. package/dist/components/BannerRenderer/components/InteractiveLines.d.ts +26 -0
  9. package/dist/components/BannerRenderer/components/InteractiveLines.d.ts.map +1 -0
  10. package/dist/components/BannerRenderer/components/InteractiveLines.js +172 -0
  11. package/dist/components/BannerRenderer/components/LogoElement.d.ts +55 -0
  12. package/dist/components/BannerRenderer/components/LogoElement.d.ts.map +1 -0
  13. package/dist/components/BannerRenderer/components/LogoElement.js +53 -0
  14. package/dist/components/BannerRenderer/components/VisualGuides.d.ts +43 -0
  15. package/dist/components/BannerRenderer/components/VisualGuides.d.ts.map +1 -0
  16. package/dist/components/BannerRenderer/components/VisualGuides.js +110 -0
  17. package/dist/components/BannerRenderer/components/index.d.ts +12 -0
  18. package/dist/components/BannerRenderer/components/index.d.ts.map +1 -0
  19. package/dist/components/BannerRenderer/components/index.js +14 -0
  20. package/dist/components/BannerRenderer/constants.d.ts +15 -0
  21. package/dist/components/BannerRenderer/constants.d.ts.map +1 -0
  22. package/dist/components/BannerRenderer/constants.js +36 -0
  23. package/dist/components/BannerRenderer/hooks/index.d.ts +14 -0
  24. package/dist/components/BannerRenderer/hooks/index.d.ts.map +1 -0
  25. package/dist/components/BannerRenderer/hooks/index.js +16 -0
  26. package/dist/components/BannerRenderer/hooks/useAutoPositioning/debugPositions.d.ts +30 -0
  27. package/dist/components/BannerRenderer/hooks/useAutoPositioning/debugPositions.d.ts.map +1 -0
  28. package/dist/components/BannerRenderer/hooks/useAutoPositioning/debugPositions.js +87 -0
  29. package/dist/components/BannerRenderer/hooks/useAutoPositioning/index.d.ts +13 -0
  30. package/dist/components/BannerRenderer/hooks/useAutoPositioning/index.d.ts.map +1 -0
  31. package/dist/components/BannerRenderer/hooks/useAutoPositioning/index.js +21 -0
  32. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAnchorEdgeLocking.d.ts +73 -0
  33. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAnchorEdgeLocking.d.ts.map +1 -0
  34. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAnchorEdgeLocking.js +151 -0
  35. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAutoPositioningMain.d.ts +66 -0
  36. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAutoPositioningMain.d.ts.map +1 -0
  37. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAutoPositioningMain.js +335 -0
  38. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useChainPositioning.d.ts +61 -0
  39. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useChainPositioning.d.ts.map +1 -0
  40. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useChainPositioning.js +180 -0
  41. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useHeightCompensation.d.ts +60 -0
  42. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useHeightCompensation.d.ts.map +1 -0
  43. package/dist/components/BannerRenderer/hooks/useAutoPositioning/useHeightCompensation.js +178 -0
  44. package/dist/components/BannerRenderer/hooks/useAutoPositioning.d.ts +8 -0
  45. package/dist/components/BannerRenderer/hooks/useAutoPositioning.d.ts.map +1 -0
  46. package/dist/components/BannerRenderer/hooks/useAutoPositioning.js +12 -0
  47. package/dist/components/BannerRenderer/hooks/useDragSnap.d.ts +30 -0
  48. package/dist/components/BannerRenderer/hooks/useDragSnap.d.ts.map +1 -0
  49. package/dist/components/BannerRenderer/hooks/useDragSnap.js +90 -0
  50. package/dist/components/BannerRenderer/hooks/useElementRefs.d.ts +22 -0
  51. package/dist/components/BannerRenderer/hooks/useElementRefs.d.ts.map +1 -0
  52. package/dist/components/BannerRenderer/hooks/useElementRefs.js +70 -0
  53. package/dist/components/BannerRenderer/hooks/useLineDrawing.d.ts +40 -0
  54. package/dist/components/BannerRenderer/hooks/useLineDrawing.d.ts.map +1 -0
  55. package/dist/components/BannerRenderer/hooks/useLineDrawing.js +198 -0
  56. package/dist/components/BannerRenderer/hooks/useProximityDetection.d.ts +43 -0
  57. package/dist/components/BannerRenderer/hooks/useProximityDetection.d.ts.map +1 -0
  58. package/dist/components/BannerRenderer/hooks/useProximityDetection.js +491 -0
  59. package/dist/components/BannerRenderer/index.d.ts +6 -0
  60. package/dist/components/BannerRenderer/index.d.ts.map +1 -0
  61. package/dist/components/BannerRenderer/index.js +8 -0
  62. package/dist/components/{BannerRenderer.d.ts → BannerRenderer/types.d.ts} +29 -8
  63. package/dist/components/BannerRenderer/types.d.ts.map +1 -0
  64. package/dist/components/BannerRenderer/types.js +5 -0
  65. package/dist/components/BannerRenderer/utils/alignmentUtils.d.ts +38 -0
  66. package/dist/components/BannerRenderer/utils/alignmentUtils.d.ts.map +1 -0
  67. package/dist/components/BannerRenderer/utils/alignmentUtils.js +138 -0
  68. package/dist/components/BannerRenderer/utils/elementCheckUtils.d.ts +22 -0
  69. package/dist/components/BannerRenderer/utils/elementCheckUtils.d.ts.map +1 -0
  70. package/dist/components/BannerRenderer/utils/elementCheckUtils.js +37 -0
  71. package/dist/components/BannerRenderer/utils/elementIdUtils.d.ts +25 -0
  72. package/dist/components/BannerRenderer/utils/elementIdUtils.d.ts.map +1 -0
  73. package/dist/components/BannerRenderer/utils/elementIdUtils.js +56 -0
  74. package/dist/components/BannerRenderer/utils/fontUtils.d.ts +12 -0
  75. package/dist/components/BannerRenderer/utils/fontUtils.d.ts.map +1 -0
  76. package/dist/components/BannerRenderer/utils/fontUtils.js +26 -0
  77. package/dist/components/BannerRenderer/utils/graphUtils.d.ts +54 -0
  78. package/dist/components/BannerRenderer/utils/graphUtils.d.ts.map +1 -0
  79. package/dist/components/BannerRenderer/utils/graphUtils.js +138 -0
  80. package/dist/components/BannerRenderer/utils/index.d.ts +12 -0
  81. package/dist/components/BannerRenderer/utils/index.d.ts.map +1 -0
  82. package/dist/components/BannerRenderer/utils/index.js +27 -0
  83. package/dist/components/BannerRenderer/utils/snapUtils.d.ts +38 -0
  84. package/dist/components/BannerRenderer/utils/snapUtils.d.ts.map +1 -0
  85. package/dist/components/BannerRenderer/utils/snapUtils.js +109 -0
  86. package/dist/components/BannerVisor.d.ts.map +1 -1
  87. package/dist/components/BannerVisor.js +8 -1
  88. package/dist/components/index.js +1 -1
  89. package/dist/components/shared/DraggableElement.d.ts +11 -0
  90. package/dist/components/shared/DraggableElement.d.ts.map +1 -1
  91. package/dist/components/shared/DraggableElement.js +47 -51
  92. package/dist/components/styles/Style1/substyleConfig.d.ts.map +1 -1
  93. package/dist/components/styles/Style1/substyleConfig.js +53 -54
  94. package/dist/components/styles/Style2/substyleConfig.js +78 -78
  95. package/dist/components/styles/Style3/substyleConfig.d.ts.map +1 -1
  96. package/dist/components/styles/Style3/substyleConfig.js +40 -37
  97. package/dist/components/styles/Style4/substyleConfig.js +57 -57
  98. package/dist/components/styles/types/substyleTypes.d.ts +32 -15
  99. package/dist/components/styles/types/substyleTypes.d.ts.map +1 -1
  100. package/dist/components/styles/utils/chainValidation.d.ts +41 -0
  101. package/dist/components/styles/utils/chainValidation.d.ts.map +1 -0
  102. package/dist/components/styles/utils/chainValidation.js +148 -0
  103. package/dist/components/styles/utils/positioningUtils.d.ts +207 -11
  104. package/dist/components/styles/utils/positioningUtils.d.ts.map +1 -1
  105. package/dist/components/styles/utils/positioningUtils.js +520 -19
  106. package/dist/constants/characterLimits.d.ts +4 -16
  107. package/dist/constants/characterLimits.d.ts.map +1 -1
  108. package/dist/constants/characterLimits.js +28 -26
  109. package/dist/constants/styleConfigs.js +6 -6
  110. package/dist/styleConfig.d.ts +4 -4
  111. package/dist/styleConfig.d.ts.map +1 -1
  112. package/dist/styleConfig.js +8 -16
  113. package/dist/types.d.ts +42 -0
  114. package/dist/types.d.ts.map +1 -1
  115. package/package.json +1 -1
  116. package/dist/components/BannerRenderer.d.ts.map +0 -1
  117. package/dist/components/BannerRenderer.js +0 -559
@@ -1,559 +0,0 @@
1
- "use strict";
2
- /**
3
- * BannerRenderer component - Generic platform-agnostic banner renderer
4
- * Unified component that handles all banner styles based on configuration
5
- */
6
- "use client";
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
- var __importDefault = (this && this.__importDefault) || function (mod) {
41
- return (mod && mod.__esModule) ? mod : { "default": mod };
42
- };
43
- Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.BannerRenderer = void 0;
45
- const jsx_runtime_1 = require("react/jsx-runtime");
46
- const react_1 = __importStar(require("react"));
47
- const clsx_1 = __importDefault(require("clsx"));
48
- const shadowUtils_1 = require("../styles/shadowUtils");
49
- const shared_1 = require("./shared");
50
- const styleConfig_1 = require("../styleConfig");
51
- const defaults_1 = require("../constants/defaults");
52
- const substyleConfig_1 = require("./styles/Style1/substyleConfig");
53
- const substyleConfig_2 = require("./styles/Style2/substyleConfig");
54
- const substyleConfig_3 = require("./styles/Style3/substyleConfig");
55
- const substyleConfig_4 = require("./styles/Style4/substyleConfig");
56
- const positioningUtils_1 = require("./styles/utils/positioningUtils");
57
- const BannerRenderer = ({ bannerStyle, copies = [], bannerSubstyle = 1, logoUrl, sizeMultiplier = 1.0, logoSizeMultiplier = 1.0, overlayIntensityMultiplier: _overlayIntensityMultiplier = 1.0, shadowIntensityMultiplier = 1.0, backgroundImageUrl, postType, ImageComponent, logoTranslateX = 0, logoTranslateY = 0, draggableMode = false, onLogoPositionChange, logoRotation = 0, onLogoRotationChange, logoWidth, onLogoWidthChange, onCopyPositionChange, onCopyRotationChange, onCopyWidthChange, textShadowEnabled, textShadowSize, textShadowIntensity, logoShadowEnabled, logoShadowSize, logoShadowIntensity, noiseEnabled, noiseIntensity = 1.0, fontFamily, }) => {
58
- const [selectedElement, setSelectedElement] = (0, react_1.useState)(null);
59
- // Auto-positioning state and refs
60
- const [autoOffsets, setAutoOffsets] = (0, react_1.useState)({});
61
- const [recalcTrigger, setRecalcTrigger] = (0, react_1.useState)(0);
62
- const logoRef = (0, react_1.useRef)(null);
63
- const copyRefs = (0, react_1.useRef)([]);
64
- const bannerContainerRef = (0, react_1.useRef)(null);
65
- // Live drag position for guide lines
66
- const [liveDragPosition, setLiveDragPosition] = (0, react_1.useState)(null);
67
- // Track if currently dragging
68
- const [isDragging, setIsDragging] = (0, react_1.useState)(false);
69
- // Get substyle configuration based on bannerStyle
70
- const config = (0, react_1.useMemo)(() => {
71
- switch (bannerStyle) {
72
- case 2:
73
- return (0, substyleConfig_2.getSubstyleConfig)(bannerSubstyle);
74
- case 3:
75
- return (0, substyleConfig_3.getSubstyleConfig)(bannerSubstyle);
76
- case 4:
77
- return (0, substyleConfig_4.getSubstyleConfig)(bannerSubstyle);
78
- case 1:
79
- default:
80
- return (0, substyleConfig_1.getSubstyleConfig)(bannerSubstyle);
81
- }
82
- }, [bannerStyle, bannerSubstyle]);
83
- // Get style configuration
84
- const styleConfig = (0, styleConfig_1.getStyleConfig)(bannerStyle);
85
- // Y-axis multiplier for STORY format (to spread elements vertically)
86
- const yMultiplier = postType === "STORY" ? 1.42 : 1.0; // 1920/1350 ≈ 1.42
87
- // Trigger auto-positioning recalculation when style or substyle changes
88
- react_1.default.useEffect(() => {
89
- setRecalcTrigger(prev => prev + 1);
90
- }, [bannerStyle, bannerSubstyle]);
91
- // Calculate font sizes for copies based on their styleSlot and fontSize multiplier
92
- const fontSizes = (0, react_1.useMemo)(() => {
93
- const baseSizeRem = defaults_1.DEFAULT_BASE_FONT_SIZE_REM;
94
- return {
95
- fontSize_01: `${baseSizeRem * (config.fontSize.copy1 || 1.0)}rem`,
96
- fontSize_02: `${baseSizeRem * (config.fontSize.copy2 || 0.65)}rem`,
97
- };
98
- }, [config.fontSize]);
99
- // Convert font weight string to CSS value
100
- const getFontWeight = (weight) => {
101
- switch (weight) {
102
- case 'thin': return '300';
103
- case 'normal': return '400';
104
- case 'bold': return '700';
105
- default: return '400';
106
- }
107
- };
108
- // Reset auto-offsets when config changes (e.g., when changing substyle)
109
- (0, react_1.useEffect)(() => {
110
- setAutoOffsets({});
111
- }, [config]);
112
- // Auto-positioning calculation
113
- (0, react_1.useLayoutEffect)(() => {
114
- // Only calculate if auto-positioning is enabled
115
- if (!config.autoPositioning || !config.autoPositioningConfig) {
116
- return;
117
- }
118
- const { anchorElement, targetElement } = config.autoPositioningConfig;
119
- // Get anchor copy object to check if it's been dragged
120
- let anchorCopy;
121
- if (anchorElement === 'copy1') {
122
- anchorCopy = copies.find(c => c.styleSlot === 0);
123
- }
124
- else if (anchorElement === 'copy2') {
125
- anchorCopy = copies.find(c => c.styleSlot === 1);
126
- }
127
- // Get target copy object to check if it's been dragged
128
- let targetCopy;
129
- if (targetElement === 'copy1') {
130
- targetCopy = copies.find(c => c.styleSlot === 0);
131
- }
132
- else if (targetElement === 'copy2') {
133
- targetCopy = copies.find(c => c.styleSlot === 1);
134
- }
135
- // Check if anchor has been manually dragged
136
- const anchorHasBeenDragged = anchorCopy && ((anchorCopy.translateX !== undefined && anchorCopy.translateX !== 0) ||
137
- (anchorCopy.translateY !== undefined && anchorCopy.translateY !== 0));
138
- // Check if target has been manually dragged
139
- const targetHasBeenDragged = targetCopy && ((targetCopy.translateX !== undefined && targetCopy.translateX !== 0) ||
140
- (targetCopy.translateY !== undefined && targetCopy.translateY !== 0));
141
- // Skip auto-positioning if either anchor or target has been manually positioned
142
- if (anchorHasBeenDragged || targetHasBeenDragged) {
143
- return;
144
- }
145
- // Get anchor element ref
146
- let anchorRef = null;
147
- if (anchorElement === 'logo') {
148
- anchorRef = logoRef.current;
149
- }
150
- else if (anchorElement === 'copy1') {
151
- // Find copy with styleSlot 0 (copy1)
152
- const copy1Index = copies.findIndex(c => c.styleSlot === 0);
153
- if (copy1Index !== -1) {
154
- anchorRef = copyRefs.current[copy1Index];
155
- }
156
- }
157
- else if (anchorElement === 'copy2') {
158
- // Find copy with styleSlot 1 (copy2)
159
- const copy2Index = copies.findIndex(c => c.styleSlot === 1);
160
- if (copy2Index !== -1) {
161
- anchorRef = copyRefs.current[copy2Index];
162
- }
163
- }
164
- // If anchor element doesn't exist, can't calculate
165
- if (!anchorRef) {
166
- return;
167
- }
168
- // Get target element ref
169
- let targetRef = null;
170
- if (targetElement === 'copy1') {
171
- const copy1Index = copies.findIndex(c => c.styleSlot === 0);
172
- if (copy1Index !== -1) {
173
- targetRef = copyRefs.current[copy1Index];
174
- }
175
- }
176
- else if (targetElement === 'copy2') {
177
- const copy2Index = copies.findIndex(c => c.styleSlot === 1);
178
- if (copy2Index !== -1) {
179
- targetRef = copyRefs.current[copy2Index];
180
- }
181
- }
182
- // If target element doesn't exist, can't calculate
183
- if (!targetRef) {
184
- return;
185
- }
186
- // Measure anchor and target heights
187
- const anchorHeight = anchorRef.getBoundingClientRect().height / sizeMultiplier;
188
- const targetHeight = targetRef.getBoundingClientRect().height / sizeMultiplier;
189
- // Determine if anchor has centerOrigin (logo doesn't, copies do)
190
- const anchorHasCenterOrigin = anchorElement !== 'logo';
191
- // Calculate offset
192
- const offset = (0, positioningUtils_1.calculateAutoPositionOffset)(config, config.autoPositioningConfig, anchorHeight, targetHeight, anchorHasCenterOrigin);
193
- // Find target styleSlot
194
- let targetStyleSlot;
195
- if (targetElement === 'copy1') {
196
- targetStyleSlot = 0;
197
- }
198
- else if (targetElement === 'copy2') {
199
- targetStyleSlot = 1;
200
- }
201
- // Update offsets only if changed
202
- if (targetStyleSlot !== undefined) {
203
- setAutoOffsets(prev => {
204
- // Only update if offset has changed significantly (to prevent infinite loops from floating point precision)
205
- const prevOffset = prev[targetStyleSlot] || 0;
206
- const EPSILON = 0.1; // 0.1px tolerance
207
- if (Math.abs(prevOffset - offset) > EPSILON) {
208
- const newOffsets = {
209
- ...prev,
210
- [targetStyleSlot]: offset,
211
- };
212
- return newOffsets;
213
- }
214
- return prev; // No significant change, return same object to prevent re-render
215
- });
216
- }
217
- }, [config, recalcTrigger, copies]); // Recalculate on style/substyle change and when copy text changes (if not dragged)
218
- // Rotation snap function - snaps to 0°, 90°, 180°, 270°
219
- const handleRotationSnap = react_1.default.useCallback((angle) => {
220
- const snapAngles = [0, 90, 180, 270, -90, -180, -270];
221
- const snapThreshold = 3; // degrees
222
- // Normalize angle to -180 to 180 range
223
- let normalized = angle % 360;
224
- if (normalized > 180)
225
- normalized -= 360;
226
- if (normalized < -180)
227
- normalized += 360;
228
- // Check if close to any snap angle
229
- for (const snapAngle of snapAngles) {
230
- if (Math.abs(normalized - snapAngle) < snapThreshold) {
231
- return snapAngle;
232
- }
233
- }
234
- return normalized;
235
- }, []);
236
- // Shadow calculations using style configuration
237
- const { shadowStyle, logoShadowStyle } = (0, react_1.useMemo)(() => {
238
- var _a, _b;
239
- // Get shadow defaults from style config (or use fallback values)
240
- const textShadowConfig = ((_a = styleConfig.shadows) === null || _a === void 0 ? void 0 : _a.textShadow) || {
241
- enabled: true,
242
- size: 70,
243
- intensity: 0.85,
244
- direction: 'bottom',
245
- };
246
- const logoShadowConfig = ((_b = styleConfig.shadows) === null || _b === void 0 ? void 0 : _b.logoShadow) || {
247
- enabled: true,
248
- size: 150,
249
- intensity: 0.375,
250
- direction: 'top-left',
251
- };
252
- // Use prop overrides if provided, otherwise use config values
253
- const effectiveTextShadowEnabled = textShadowEnabled !== null && textShadowEnabled !== void 0 ? textShadowEnabled : textShadowConfig.enabled;
254
- const effectiveTextShadowSize = textShadowSize !== null && textShadowSize !== void 0 ? textShadowSize : textShadowConfig.size;
255
- const effectiveTextShadowIntensity = textShadowIntensity !== null && textShadowIntensity !== void 0 ? textShadowIntensity : textShadowConfig.intensity;
256
- const effectiveLogoShadowEnabled = logoShadowEnabled !== null && logoShadowEnabled !== void 0 ? logoShadowEnabled : logoShadowConfig.enabled;
257
- const effectiveLogoShadowSize = logoShadowSize !== null && logoShadowSize !== void 0 ? logoShadowSize : logoShadowConfig.size;
258
- const effectiveLogoShadowIntensity = logoShadowIntensity !== null && logoShadowIntensity !== void 0 ? logoShadowIntensity : logoShadowConfig.intensity;
259
- // Generate shadow styles only if enabled
260
- const shadowStyle = effectiveTextShadowEnabled
261
- ? (0, shadowUtils_1.createAbstractShadowStyle)({
262
- direction: textShadowConfig.direction,
263
- size: `${effectiveTextShadowSize}%`,
264
- intensity: effectiveTextShadowIntensity * shadowIntensityMultiplier,
265
- })
266
- : {};
267
- const logoShadowStyle = effectiveLogoShadowEnabled
268
- ? (0, shadowUtils_1.createAbstractShadowStyle)({
269
- direction: logoShadowConfig.direction,
270
- size: `${effectiveLogoShadowSize}%`,
271
- intensity: effectiveLogoShadowIntensity * shadowIntensityMultiplier,
272
- })
273
- : {};
274
- return { shadowStyle, logoShadowStyle };
275
- }, [
276
- styleConfig.shadows,
277
- textShadowEnabled,
278
- textShadowSize,
279
- textShadowIntensity,
280
- logoShadowEnabled,
281
- logoShadowSize,
282
- logoShadowIntensity,
283
- shadowIntensityMultiplier,
284
- ]);
285
- // Shared logo component
286
- const logoComponent = ((0, jsx_runtime_1.jsx)(shared_1.DraggableElement, { enabled: draggableMode, position: { x: logoTranslateX, y: logoTranslateY }, rotation: logoRotation, width: logoWidth, scale: sizeMultiplier, elementId: "logo", isSelected: selectedElement === "logo", onPositionChange: (pos) => {
287
- // Clear dragging state when drag ends
288
- setIsDragging(false);
289
- setLiveDragPosition(null);
290
- onLogoPositionChange === null || onLogoPositionChange === void 0 ? void 0 : onLogoPositionChange(pos);
291
- }, onRotationChange: onLogoRotationChange, onWidthChange: onLogoWidthChange, onSelect: (id) => setSelectedElement(id), onDeselect: () => {
292
- setSelectedElement(null);
293
- setLiveDragPosition(null);
294
- setIsDragging(false);
295
- }, onRotationSnap: handleRotationSnap, onDragMove: (elementId, bounds) => {
296
- // Set dragging state to true
297
- setIsDragging(true);
298
- // Calculate live position from element bounds
299
- if (!bannerContainerRef.current)
300
- return;
301
- const bannerBounds = bannerContainerRef.current.getBoundingClientRect();
302
- const elementCenterX = bounds.left + bounds.width / 2;
303
- const elementCenterY = bounds.top + bounds.height / 2;
304
- // Banner center in viewport coordinates
305
- const bannerCenterX = bannerBounds.left + bannerBounds.width / 2;
306
- const bannerCenterY = bannerBounds.top + bannerBounds.height / 2;
307
- // Calculate offset from banner center (in scaled pixels)
308
- const offsetX = (elementCenterX - bannerCenterX) / sizeMultiplier;
309
- const offsetY = (elementCenterY - bannerCenterY) / sizeMultiplier;
310
- // Store the live position
311
- setLiveDragPosition({
312
- elementId,
313
- x: offsetX,
314
- y: offsetY,
315
- });
316
- }, children: (0, jsx_runtime_1.jsx)("div", { ref: logoRef, className: "relative", style: {
317
- width: logoWidth ? `${logoWidth}px` : `${defaults_1.DEFAULT_LOGO_SIZE_REM * logoSizeMultiplier}rem`,
318
- height: logoWidth ? `${logoWidth}px` : `${defaults_1.DEFAULT_LOGO_SIZE_REM * logoSizeMultiplier}rem`,
319
- // Remove transform - DraggableElement already handles positioning
320
- }, children: logoUrl && ((0, jsx_runtime_1.jsx)(ImageComponent, { src: logoUrl, alt: "Logo", width: 256, height: 256, className: "object-contain absolute inset-0 w-full h-full", style: { objectFit: "contain", pointerEvents: "none" } })) }) }));
321
- // Function to render a copy component by styleSlot
322
- // Function to render a copy component with absolute positioning
323
- const renderCopyComponent = (copy) => {
324
- var _a, _b, _c, _d;
325
- // Use styleSlot to determine config (0 = copy1, 1 = copy2)
326
- const styleSlot = copy.styleSlot !== undefined ? copy.styleSlot : 0;
327
- // Determine if this is a styled copy (copy1 or copy2) vs overflow copy
328
- const isStyled = styleSlot === 0 || styleSlot === 1;
329
- // Get copy config, with fallback for styles that don't have copy2
330
- const copyConfig = styleSlot === 0
331
- ? config.copy1
332
- : ('copy2' in config ? config.copy2 : config.copy1);
333
- // Get config position and width
334
- const configX = (_a = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.x) !== null && _a !== void 0 ? _a : 0;
335
- const configY = (_b = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.y) !== null && _b !== void 0 ? _b : 0;
336
- const configWidth = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.width;
337
- const autoOffset = autoOffsets[styleSlot] || 0;
338
- // Get the font size multiplier from copy config (used for both font size and padding scaling)
339
- const copyFontSizeMultiplier = copy.fontSize || 1.0;
340
- // Calculate font size
341
- // copy.fontSize is now an absolute multiplier, not relative to config
342
- // Config fontSize values only set the initial copy.fontSize value
343
- const effectiveFontSize = `${defaults_1.DEFAULT_BASE_FONT_SIZE_REM * copyFontSizeMultiplier}rem`;
344
- // Get alignment - always prioritize copy's own align property
345
- const effectiveAlign = copy.align || (isStyled && copyConfig ? copyConfig.alignment : 'center');
346
- // Get font weight - use copy's fontWeight, then config default, then fallback
347
- const effectiveFontWeight = copy.fontWeight || (isStyled ? (styleSlot === 0 ? (styleConfig.copy1FontWeight || 'bold') : (styleConfig.copy2FontWeight || 'normal')) : 'normal');
348
- // Get font family - prioritize copy's own fontFamily, then global override, then style config
349
- const effectiveCopyFontFamily = copy.fontFamily || fontFamily || styleConfig.fontFamily;
350
- // Get color properties - prioritize copy's own properties, then substyle config, then defaults
351
- const effectiveColor = copy.color || (isStyled && copyConfig ? copyConfig.color : undefined) || 'white';
352
- const effectiveBgColor = copy.bgColor || (isStyled && copyConfig ? copyConfig.bgColor : undefined);
353
- const effectiveHasBg = copy.hasBg !== undefined ? copy.hasBg : (isStyled && copyConfig ? copyConfig.hasBg : false);
354
- // Get padding and scale it proportionally with font size to maintain visual consistency
355
- const basePaddingX = copy.paddingX || (isStyled && copyConfig ? copyConfig.paddingX : undefined);
356
- const basePaddingY = copy.paddingY || (isStyled && copyConfig ? copyConfig.paddingY : undefined);
357
- const effectivePaddingX = basePaddingX
358
- ? `${parseFloat(basePaddingX.replace('rem', '')) * copyFontSizeMultiplier}rem`
359
- : undefined;
360
- const effectivePaddingY = basePaddingY
361
- ? `${parseFloat(basePaddingY.replace('rem', '')) * copyFontSizeMultiplier}rem`
362
- : undefined;
363
- const effectiveBorderRadius = copy.borderRadius || (isStyled && copyConfig ? copyConfig.borderRadius : undefined);
364
- // Apply text decoration styles
365
- const textDecorationStyles = [];
366
- if (copy.underline)
367
- textDecorationStyles.push('underline');
368
- const textDecoration = textDecorationStyles.length > 0 ? textDecorationStyles.join(' ') : 'none';
369
- // Apply font style
370
- const fontStyle = copy.italic ? 'italic' : 'normal';
371
- // Apply additional bold if textBold is true (combines with fontWeight)
372
- const finalFontWeight = copy.textBold
373
- ? 'bold'
374
- : getFontWeight(effectiveFontWeight);
375
- // Text element
376
- const textElement = ((0, jsx_runtime_1.jsx)("p", { style: {
377
- fontSize: effectiveFontSize,
378
- fontWeight: finalFontWeight,
379
- fontFamily: effectiveCopyFontFamily,
380
- color: effectiveColor,
381
- textDecoration,
382
- fontStyle,
383
- }, className: (0, clsx_1.default)("whitespace-pre-wrap", `text-${effectiveAlign}`), children: copy.text }));
384
- // Wrap with background if needed
385
- const contentElement = effectiveHasBg ? ((0, jsx_runtime_1.jsx)("div", { style: {
386
- backgroundColor: effectiveBgColor,
387
- paddingLeft: effectivePaddingX,
388
- paddingRight: effectivePaddingX,
389
- paddingTop: effectivePaddingY,
390
- paddingBottom: effectivePaddingY,
391
- borderRadius: effectiveBorderRadius,
392
- display: 'inline-block',
393
- }, children: textElement })) : textElement;
394
- // Calculate final position: config position + auto-offset + user adjustment
395
- const baseX = isStyled ? configX : 0;
396
- const baseY = isStyled ? (configY * yMultiplier + autoOffset) : 0;
397
- const finalX = baseX + (copy.translateX || 0);
398
- const finalY = baseY + (copy.translateY || 0);
399
- const finalWidth = copy.width || configWidth;
400
- const finalRotation = (_c = copy.rotation) !== null && _c !== void 0 ? _c : (isStyled ? ((_d = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.rotation) !== null && _d !== void 0 ? _d : 0) : 0);
401
- return ((0, jsx_runtime_1.jsx)(shared_1.DraggableElement, { enabled: draggableMode, position: { x: finalX, y: finalY }, rotation: finalRotation, width: finalWidth, scale: sizeMultiplier, elementId: `copy-${copy.id}`, isSelected: selectedElement === `copy-${copy.id}`, centerOrigin: true, onPositionChange: (pos) => {
402
- // Clear live drag position and dragging state when drag ends
403
- setLiveDragPosition(null);
404
- setIsDragging(false);
405
- // Subtract base position to get only user adjustment
406
- const adjustedPos = {
407
- x: pos.x - baseX,
408
- y: pos.y - baseY,
409
- };
410
- // Find index of this copy in the copies array to call the callback
411
- const copyIndex = copies.findIndex(c => c.id === copy.id);
412
- if (copyIndex !== -1) {
413
- onCopyPositionChange === null || onCopyPositionChange === void 0 ? void 0 : onCopyPositionChange(copyIndex, adjustedPos);
414
- }
415
- }, onRotationChange: (rot) => {
416
- const copyIndex = copies.findIndex(c => c.id === copy.id);
417
- if (copyIndex !== -1) {
418
- onCopyRotationChange === null || onCopyRotationChange === void 0 ? void 0 : onCopyRotationChange(copyIndex, rot);
419
- }
420
- }, onWidthChange: (w) => {
421
- const copyIndex = copies.findIndex(c => c.id === copy.id);
422
- if (copyIndex !== -1) {
423
- onCopyWidthChange === null || onCopyWidthChange === void 0 ? void 0 : onCopyWidthChange(copyIndex, w);
424
- }
425
- }, onSelect: (id) => setSelectedElement(id), onDeselect: () => {
426
- setSelectedElement(null);
427
- setLiveDragPosition(null);
428
- }, onRotationSnap: handleRotationSnap, onDragMove: (elementId, bounds) => {
429
- // Set dragging state to true
430
- setIsDragging(true);
431
- // Calculate live position from element bounds
432
- if (!bannerContainerRef.current)
433
- return;
434
- const bannerBounds = bannerContainerRef.current.getBoundingClientRect();
435
- const elementCenterX = bounds.left + bounds.width / 2;
436
- const elementCenterY = bounds.top + bounds.height / 2;
437
- // Banner center in viewport coordinates
438
- const bannerCenterX = bannerBounds.left + bannerBounds.width / 2;
439
- const bannerCenterY = bannerBounds.top + bannerBounds.height / 2;
440
- // Calculate offset from banner center (in scaled pixels)
441
- const offsetX = (elementCenterX - bannerCenterX) / sizeMultiplier;
442
- const offsetY = (elementCenterY - bannerCenterY) / sizeMultiplier;
443
- // Store the live position
444
- setLiveDragPosition({
445
- elementId,
446
- x: offsetX,
447
- y: offsetY,
448
- });
449
- }, children: (0, jsx_runtime_1.jsx)("div", { ref: (el) => {
450
- // Store ref by styleSlot for auto-positioning
451
- if (styleSlot === 0)
452
- copyRefs.current[0] = el;
453
- else if (styleSlot === 1)
454
- copyRefs.current[1] = el;
455
- }, style: {
456
- // Remove transform - DraggableElement already handles positioning and rotation
457
- width: '100%',
458
- // Hide copy if hidden property is true
459
- display: copy.hidden ? 'none' : undefined,
460
- }, children: contentElement }) }, copy.id));
461
- };
462
- return ((0, jsx_runtime_1.jsx)("div", { className: "w-full h-full text-white leading-[1.05]", children: (0, jsx_runtime_1.jsxs)("div", { ref: bannerContainerRef, className: (0, clsx_1.default)("inset-0 flex flex-col items-start h-full relative isolate overflow-hidden gap-4 px-20", postType === "STORY" ? "pb-32 pt-44" : "py-20"), children: [backgroundImageUrl && ((0, jsx_runtime_1.jsx)(ImageComponent, { src: backgroundImageUrl, alt: "Background", width: 1080, height: postType === "STORY" ? 1920 : 1350, className: "object-cover absolute inset-0 w-full h-full -z-10", style: { objectFit: "cover", pointerEvents: "none" } })), noiseEnabled && ((0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 pointer-events-none", style: {
463
- opacity: Math.min(noiseIntensity / 2, 1), // Normalize 0-2 range to 0-1
464
- mixBlendMode: 'overlay',
465
- backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E")`,
466
- zIndex: 5,
467
- } })), (0, jsx_runtime_1.jsx)("div", { style: shadowStyle, className: "relative z-10", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("div", { style: logoShadowStyle, className: "relative z-10", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("div", { className: "absolute z-20", style: {
468
- top: '50%',
469
- left: '50%',
470
- transform: `translate(${config.logo.x}px, ${config.logo.y * yMultiplier}px)`,
471
- }, children: logoComponent }), draggableMode && isDragging && selectedElement && (() => {
472
- var _a, _b;
473
- let displayX = 0;
474
- let displayY = 0;
475
- if (selectedElement === 'logo') {
476
- // Logo position
477
- const finalX = logoTranslateX;
478
- const finalY = logoTranslateY;
479
- // Use live drag position if available, otherwise use final position
480
- displayX = liveDragPosition && liveDragPosition.elementId === selectedElement
481
- ? liveDragPosition.x
482
- : finalX;
483
- displayY = liveDragPosition && liveDragPosition.elementId === selectedElement
484
- ? liveDragPosition.y
485
- : finalY;
486
- }
487
- else if (selectedElement.startsWith('copy-')) {
488
- // Copy position
489
- const selectedCopyId = selectedElement.replace('copy-', '');
490
- const selectedCopy = copies.find(c => c.id === selectedCopyId);
491
- if (!selectedCopy)
492
- return null;
493
- // Calculate position for selected copy
494
- const styleSlot = selectedCopy.styleSlot !== undefined ? selectedCopy.styleSlot : 0;
495
- const isStyled = styleSlot === 0 || styleSlot === 1;
496
- const copyConfig = styleSlot === 0
497
- ? config.copy1
498
- : ('copy2' in config ? config.copy2 : config.copy1);
499
- const configX = (_a = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.x) !== null && _a !== void 0 ? _a : 0;
500
- const configY = (_b = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.y) !== null && _b !== void 0 ? _b : 0;
501
- const autoOffset = autoOffsets[styleSlot] || 0;
502
- const baseX = isStyled ? configX : 0;
503
- const baseY = isStyled ? (configY * yMultiplier + autoOffset) : 0;
504
- const finalX = baseX + (selectedCopy.translateX || 0);
505
- const finalY = baseY + (selectedCopy.translateY || 0);
506
- // Use live drag position if available, otherwise use final position
507
- displayX = liveDragPosition && liveDragPosition.elementId === selectedElement
508
- ? liveDragPosition.x
509
- : finalX;
510
- displayY = liveDragPosition && liveDragPosition.elementId === selectedElement
511
- ? liveDragPosition.y
512
- : finalY;
513
- }
514
- else {
515
- return null;
516
- }
517
- // Threshold for considering element "centered" (in pixels)
518
- const CENTER_THRESHOLD = 5;
519
- // Check if element is centered on each axis
520
- const isCenteredHorizontally = Math.abs(displayX) <= CENTER_THRESHOLD;
521
- const isCenteredVertically = Math.abs(displayY) <= CENTER_THRESHOLD;
522
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isCenteredHorizontally && ((0, jsx_runtime_1.jsx)("div", { className: "absolute pointer-events-none", style: {
523
- left: '50%',
524
- top: 0,
525
- bottom: 0,
526
- width: '6px',
527
- backgroundColor: 'rgb(125, 211, 252)', // sky-300
528
- transform: `translateX(${displayX - 3}px)`, // -3px to center the 6px line
529
- zIndex: 5,
530
- } })), isCenteredVertically && ((0, jsx_runtime_1.jsx)("div", { className: "absolute pointer-events-none", style: {
531
- top: '50%',
532
- left: 0,
533
- right: 0,
534
- height: '6px',
535
- backgroundColor: 'rgb(125, 211, 252)', // sky-300
536
- transform: `translateY(${displayY - 3}px)`, // -3px to center the 6px line
537
- zIndex: 5,
538
- } }))] }));
539
- })(), (0, jsx_runtime_1.jsx)("div", { className: "absolute pointer-events-none", style: {
540
- top: '50%',
541
- left: '50%',
542
- width: 0,
543
- height: 0,
544
- zIndex: 10,
545
- }, children: copies.map((copy) => {
546
- // Get width from config for the wrapper
547
- const styleSlot = copy.styleSlot !== undefined ? copy.styleSlot : 0;
548
- const copyConfig = styleSlot === 0
549
- ? config.copy1
550
- : ('copy2' in config ? config.copy2 : config.copy1);
551
- const configWidth = copy.width || (copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.width);
552
- return ((0, jsx_runtime_1.jsx)("div", { className: "pointer-events-auto absolute", style: {
553
- top: '50%',
554
- left: '50%',
555
- width: configWidth,
556
- }, children: renderCopyComponent(copy) }, copy.id));
557
- }) })] }) }));
558
- };
559
- exports.BannerRenderer = BannerRenderer;