zuljaman-banner-components 1.0.6 → 1.0.7

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 (98) hide show
  1. package/dist/components/BannerRenderer.d.ts +48 -0
  2. package/dist/components/BannerRenderer.d.ts.map +1 -0
  3. package/dist/components/BannerRenderer.js +449 -0
  4. package/dist/components/BannerVisor.d.ts.map +1 -1
  5. package/dist/components/BannerVisor.js +132 -18
  6. package/dist/components/index.d.ts +1 -2
  7. package/dist/components/index.d.ts.map +1 -1
  8. package/dist/components/index.js +4 -2
  9. package/dist/components/shared/DraggableElement.d.ts +31 -0
  10. package/dist/components/shared/DraggableElement.d.ts.map +1 -0
  11. package/dist/components/shared/DraggableElement.js +367 -0
  12. package/dist/components/shared/index.d.ts +7 -0
  13. package/dist/components/shared/index.d.ts.map +1 -0
  14. package/dist/components/shared/index.js +9 -0
  15. package/dist/components/styles/Style1/substyleConfig.d.ts +20 -0
  16. package/dist/components/styles/Style1/substyleConfig.d.ts.map +1 -0
  17. package/dist/components/styles/Style1/substyleConfig.js +105 -0
  18. package/dist/components/styles/Style2/substyleConfig.d.ts +20 -0
  19. package/dist/components/styles/Style2/substyleConfig.d.ts.map +1 -0
  20. package/dist/components/styles/Style2/substyleConfig.js +133 -0
  21. package/dist/components/styles/Style3/substyleConfig.d.ts +20 -0
  22. package/dist/components/styles/Style3/substyleConfig.d.ts.map +1 -0
  23. package/dist/components/styles/Style3/substyleConfig.js +91 -0
  24. package/dist/components/styles/Style4/substyleConfig.d.ts +20 -0
  25. package/dist/components/styles/Style4/substyleConfig.d.ts.map +1 -0
  26. package/dist/components/styles/Style4/substyleConfig.js +112 -0
  27. package/dist/components/styles/types/substyleTypes.d.ts +68 -0
  28. package/dist/components/styles/types/substyleTypes.d.ts.map +1 -0
  29. package/dist/components/styles/types/substyleTypes.js +6 -0
  30. package/dist/components/styles/utils/calculations.d.ts +47 -0
  31. package/dist/components/styles/utils/calculations.d.ts.map +1 -0
  32. package/dist/components/styles/utils/calculations.js +69 -0
  33. package/dist/components/styles/utils/defaultsUtils.d.ts +54 -0
  34. package/dist/components/styles/utils/defaultsUtils.d.ts.map +1 -0
  35. package/dist/components/styles/utils/defaultsUtils.js +83 -0
  36. package/dist/components/styles/utils/fontSizeUtils.d.ts +32 -0
  37. package/dist/components/styles/utils/fontSizeUtils.d.ts.map +1 -0
  38. package/dist/components/styles/utils/fontSizeUtils.js +52 -0
  39. package/dist/components/styles/utils/positioningUtils.d.ts +38 -0
  40. package/dist/components/styles/utils/positioningUtils.d.ts.map +1 -0
  41. package/dist/components/styles/utils/positioningUtils.js +79 -0
  42. package/dist/components/styles/utils/substyleUtils.d.ts +14 -0
  43. package/dist/components/styles/utils/substyleUtils.d.ts.map +1 -0
  44. package/dist/components/styles/utils/substyleUtils.js +18 -0
  45. package/dist/components/styles/utils/transformUtils.d.ts +36 -0
  46. package/dist/components/styles/utils/transformUtils.d.ts.map +1 -0
  47. package/dist/components/styles/utils/transformUtils.js +53 -0
  48. package/dist/constants/characterLimits.d.ts +97 -0
  49. package/dist/constants/characterLimits.d.ts.map +1 -0
  50. package/dist/constants/characterLimits.js +144 -0
  51. package/dist/constants/defaults.d.ts +19 -0
  52. package/dist/constants/defaults.d.ts.map +1 -0
  53. package/dist/constants/defaults.js +27 -0
  54. package/dist/constants/index.d.ts +2 -0
  55. package/dist/constants/index.d.ts.map +1 -1
  56. package/dist/constants/index.js +2 -0
  57. package/dist/constants/styleConfigs.d.ts.map +1 -1
  58. package/dist/constants/styleConfigs.js +13 -7
  59. package/dist/index.d.ts +8 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +12 -0
  62. package/dist/styleConfig.d.ts +40 -0
  63. package/dist/styleConfig.d.ts.map +1 -0
  64. package/dist/styleConfig.js +115 -0
  65. package/dist/styles/shadowUtils.js +4 -4
  66. package/dist/types.d.ts +149 -1
  67. package/dist/types.d.ts.map +1 -1
  68. package/package.json +10 -9
  69. package/dist/components/Style1/BannerStyle1.d.ts +0 -19
  70. package/dist/components/Style1/BannerStyle1.d.ts.map +0 -1
  71. package/dist/components/Style1/BannerStyle1.js +0 -27
  72. package/dist/components/Style1/substyles/BannerSubstyle1.d.ts +0 -12
  73. package/dist/components/Style1/substyles/BannerSubstyle1.d.ts.map +0 -1
  74. package/dist/components/Style1/substyles/BannerSubstyle1.js +0 -52
  75. package/dist/components/Style1/substyles/BannerSubstyle2.d.ts +0 -12
  76. package/dist/components/Style1/substyles/BannerSubstyle2.d.ts.map +0 -1
  77. package/dist/components/Style1/substyles/BannerSubstyle2.js +0 -52
  78. package/dist/components/Style1/substyles/BannerSubstyle3.d.ts +0 -12
  79. package/dist/components/Style1/substyles/BannerSubstyle3.d.ts.map +0 -1
  80. package/dist/components/Style1/substyles/BannerSubstyle3.js +0 -61
  81. package/dist/components/Style1/substyles/index.d.ts +0 -7
  82. package/dist/components/Style1/substyles/index.d.ts.map +0 -1
  83. package/dist/components/Style1/substyles/index.js +0 -22
  84. package/dist/components/Style2/BannerStyle2.d.ts +0 -19
  85. package/dist/components/Style2/BannerStyle2.d.ts.map +0 -1
  86. package/dist/components/Style2/BannerStyle2.js +0 -32
  87. package/dist/components/Style2/substyles/BannerSubstyle1.d.ts +0 -12
  88. package/dist/components/Style2/substyles/BannerSubstyle1.d.ts.map +0 -1
  89. package/dist/components/Style2/substyles/BannerSubstyle1.js +0 -35
  90. package/dist/components/Style2/substyles/BannerSubstyle2.d.ts +0 -12
  91. package/dist/components/Style2/substyles/BannerSubstyle2.d.ts.map +0 -1
  92. package/dist/components/Style2/substyles/BannerSubstyle2.js +0 -35
  93. package/dist/components/Style2/substyles/BannerSubstyle3.d.ts +0 -12
  94. package/dist/components/Style2/substyles/BannerSubstyle3.d.ts.map +0 -1
  95. package/dist/components/Style2/substyles/BannerSubstyle3.js +0 -35
  96. package/dist/components/Style2/substyles/index.d.ts +0 -7
  97. package/dist/components/Style2/substyles/index.d.ts.map +0 -1
  98. package/dist/components/Style2/substyles/index.js +0 -22
@@ -0,0 +1,48 @@
1
+ /**
2
+ * BannerRenderer component - Generic platform-agnostic banner renderer
3
+ * Unified component that handles all banner styles based on configuration
4
+ */
5
+ import React from "react";
6
+ import type { ImageProps, CopyConfig } from "../types";
7
+ interface BannerRendererProps {
8
+ bannerStyle: number;
9
+ copies?: CopyConfig[];
10
+ bannerSubstyle?: number;
11
+ logoUrl?: string;
12
+ sizeMultiplier?: number;
13
+ logoSizeMultiplier?: number;
14
+ overlayIntensityMultiplier?: number;
15
+ shadowIntensityMultiplier?: number;
16
+ backgroundImageUrl?: string;
17
+ postType?: string;
18
+ ImageComponent: React.ComponentType<ImageProps>;
19
+ logoTranslateX?: number;
20
+ logoTranslateY?: number;
21
+ logoRotation?: number;
22
+ logoWidth?: number;
23
+ textShadowEnabled?: boolean;
24
+ textShadowSize?: number;
25
+ textShadowIntensity?: number;
26
+ logoShadowEnabled?: boolean;
27
+ logoShadowSize?: number;
28
+ logoShadowIntensity?: number;
29
+ noiseEnabled?: boolean;
30
+ noiseIntensity?: number;
31
+ fontFamily?: string;
32
+ draggableMode?: boolean;
33
+ onLogoPositionChange?: (position: {
34
+ x: number;
35
+ y: number;
36
+ }) => void;
37
+ onLogoRotationChange?: (rotation: number) => void;
38
+ onLogoWidthChange?: (width: number) => void;
39
+ onCopyPositionChange?: (copyIndex: number, position: {
40
+ x: number;
41
+ y: number;
42
+ }) => void;
43
+ onCopyRotationChange?: (copyIndex: number, rotation: number) => void;
44
+ onCopyWidthChange?: (copyIndex: number, width: number) => void;
45
+ }
46
+ export declare const BannerRenderer: React.FC<BannerRendererProps>;
47
+ export {};
48
+ //# sourceMappingURL=BannerRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BannerRenderer.d.ts","sourceRoot":"","sources":["../../src/components/BannerRenderer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAgE,MAAM,OAAO,CAAC;AAGrF,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAUvD,UAAU,mBAAmB;IAE3B,WAAW,EAAE,MAAM,CAAC;IAGpB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IAEtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAGhD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAG7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACpE,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAG5C,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvF,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAChE;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA4lBxD,CAAC"}
@@ -0,0 +1,449 @@
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
+ // Get substyle configuration based on bannerStyle
65
+ const config = (0, react_1.useMemo)(() => {
66
+ switch (bannerStyle) {
67
+ case 2:
68
+ return (0, substyleConfig_2.getSubstyleConfig)(bannerSubstyle);
69
+ case 3:
70
+ return (0, substyleConfig_3.getSubstyleConfig)(bannerSubstyle);
71
+ case 4:
72
+ return (0, substyleConfig_4.getSubstyleConfig)(bannerSubstyle);
73
+ case 1:
74
+ default:
75
+ return (0, substyleConfig_1.getSubstyleConfig)(bannerSubstyle);
76
+ }
77
+ }, [bannerStyle, bannerSubstyle]);
78
+ // Get style configuration
79
+ const styleConfig = (0, styleConfig_1.getStyleConfig)(bannerStyle);
80
+ // Trigger auto-positioning recalculation when style or substyle changes
81
+ react_1.default.useEffect(() => {
82
+ setRecalcTrigger(prev => prev + 1);
83
+ }, [bannerStyle, bannerSubstyle]);
84
+ // Calculate font sizes for copies based on their styleSlot and fontSize multiplier
85
+ const fontSizes = (0, react_1.useMemo)(() => {
86
+ const baseSizeRem = defaults_1.DEFAULT_BASE_FONT_SIZE_REM;
87
+ return {
88
+ fontSize_01: `${baseSizeRem * (config.fontSize.copy1 || 1.0)}rem`,
89
+ fontSize_02: `${baseSizeRem * (config.fontSize.copy2 || 0.65)}rem`,
90
+ };
91
+ }, [config.fontSize]);
92
+ // Convert font weight string to CSS value
93
+ const getFontWeight = (weight) => {
94
+ switch (weight) {
95
+ case 'thin': return '300';
96
+ case 'normal': return '400';
97
+ case 'bold': return '700';
98
+ default: return '400';
99
+ }
100
+ };
101
+ // Reset auto-offsets when config changes (e.g., when changing substyle)
102
+ (0, react_1.useEffect)(() => {
103
+ setAutoOffsets({});
104
+ }, [config]);
105
+ // Memoize copies without rotation to prevent auto-positioning recalc on rotation changes
106
+ const copiesWithoutRotation = (0, react_1.useMemo)(() => {
107
+ return copies.map(copy => ({
108
+ text: copy.text,
109
+ styleSlot: copy.styleSlot,
110
+ translateX: copy.translateX,
111
+ translateY: copy.translateY,
112
+ width: copy.width,
113
+ // Exclude rotation from memoization
114
+ }));
115
+ }, [copies.map(c => `${c.text}-${c.styleSlot}-${c.translateX || 0}-${c.translateY || 0}-${c.width || 'auto'}`).join(',')]);
116
+ // Auto-positioning calculation
117
+ (0, react_1.useLayoutEffect)(() => {
118
+ // Only calculate if auto-positioning is enabled
119
+ if (!config.autoPositioning || !config.autoPositioningConfig) {
120
+ return;
121
+ }
122
+ const { anchorElement, targetElement } = config.autoPositioningConfig;
123
+ console.log('🎯 AUTO-POSITION CALC:', {
124
+ anchorElement,
125
+ targetElement,
126
+ direction: config.autoPositioningConfig.direction,
127
+ gapRem: config.gapRem,
128
+ });
129
+ // Get anchor element ref
130
+ let anchorRef = null;
131
+ if (anchorElement === 'logo') {
132
+ anchorRef = logoRef.current;
133
+ console.log('📍 Logo anchor:', {
134
+ exists: !!anchorRef,
135
+ height: anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.getBoundingClientRect().height,
136
+ });
137
+ }
138
+ else if (anchorElement === 'copy1') {
139
+ // Find copy with styleSlot 0 (copy1)
140
+ const copy1Index = copies.findIndex(c => c.styleSlot === 0);
141
+ if (copy1Index !== -1) {
142
+ anchorRef = copyRefs.current[copy1Index];
143
+ }
144
+ console.log('📍 Copy1 anchor:', {
145
+ exists: !!anchorRef,
146
+ height: anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.getBoundingClientRect().height,
147
+ });
148
+ }
149
+ else if (anchorElement === 'copy2') {
150
+ // Find copy with styleSlot 1 (copy2)
151
+ const copy2Index = copies.findIndex(c => c.styleSlot === 1);
152
+ if (copy2Index !== -1) {
153
+ anchorRef = copyRefs.current[copy2Index];
154
+ }
155
+ console.log('📍 Copy2 anchor:', {
156
+ exists: !!anchorRef,
157
+ height: anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.getBoundingClientRect().height,
158
+ });
159
+ }
160
+ // If anchor element doesn't exist, can't calculate
161
+ if (!anchorRef) {
162
+ console.log('❌ NO ANCHOR REF - Skipping calculation');
163
+ return;
164
+ }
165
+ // Get target element ref
166
+ let targetRef = null;
167
+ if (targetElement === 'copy1') {
168
+ const copy1Index = copies.findIndex(c => c.styleSlot === 0);
169
+ if (copy1Index !== -1) {
170
+ targetRef = copyRefs.current[copy1Index];
171
+ }
172
+ }
173
+ else if (targetElement === 'copy2') {
174
+ const copy2Index = copies.findIndex(c => c.styleSlot === 1);
175
+ if (copy2Index !== -1) {
176
+ targetRef = copyRefs.current[copy2Index];
177
+ }
178
+ }
179
+ // If target element doesn't exist, can't calculate
180
+ if (!targetRef) {
181
+ console.log('❌ NO TARGET REF - Skipping calculation');
182
+ return;
183
+ }
184
+ // Measure anchor and target heights
185
+ const anchorHeight = anchorRef.getBoundingClientRect().height / sizeMultiplier;
186
+ const targetHeight = targetRef.getBoundingClientRect().height / sizeMultiplier;
187
+ // Determine if anchor has centerOrigin (logo doesn't, copies do)
188
+ const anchorHasCenterOrigin = anchorElement !== 'logo';
189
+ console.log('📏 Heights:', { anchorHeight, targetHeight, anchorHasCenterOrigin });
190
+ // Calculate offset
191
+ const offset = (0, positioningUtils_1.calculateAutoPositionOffset)(config, config.autoPositioningConfig, anchorHeight, targetHeight, anchorHasCenterOrigin);
192
+ console.log('✨ Calculated offset:', offset);
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
+ console.log('🎪 Target styleSlot:', targetStyleSlot);
202
+ // Update offsets only if changed
203
+ if (targetStyleSlot !== undefined) {
204
+ setAutoOffsets(prev => {
205
+ // Only update if offset has changed significantly (to prevent infinite loops from floating point precision)
206
+ const prevOffset = prev[targetStyleSlot] || 0;
207
+ const EPSILON = 0.1; // 0.1px tolerance
208
+ console.log('🔄 Offset comparison:', { prevOffset, newOffset: offset, willUpdate: Math.abs(prevOffset - offset) > EPSILON });
209
+ if (Math.abs(prevOffset - offset) > EPSILON) {
210
+ const newOffsets = {
211
+ ...prev,
212
+ [targetStyleSlot]: offset,
213
+ };
214
+ console.log('✅ UPDATING OFFSETS:', newOffsets);
215
+ return newOffsets;
216
+ }
217
+ console.log('⏭️ SKIPPING - no significant change');
218
+ return prev; // No significant change, return same object to prevent re-render
219
+ });
220
+ }
221
+ }, [config, sizeMultiplier, recalcTrigger, copiesWithoutRotation]);
222
+ // Rotation snap function - snaps to 0°, 90°, 180°, 270°
223
+ const handleRotationSnap = react_1.default.useCallback((angle) => {
224
+ const snapAngles = [0, 90, 180, 270, -90, -180, -270];
225
+ const snapThreshold = 3; // degrees
226
+ // Normalize angle to -180 to 180 range
227
+ let normalized = angle % 360;
228
+ if (normalized > 180)
229
+ normalized -= 360;
230
+ if (normalized < -180)
231
+ normalized += 360;
232
+ // Check if close to any snap angle
233
+ for (const snapAngle of snapAngles) {
234
+ if (Math.abs(normalized - snapAngle) < snapThreshold) {
235
+ return snapAngle;
236
+ }
237
+ }
238
+ return normalized;
239
+ }, []);
240
+ // Shadow calculations using style configuration
241
+ const { shadowStyle, logoShadowStyle } = (0, react_1.useMemo)(() => {
242
+ var _a, _b;
243
+ // Get shadow defaults from style config (or use fallback values)
244
+ const textShadowConfig = ((_a = styleConfig.shadows) === null || _a === void 0 ? void 0 : _a.textShadow) || {
245
+ enabled: true,
246
+ size: 70,
247
+ intensity: 0.85,
248
+ direction: 'bottom',
249
+ };
250
+ const logoShadowConfig = ((_b = styleConfig.shadows) === null || _b === void 0 ? void 0 : _b.logoShadow) || {
251
+ enabled: true,
252
+ size: 150,
253
+ intensity: 0.375,
254
+ direction: 'top-left',
255
+ };
256
+ // Use prop overrides if provided, otherwise use config values
257
+ const effectiveTextShadowEnabled = textShadowEnabled !== null && textShadowEnabled !== void 0 ? textShadowEnabled : textShadowConfig.enabled;
258
+ const effectiveTextShadowSize = textShadowSize !== null && textShadowSize !== void 0 ? textShadowSize : textShadowConfig.size;
259
+ const effectiveTextShadowIntensity = textShadowIntensity !== null && textShadowIntensity !== void 0 ? textShadowIntensity : textShadowConfig.intensity;
260
+ const effectiveLogoShadowEnabled = logoShadowEnabled !== null && logoShadowEnabled !== void 0 ? logoShadowEnabled : logoShadowConfig.enabled;
261
+ const effectiveLogoShadowSize = logoShadowSize !== null && logoShadowSize !== void 0 ? logoShadowSize : logoShadowConfig.size;
262
+ const effectiveLogoShadowIntensity = logoShadowIntensity !== null && logoShadowIntensity !== void 0 ? logoShadowIntensity : logoShadowConfig.intensity;
263
+ // Generate shadow styles only if enabled
264
+ const shadowStyle = effectiveTextShadowEnabled
265
+ ? (0, shadowUtils_1.createAbstractShadowStyle)({
266
+ direction: textShadowConfig.direction,
267
+ size: `${effectiveTextShadowSize}%`,
268
+ intensity: effectiveTextShadowIntensity * shadowIntensityMultiplier,
269
+ })
270
+ : {};
271
+ const logoShadowStyle = effectiveLogoShadowEnabled
272
+ ? (0, shadowUtils_1.createAbstractShadowStyle)({
273
+ direction: logoShadowConfig.direction,
274
+ size: `${effectiveLogoShadowSize}%`,
275
+ intensity: effectiveLogoShadowIntensity * shadowIntensityMultiplier,
276
+ })
277
+ : {};
278
+ return { shadowStyle, logoShadowStyle };
279
+ }, [
280
+ styleConfig.shadows,
281
+ textShadowEnabled,
282
+ textShadowSize,
283
+ textShadowIntensity,
284
+ logoShadowEnabled,
285
+ logoShadowSize,
286
+ logoShadowIntensity,
287
+ shadowIntensityMultiplier,
288
+ ]);
289
+ // Shared logo component
290
+ 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: onLogoPositionChange, onRotationChange: onLogoRotationChange, onWidthChange: onLogoWidthChange, onSelect: (id) => setSelectedElement(id), onDeselect: () => setSelectedElement(null), onRotationSnap: handleRotationSnap, children: (0, jsx_runtime_1.jsx)("div", { ref: logoRef, className: "relative", style: {
291
+ width: logoWidth ? `${logoWidth}px` : `${defaults_1.DEFAULT_LOGO_SIZE_REM * logoSizeMultiplier}rem`,
292
+ height: logoWidth ? `${logoWidth}px` : `${defaults_1.DEFAULT_LOGO_SIZE_REM * logoSizeMultiplier}rem`,
293
+ transform: !draggableMode ? `translate(${logoTranslateX}px, ${logoTranslateY}px)` : undefined,
294
+ }, 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" } })) }) }));
295
+ // Function to render a copy component by styleSlot
296
+ // Function to render a copy component with absolute positioning
297
+ const renderCopyComponent = (copy) => {
298
+ var _a, _b, _c, _d;
299
+ // Use styleSlot to determine config (0 = copy1, 1 = copy2)
300
+ const styleSlot = copy.styleSlot !== undefined ? copy.styleSlot : 0;
301
+ // Determine if this is a styled copy (copy1 or copy2) vs overflow copy
302
+ const isStyled = styleSlot === 0 || styleSlot === 1;
303
+ // Get copy config, with fallback for styles that don't have copy2
304
+ const copyConfig = styleSlot === 0
305
+ ? config.copy1
306
+ : ('copy2' in config ? config.copy2 : config.copy1);
307
+ // Get config position and width
308
+ const configX = (_a = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.x) !== null && _a !== void 0 ? _a : 0;
309
+ const configY = (_b = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.y) !== null && _b !== void 0 ? _b : 0;
310
+ const configWidth = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.width;
311
+ const autoOffset = autoOffsets[styleSlot] || 0;
312
+ // Get the font size multiplier from copy config (used for both font size and padding scaling)
313
+ const copyFontSizeMultiplier = copy.fontSize || 1.0;
314
+ // Calculate font size
315
+ // copy.fontSize is now an absolute multiplier, not relative to config
316
+ // Config fontSize values only set the initial copy.fontSize value
317
+ const effectiveFontSize = `${defaults_1.DEFAULT_BASE_FONT_SIZE_REM * copyFontSizeMultiplier}rem`;
318
+ // Get alignment - always prioritize copy's own align property
319
+ const effectiveAlign = copy.align || (isStyled && copyConfig ? copyConfig.alignment : 'center');
320
+ // Get font weight - use copy's fontWeight, then config default, then fallback
321
+ const effectiveFontWeight = copy.fontWeight || (isStyled ? (styleSlot === 0 ? (styleConfig.copy1FontWeight || 'bold') : (styleConfig.copy2FontWeight || 'normal')) : 'normal');
322
+ // Get font family - prioritize copy's own fontFamily, then global override, then style config
323
+ const effectiveCopyFontFamily = copy.fontFamily || fontFamily || styleConfig.fontFamily;
324
+ // Get color properties - prioritize copy's own properties, then substyle config, then defaults
325
+ const effectiveColor = copy.color || (isStyled && copyConfig ? copyConfig.color : undefined) || 'white';
326
+ const effectiveBgColor = copy.bgColor || (isStyled && copyConfig ? copyConfig.bgColor : undefined);
327
+ const effectiveHasBg = copy.hasBg !== undefined ? copy.hasBg : (isStyled && copyConfig ? copyConfig.hasBg : false);
328
+ // Get padding and scale it proportionally with font size to maintain visual consistency
329
+ const basePaddingX = copy.paddingX || (isStyled && copyConfig ? copyConfig.paddingX : undefined);
330
+ const basePaddingY = copy.paddingY || (isStyled && copyConfig ? copyConfig.paddingY : undefined);
331
+ const effectivePaddingX = basePaddingX
332
+ ? `${parseFloat(basePaddingX.replace('rem', '')) * copyFontSizeMultiplier}rem`
333
+ : undefined;
334
+ const effectivePaddingY = basePaddingY
335
+ ? `${parseFloat(basePaddingY.replace('rem', '')) * copyFontSizeMultiplier}rem`
336
+ : undefined;
337
+ const effectiveBorderRadius = copy.borderRadius || (isStyled && copyConfig ? copyConfig.borderRadius : undefined);
338
+ // Apply text decoration styles
339
+ const textDecorationStyles = [];
340
+ if (copy.underline)
341
+ textDecorationStyles.push('underline');
342
+ const textDecoration = textDecorationStyles.length > 0 ? textDecorationStyles.join(' ') : 'none';
343
+ // Apply font style
344
+ const fontStyle = copy.italic ? 'italic' : 'normal';
345
+ // Apply additional bold if textBold is true (combines with fontWeight)
346
+ const finalFontWeight = copy.textBold
347
+ ? 'bold'
348
+ : getFontWeight(effectiveFontWeight);
349
+ // Text element
350
+ const textElement = ((0, jsx_runtime_1.jsx)("p", { style: {
351
+ fontSize: effectiveFontSize,
352
+ fontWeight: finalFontWeight,
353
+ fontFamily: effectiveCopyFontFamily,
354
+ color: effectiveColor,
355
+ textDecoration,
356
+ fontStyle,
357
+ }, className: (0, clsx_1.default)("whitespace-pre-wrap", `text-${effectiveAlign}`), children: copy.text }));
358
+ // Wrap with background if needed
359
+ const contentElement = effectiveHasBg ? ((0, jsx_runtime_1.jsx)("div", { style: {
360
+ backgroundColor: effectiveBgColor,
361
+ paddingLeft: effectivePaddingX,
362
+ paddingRight: effectivePaddingX,
363
+ paddingTop: effectivePaddingY,
364
+ paddingBottom: effectivePaddingY,
365
+ borderRadius: effectiveBorderRadius,
366
+ display: 'inline-block',
367
+ }, children: textElement })) : textElement;
368
+ // Calculate final position: config position + auto-offset + user adjustment
369
+ const baseX = isStyled ? configX : 0;
370
+ const baseY = isStyled ? (configY + autoOffset) : 0;
371
+ const finalX = baseX + (copy.translateX || 0);
372
+ const finalY = baseY + (copy.translateY || 0);
373
+ const finalWidth = copy.width || configWidth;
374
+ 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);
375
+ console.log(`📦 DRAGGABLE POSITION (styleSlot ${styleSlot}):`, {
376
+ configX,
377
+ configY,
378
+ autoOffset,
379
+ baseX,
380
+ baseY,
381
+ 'copy.translateX': copy.translateX,
382
+ 'copy.translateY': copy.translateY,
383
+ finalX,
384
+ finalY,
385
+ finalWidth,
386
+ });
387
+ 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) => {
388
+ // Subtract base position to get only user adjustment
389
+ const adjustedPos = {
390
+ x: pos.x - baseX,
391
+ y: pos.y - baseY,
392
+ };
393
+ // Find index of this copy in the copies array to call the callback
394
+ const copyIndex = copies.findIndex(c => c.id === copy.id);
395
+ if (copyIndex !== -1) {
396
+ onCopyPositionChange === null || onCopyPositionChange === void 0 ? void 0 : onCopyPositionChange(copyIndex, adjustedPos);
397
+ }
398
+ }, onRotationChange: (rot) => {
399
+ const copyIndex = copies.findIndex(c => c.id === copy.id);
400
+ if (copyIndex !== -1) {
401
+ onCopyRotationChange === null || onCopyRotationChange === void 0 ? void 0 : onCopyRotationChange(copyIndex, rot);
402
+ }
403
+ }, onWidthChange: (w) => {
404
+ const copyIndex = copies.findIndex(c => c.id === copy.id);
405
+ if (copyIndex !== -1) {
406
+ onCopyWidthChange === null || onCopyWidthChange === void 0 ? void 0 : onCopyWidthChange(copyIndex, w);
407
+ }
408
+ }, onSelect: (id) => setSelectedElement(id), onDeselect: () => setSelectedElement(null), onRotationSnap: handleRotationSnap, children: (0, jsx_runtime_1.jsx)("div", { ref: (el) => {
409
+ // Store ref by styleSlot for auto-positioning
410
+ if (styleSlot === 0)
411
+ copyRefs.current[0] = el;
412
+ else if (styleSlot === 1)
413
+ copyRefs.current[1] = el;
414
+ }, style: {
415
+ transform: !draggableMode ? `translate(${finalX}px, ${finalY}px) rotate(${finalRotation}deg)` : undefined,
416
+ width: '100%',
417
+ // Hide copy if hidden property is true
418
+ display: copy.hidden ? 'none' : undefined,
419
+ }, children: contentElement }) }, copy.id));
420
+ };
421
+ return ((0, jsx_runtime_1.jsx)("div", { className: "w-full h-full text-white leading-[1.05]", children: (0, jsx_runtime_1.jsxs)("div", { 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: {
422
+ opacity: Math.min(noiseIntensity / 2, 1), // Normalize 0-2 range to 0-1
423
+ mixBlendMode: 'overlay',
424
+ 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")`,
425
+ zIndex: 5,
426
+ } })), (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: {
427
+ top: '50%',
428
+ left: '50%',
429
+ transform: `translate(${config.logo.x}px, ${config.logo.y}px)`,
430
+ }, children: logoComponent }), (0, jsx_runtime_1.jsx)("div", { className: "absolute pointer-events-none", style: {
431
+ top: '50%',
432
+ left: '50%',
433
+ width: 0,
434
+ height: 0
435
+ }, children: copies.map((copy) => {
436
+ // Get width from config for the wrapper
437
+ const styleSlot = copy.styleSlot !== undefined ? copy.styleSlot : 0;
438
+ const copyConfig = styleSlot === 0
439
+ ? config.copy1
440
+ : ('copy2' in config ? config.copy2 : config.copy1);
441
+ const configWidth = copy.width || (copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.width);
442
+ return ((0, jsx_runtime_1.jsx)("div", { className: "pointer-events-auto absolute", style: {
443
+ top: '50%',
444
+ left: '50%',
445
+ width: configWidth,
446
+ }, children: renderCopyComponent(copy) }, copy.id));
447
+ }) })] }) }));
448
+ };
449
+ exports.BannerRenderer = BannerRenderer;
@@ -1 +1 @@
1
- {"version":3,"file":"BannerVisor.d.ts","sourceRoot":"","sources":["../../src/components/BannerVisor.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAY7D,UAAU,yBAA0B,SAAQ,gBAAgB;IAC1D,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAUD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAwJ3D,CAAC"}
1
+ {"version":3,"file":"BannerVisor.d.ts","sourceRoot":"","sources":["../../src/components/BannerVisor.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAA+C,MAAM,OAAO,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAc,MAAM,UAAU,CAAC;AAYzE,UAAU,yBAA0B,SAAQ,gBAAgB;IAC1D,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAUD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAkU3D,CAAC"}