@zync/zync-screnplay-player 0.1.187
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.
- package/dist/ZyncScreenplayPlayer.js +35 -0
- package/dist/bundle.js +2 -0
- package/dist/bundle.js.LICENSE.txt +54 -0
- package/dist/index.js +4 -0
- package/dist/screenplay/RemotionRenderer/RemotionRenderer.js +281 -0
- package/dist/screenplay/RemotionRenderer/Root.js +22 -0
- package/dist/screenplay/RemotionRenderer/components/LottieAnimationGlobal.js +116 -0
- package/dist/screenplay/RemotionRenderer/components/backgrounds/VirtualBackground.js +26 -0
- package/dist/screenplay/RemotionRenderer/components/backgrounds/VirtualBackgroundUnderlay.js +41 -0
- package/dist/screenplay/RemotionRenderer/components/captions/CaptionSimple.js +12 -0
- package/dist/screenplay/RemotionRenderer/components/effects/BrollFullscreen.js +27 -0
- package/dist/screenplay/RemotionRenderer/components/effects/GlitchText.js +22 -0
- package/dist/screenplay/RemotionRenderer/components/effects/HandoffNametag.js +7 -0
- package/dist/screenplay/RemotionRenderer/components/effects/LottieAnimation.js +64 -0
- package/dist/screenplay/RemotionRenderer/components/effects/Nametag.js +9 -0
- package/dist/screenplay/RemotionRenderer/components/effects/PhraseRainbowEffect.js +34 -0
- package/dist/screenplay/RemotionRenderer/components/effects/Sentence.js +50 -0
- package/dist/screenplay/RemotionRenderer/components/effects/Title.js +12 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/BrollGreenScreen.js +742 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/BrollSplitScreen.js +714 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/BrollStudioBackdrop.js +620 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/DynamicTriangle.js +618 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/Handoff.js +161 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/IntroVideo.js +1330 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/KeyPointOverlayDepth.js +397 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/Keyword.js +539 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/KeywordStudioBackdrop.js +714 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStill.js +381 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillFullScreen.js +178 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillGreenScreen.js +568 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillGreenScreenV2.js +731 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/MotionStillStudioBackdrop.js +588 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrame.js +183 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameBroll.js +181 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameSentence.js +17 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/SimpleFrameZoomCut.js +13 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/TextWithVideo.js +373 -0
- package/dist/screenplay/RemotionRenderer/components/layouts/quote-bubble-animation.json +1 -0
- package/dist/screenplay/RemotionRenderer/components/utils/BlurOverlay.js +19 -0
- package/dist/screenplay/RemotionRenderer/components/utils/ChromaKeyedVideo.js +59 -0
- package/dist/screenplay/RemotionRenderer/components/utils/FaceCenteredVideo.js +562 -0
- package/dist/screenplay/RemotionRenderer/components/utils/PausableImg.js +124 -0
- package/dist/screenplay/RemotionRenderer/components/utils/README.md +80 -0
- package/dist/screenplay/RemotionRenderer/components/utils/SafeZones.js +69 -0
- package/dist/screenplay/RemotionRenderer/components/utils/StretchText.js +124 -0
- package/dist/screenplay/RemotionRenderer/components/utils/StretchTextDemo.js +66 -0
- package/dist/screenplay/RemotionRenderer/config.js +8 -0
- package/dist/screenplay/RemotionRenderer/development.js +1370 -0
- package/dist/screenplay/RemotionRenderer/helpers/cleanFacemetadata.js +29 -0
- package/dist/screenplay/RemotionRenderer/helpers/convertToSeconds.js +14 -0
- package/dist/screenplay/RemotionRenderer/helpers/faceBasedVideoStyles.js +212 -0
- package/dist/screenplay/RemotionRenderer/helpers/faceCenteredVideoTransforms.js +468 -0
- package/dist/screenplay/RemotionRenderer/helpers/getContrastColor.js +15 -0
- package/dist/screenplay/RemotionRenderer/helpers/getVideoOrientation.js +21 -0
- package/dist/screenplay/RemotionRenderer/helpers/hexToRgb.js +48 -0
- package/dist/screenplay/RemotionRenderer/hooks/useLottieReplaceColor.js +45 -0
- package/dist/screenplay/RemotionRenderer/hooks/useOrientationBased.js +29 -0
- package/dist/screenplay/RemotionRenderer/hooks/useTimeInterpolate.js +54 -0
- package/dist/screenplay/RemotionRenderer/hooks/useVirtualBackground.js +38 -0
- package/dist/screenplay/RemotionRenderer/index.js +3 -0
- package/dist/screenplay/RemotionRenderer/main/lib/Sequence.js +76 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/DefaultLayout.js +72 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/DynamicTriangleLayout.js +54 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/HandoffLayout.js +50 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/IntroVideoLayout.js +33 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/KeywordLayout.js +36 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/LayoutFactory.js +68 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/MotionStillLayout.js +36 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/SimpleFrameLayout.js +43 -0
- package/dist/screenplay/RemotionRenderer/main/lib/layouts/TextWithVideoLayout.js +52 -0
- package/dist/screenplay/RemotionRenderer/main/screenplaySchema.js +92 -0
- package/dist/screenplay/RemotionRenderer/registeredComponents.js +91 -0
- package/dist/screenplay/RemotionRenderer/theme/config.js +8 -0
- package/dist/screenplay/RemotionRenderer/theme/hooks/useTheme.js +24 -0
- package/dist/screenplay/RemotionRenderer/theme/hooks/useThemedComponents.js +101 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldNameTag.js +147 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldSentence.js +138 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/bigbold/BigBoldTitle.js +136 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColor.js +67 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColorInverse.js +67 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionColorShadow.js +66 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionElegant.js +134 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionEmphasis.js +122 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionPunctuated.js +84 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordBoom.js +88 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordBubble.js +91 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/CaptionWordPopup.js +118 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/DefaultCaption.js +62 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/HandoffNametag/handoffNametagConfig.js +59 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/HandoffNametag.js +173 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Nametag.js +129 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/AnimatedSentence.js +20 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/AnimatedSentenceDefault.js +29 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence/SentenceSimple.helpers.js +61 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Sentence.js +86 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/Title.js +112 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/default/constants.js +1 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Nametag.js +134 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Sentence.js +49 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/Title.js +108 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/animations.js +30 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glassmorphism/config.js +9 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchNametag.js +252 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchSentence.js +156 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/GlitchTitle.js +142 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/DisplacedText.js +66 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/GlitchAnimatedLine.js +38 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/components/SplitSentence.js +80 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/glitch/helpers.js +32 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/none/Nametag.js +3 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/none/Title.js +3 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullNametag.js +165 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullSentence.js +94 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/PushPullTitle.js +98 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/designs/sentence.js +92 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/pushpull/designs/title.js +119 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/Nametag.js +122 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/SportsCaption.js +93 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/SportsSentence.js +76 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/Title.js +90 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sports/shared.js +62 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/Nametag.js +145 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/SportsBounceSentence.js +148 -0
- package/dist/screenplay/RemotionRenderer/theme/themes/sportsbounce/Title.js +160 -0
- package/dist/screenplay/RemotionRenderer/tracks/AudioTrack.js +23 -0
- package/dist/screenplay/RemotionRenderer/tracks/CaptionsVideoTrack.js +23 -0
- package/dist/screenplay/RemotionRenderer/tracks/DynamicVideoComposition.js +31 -0
- package/dist/screenplay/RemotionRenderer/tracks/EffectsVideoTrack.js +23 -0
- package/dist/screenplay/RemotionRenderer/tracks/LayoutVideoTrack.js +141 -0
- package/dist/screenplay/RemotionRenderer/tracks/Soundtrack.js +16 -0
- package/dist/screenplay/RemotionRenderer/tracks/Watermark.js +23 -0
- package/dist/screenplay/RemotionRenderer/tracks/transitions/GlitchOne.js +92 -0
- package/package.json +45 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
+
/**
|
|
8
|
+
* Face-Centered Video Transform Calculator
|
|
9
|
+
*
|
|
10
|
+
* This helper calculates transform origin and positioning to ensure a video is ALWAYS
|
|
11
|
+
* centered on a person's face, regardless of aspect ratio (landscape, square, portrait).
|
|
12
|
+
*
|
|
13
|
+
* Key features:
|
|
14
|
+
* - Converts absolute face coordinates to relative values
|
|
15
|
+
* - Handles different target aspect ratios (1920x1080, 1080x1080, 1080x1920)
|
|
16
|
+
* - Provides smooth interpolation between frames
|
|
17
|
+
* - Calculates optimal scale and positioning for face centering
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { useCurrentFrame } from "remotion";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Calculate face-centered video transforms
|
|
24
|
+
* @param {Object} params - Configuration object
|
|
25
|
+
* @param {Object} params.faceMetadata - Face detection metadata
|
|
26
|
+
* @param {number} params.targetWidth - Target video width (1920 for landscape, 1080 for square/portrait)
|
|
27
|
+
* @param {number} params.targetHeight - Target video height (1080 for landscape/square, 1920 for portrait)
|
|
28
|
+
* @param {number} params.currentFrame - Current frame number (optional, will use useCurrentFrame if not provided)
|
|
29
|
+
* @param {boolean} params.enableInterpolation - Whether to interpolate between frames
|
|
30
|
+
* @param {number} params.faceScale - Scale factor for face area (1.0 = face fills frame, 0.5 = face takes half frame)
|
|
31
|
+
* @param {boolean} params.useAveragePosition - Whether to use average face position for entire video duration
|
|
32
|
+
* @param {boolean} params.centerHorizontally - Whether to only center horizontally (X axis), not vertically (Y axis)
|
|
33
|
+
* @returns {Object} Transform styles and debug info
|
|
34
|
+
*/
|
|
35
|
+
export var calculateFaceCenteredTransforms = function calculateFaceCenteredTransforms(_ref) {
|
|
36
|
+
var _faceMetadata$metadat, _faceMetadata$metadat2;
|
|
37
|
+
var faceMetadata = _ref.faceMetadata,
|
|
38
|
+
targetWidth = _ref.targetWidth,
|
|
39
|
+
targetHeight = _ref.targetHeight,
|
|
40
|
+
_ref$currentFrame = _ref.currentFrame,
|
|
41
|
+
currentFrame = _ref$currentFrame === void 0 ? null : _ref$currentFrame,
|
|
42
|
+
_ref$enableInterpolat = _ref.enableInterpolation,
|
|
43
|
+
enableInterpolation = _ref$enableInterpolat === void 0 ? true : _ref$enableInterpolat,
|
|
44
|
+
_ref$faceScale = _ref.faceScale,
|
|
45
|
+
faceScale = _ref$faceScale === void 0 ? 0.6 : _ref$faceScale,
|
|
46
|
+
_ref$useAveragePositi = _ref.useAveragePosition,
|
|
47
|
+
useAveragePosition = _ref$useAveragePositi === void 0 ? false : _ref$useAveragePositi,
|
|
48
|
+
_ref$centerHorizontal = _ref.centerHorizontally,
|
|
49
|
+
centerHorizontally = _ref$centerHorizontal === void 0 ? false : _ref$centerHorizontal;
|
|
50
|
+
// Get current frame if not provided
|
|
51
|
+
var frameIndex = currentFrame;
|
|
52
|
+
if (frameIndex === null) {
|
|
53
|
+
try {
|
|
54
|
+
var remotionFrame = useCurrentFrame();
|
|
55
|
+
frameIndex = remotionFrame;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
// useCurrentFrame not available (e.g., in testing environment)
|
|
58
|
+
frameIndex = 0;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Validate inputs
|
|
63
|
+
if (!(faceMetadata !== null && faceMetadata !== void 0 && (_faceMetadata$metadat = faceMetadata.metadata) !== null && _faceMetadata$metadat !== void 0 && _faceMetadata$metadat.frames) || !(faceMetadata !== null && faceMetadata !== void 0 && (_faceMetadata$metadat2 = faceMetadata.metadata) !== null && _faceMetadata$metadat2 !== void 0 && _faceMetadata$metadat2.videoProperties)) {
|
|
64
|
+
return {
|
|
65
|
+
transform: "scale(1) translate(0px, 0px)",
|
|
66
|
+
transformOrigin: "center center",
|
|
67
|
+
debugInfo: {
|
|
68
|
+
error: "Invalid face metadata"
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
var _faceMetadata$metadat3 = faceMetadata.metadata,
|
|
73
|
+
frames = _faceMetadata$metadat3.frames,
|
|
74
|
+
videoProperties = _faceMetadata$metadat3.videoProperties;
|
|
75
|
+
var sourceWidth = videoProperties.width,
|
|
76
|
+
sourceHeight = videoProperties.height;
|
|
77
|
+
|
|
78
|
+
// Get face data for current frame or use average position
|
|
79
|
+
var faceData = useAveragePosition ? getAverageFaceData(frames) : getFaceDataForFrame(frames, frameIndex, enableInterpolation);
|
|
80
|
+
if (!faceData) {
|
|
81
|
+
return {
|
|
82
|
+
transform: "scale(1) translate(0px, 0px)",
|
|
83
|
+
transformOrigin: "center center",
|
|
84
|
+
debugInfo: {
|
|
85
|
+
error: "No face data available"
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Convert absolute face coordinates to relative (0-1 range)
|
|
91
|
+
var relativeFaceX = faceData.face_center[0] / sourceWidth;
|
|
92
|
+
var relativeFaceY = faceData.face_center[1] / sourceHeight;
|
|
93
|
+
|
|
94
|
+
// Calculate source and target aspect ratios
|
|
95
|
+
var sourceAspectRatio = sourceWidth / sourceHeight;
|
|
96
|
+
var targetAspectRatio = targetWidth / targetHeight;
|
|
97
|
+
|
|
98
|
+
// Calculate how the source video will be scaled to fit the target container
|
|
99
|
+
var videoScaleX,
|
|
100
|
+
videoScaleY,
|
|
101
|
+
videoOffsetX = 0,
|
|
102
|
+
videoOffsetY = 0;
|
|
103
|
+
if (sourceAspectRatio > targetAspectRatio) {
|
|
104
|
+
// Source is wider - will be cropped horizontally
|
|
105
|
+
videoScaleY = targetHeight / sourceHeight;
|
|
106
|
+
videoScaleX = videoScaleY;
|
|
107
|
+
var scaledWidth = sourceWidth * videoScaleX;
|
|
108
|
+
videoOffsetX = (targetWidth - scaledWidth) / 2;
|
|
109
|
+
} else {
|
|
110
|
+
// Source is taller - will be cropped vertically
|
|
111
|
+
videoScaleX = targetWidth / sourceWidth;
|
|
112
|
+
videoScaleY = videoScaleX;
|
|
113
|
+
var scaledHeight = sourceHeight * videoScaleY;
|
|
114
|
+
videoOffsetY = (targetHeight - scaledHeight) / 2;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Calculate face position in the scaled video
|
|
118
|
+
var scaledFaceX = relativeFaceX * sourceWidth * videoScaleX + videoOffsetX;
|
|
119
|
+
var scaledFaceY = relativeFaceY * sourceHeight * videoScaleY + videoOffsetY;
|
|
120
|
+
|
|
121
|
+
// Calculate how much we need to translate to center the face
|
|
122
|
+
var targetCenterX = targetWidth / 2;
|
|
123
|
+
var targetCenterY = targetHeight / 2;
|
|
124
|
+
var translateX = targetCenterX - scaledFaceX;
|
|
125
|
+
var translateY = centerHorizontally ? 0 : targetCenterY - scaledFaceY;
|
|
126
|
+
|
|
127
|
+
// Calculate optimal scale based on face size and desired face scale
|
|
128
|
+
var faceWidth = faceData.face_bbox ? faceData.face_bbox[2] : sourceWidth * 0.3; // fallback to 30% of width
|
|
129
|
+
var faceHeight = faceData.face_bbox ? faceData.face_bbox[3] : sourceHeight * 0.3; // fallback to 30% of height
|
|
130
|
+
|
|
131
|
+
// Calculate what scale would make the face the desired size
|
|
132
|
+
var relativeFaceWidth = faceWidth / sourceWidth;
|
|
133
|
+
var relativeFaceHeight = faceHeight / sourceHeight;
|
|
134
|
+
|
|
135
|
+
// Use the smaller dimension to ensure face fits
|
|
136
|
+
var faceAspectScale = Math.min(targetWidth * faceScale / (relativeFaceWidth * sourceWidth * videoScaleX), targetHeight * faceScale / (relativeFaceHeight * sourceHeight * videoScaleY));
|
|
137
|
+
|
|
138
|
+
// Combine base scale with face-centering scale
|
|
139
|
+
var finalScale = Math.max(1, faceAspectScale); // Never scale down below 1
|
|
140
|
+
|
|
141
|
+
// Adjust translation for the final scale
|
|
142
|
+
var finalTranslateX = translateX * finalScale;
|
|
143
|
+
var finalTranslateY = translateY * finalScale;
|
|
144
|
+
|
|
145
|
+
// Create transform string
|
|
146
|
+
var transform = "scale(".concat(finalScale, ") translate(").concat(finalTranslateX, "px, ").concat(finalTranslateY, "px)");
|
|
147
|
+
|
|
148
|
+
// Transform origin should be at the face position in the original video
|
|
149
|
+
var transformOriginX = (relativeFaceX * 100).toFixed(2);
|
|
150
|
+
var transformOriginY = (relativeFaceY * 100).toFixed(2);
|
|
151
|
+
var transformOrigin = "".concat(transformOriginX, "% ").concat(transformOriginY, "%");
|
|
152
|
+
return {
|
|
153
|
+
transform: transform,
|
|
154
|
+
transformOrigin: transformOrigin,
|
|
155
|
+
debugInfo: {
|
|
156
|
+
frameIndex: useAveragePosition ? "AVERAGE" : frameIndex,
|
|
157
|
+
relativeFaceX: relativeFaceX.toFixed(3),
|
|
158
|
+
relativeFaceY: relativeFaceY.toFixed(3),
|
|
159
|
+
scaledFaceX: scaledFaceX.toFixed(1),
|
|
160
|
+
scaledFaceY: scaledFaceY.toFixed(1),
|
|
161
|
+
translateX: translateX.toFixed(1),
|
|
162
|
+
translateY: translateY.toFixed(1),
|
|
163
|
+
finalScale: finalScale.toFixed(2),
|
|
164
|
+
finalTranslateX: finalTranslateX.toFixed(1),
|
|
165
|
+
finalTranslateY: finalTranslateY.toFixed(1),
|
|
166
|
+
sourceAspectRatio: sourceAspectRatio.toFixed(3),
|
|
167
|
+
targetAspectRatio: targetAspectRatio.toFixed(3),
|
|
168
|
+
videoScaleX: videoScaleX.toFixed(3),
|
|
169
|
+
videoScaleY: videoScaleY.toFixed(3),
|
|
170
|
+
useAveragePosition: useAveragePosition,
|
|
171
|
+
centerHorizontally: centerHorizontally
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Calculate average face position from all frames with face data
|
|
178
|
+
* @param {Array} frames - Array of frame data
|
|
179
|
+
* @returns {Object|null} Average face data or null if no face data available
|
|
180
|
+
*/
|
|
181
|
+
function getAverageFaceData(frames) {
|
|
182
|
+
if (!frames || frames.length === 0) return null;
|
|
183
|
+
|
|
184
|
+
// Filter frames with face data
|
|
185
|
+
var framesWithFaces = frames.filter(function (f) {
|
|
186
|
+
return f.face_detected && f.face_data;
|
|
187
|
+
});
|
|
188
|
+
if (framesWithFaces.length === 0) return null;
|
|
189
|
+
|
|
190
|
+
// Calculate average face center position
|
|
191
|
+
var totalFaceX = 0;
|
|
192
|
+
var totalFaceY = 0;
|
|
193
|
+
var totalFaceWidth = 0;
|
|
194
|
+
var totalFaceHeight = 0;
|
|
195
|
+
var validBboxCount = 0;
|
|
196
|
+
framesWithFaces.forEach(function (frame) {
|
|
197
|
+
var _frame$face_data = frame.face_data,
|
|
198
|
+
face_center = _frame$face_data.face_center,
|
|
199
|
+
face_bbox = _frame$face_data.face_bbox;
|
|
200
|
+
totalFaceX += face_center[0];
|
|
201
|
+
totalFaceY += face_center[1];
|
|
202
|
+
|
|
203
|
+
// Only include bbox data if it exists
|
|
204
|
+
if (face_bbox && face_bbox.length >= 4) {
|
|
205
|
+
totalFaceWidth += face_bbox[2];
|
|
206
|
+
totalFaceHeight += face_bbox[3];
|
|
207
|
+
validBboxCount++;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
var avgFaceX = totalFaceX / framesWithFaces.length;
|
|
211
|
+
var avgFaceY = totalFaceY / framesWithFaces.length;
|
|
212
|
+
|
|
213
|
+
// Create average face data object
|
|
214
|
+
var averageFaceData = {
|
|
215
|
+
face_center: [avgFaceX, avgFaceY]
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Add average bbox if we have valid bbox data
|
|
219
|
+
if (validBboxCount > 0) {
|
|
220
|
+
var avgFaceWidth = totalFaceWidth / validBboxCount;
|
|
221
|
+
var avgFaceHeight = totalFaceHeight / validBboxCount;
|
|
222
|
+
// Use average position and size for bbox
|
|
223
|
+
averageFaceData.face_bbox = [avgFaceX - avgFaceWidth / 2, avgFaceY - avgFaceHeight / 2, avgFaceWidth, avgFaceHeight];
|
|
224
|
+
}
|
|
225
|
+
return averageFaceData;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Get face data for a specific frame with optional interpolation
|
|
230
|
+
*/
|
|
231
|
+
function getFaceDataForFrame(frames, targetFrame, enableInterpolation) {
|
|
232
|
+
if (!frames || frames.length === 0) return null;
|
|
233
|
+
|
|
234
|
+
// Find exact frame match first
|
|
235
|
+
var exactFrame = frames.find(function (f) {
|
|
236
|
+
return f.frame_index === targetFrame && f.face_detected;
|
|
237
|
+
});
|
|
238
|
+
if (exactFrame) return exactFrame.face_data;
|
|
239
|
+
|
|
240
|
+
// Filter frames with face data
|
|
241
|
+
var framesWithFaces = frames.filter(function (f) {
|
|
242
|
+
return f.face_detected && f.face_data;
|
|
243
|
+
});
|
|
244
|
+
if (framesWithFaces.length === 0) return null;
|
|
245
|
+
if (!enableInterpolation) {
|
|
246
|
+
// Find closest frame
|
|
247
|
+
return framesWithFaces.reduce(function (closest, current) {
|
|
248
|
+
var closestDiff = Math.abs(closest.frame_index - targetFrame);
|
|
249
|
+
var currentDiff = Math.abs(current.frame_index - targetFrame);
|
|
250
|
+
return currentDiff < closestDiff ? current : closest;
|
|
251
|
+
}).face_data;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Sort frames by frame index
|
|
255
|
+
var sortedFrames = framesWithFaces.sort(function (a, b) {
|
|
256
|
+
return a.frame_index - b.frame_index;
|
|
257
|
+
});
|
|
258
|
+
if (sortedFrames.length === 1) return sortedFrames[0].face_data;
|
|
259
|
+
|
|
260
|
+
// Find surrounding frames for interpolation
|
|
261
|
+
var prevFrame = null;
|
|
262
|
+
var nextFrame = null;
|
|
263
|
+
for (var i = 0; i < sortedFrames.length; i++) {
|
|
264
|
+
if (sortedFrames[i].frame_index <= targetFrame) {
|
|
265
|
+
prevFrame = sortedFrames[i];
|
|
266
|
+
}
|
|
267
|
+
if (sortedFrames[i].frame_index >= targetFrame && !nextFrame) {
|
|
268
|
+
nextFrame = sortedFrames[i];
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Use closest frame if we don't have both sides
|
|
274
|
+
if (!prevFrame) return nextFrame.face_data;
|
|
275
|
+
if (!nextFrame) return prevFrame.face_data;
|
|
276
|
+
if (prevFrame.frame_index === nextFrame.frame_index) return prevFrame.face_data;
|
|
277
|
+
|
|
278
|
+
// Interpolate between frames
|
|
279
|
+
var progress = (targetFrame - prevFrame.frame_index) / (nextFrame.frame_index - prevFrame.frame_index);
|
|
280
|
+
var prevFace = prevFrame.face_data;
|
|
281
|
+
var nextFace = nextFrame.face_data;
|
|
282
|
+
return {
|
|
283
|
+
face_center: [prevFace.face_center[0] + (nextFace.face_center[0] - prevFace.face_center[0]) * progress, prevFace.face_center[1] + (nextFace.face_center[1] - prevFace.face_center[1]) * progress],
|
|
284
|
+
face_bbox: progress < 0.5 ? prevFace.face_bbox : nextFace.face_bbox
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Preset configurations for common aspect ratios
|
|
290
|
+
*/
|
|
291
|
+
export var ASPECT_RATIO_PRESETS = {
|
|
292
|
+
LANDSCAPE: {
|
|
293
|
+
width: 1920,
|
|
294
|
+
height: 1080
|
|
295
|
+
},
|
|
296
|
+
SQUARE: {
|
|
297
|
+
width: 1080,
|
|
298
|
+
height: 1080
|
|
299
|
+
},
|
|
300
|
+
PORTRAIT: {
|
|
301
|
+
width: 1080,
|
|
302
|
+
height: 1920
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Calculate face-centered object-position values
|
|
308
|
+
* @param {Object} params - Configuration object
|
|
309
|
+
* @param {Object} params.faceMetadata - Face detection metadata
|
|
310
|
+
* @param {number} params.targetWidth - Target video width (1920 for landscape, 1080 for square/portrait)
|
|
311
|
+
* @param {number} params.targetHeight - Target video height (1080 for landscape/square, 1920 for portrait)
|
|
312
|
+
* @param {number} params.currentFrame - Current frame number (optional, will use useCurrentFrame if not provided)
|
|
313
|
+
* @param {boolean} params.enableInterpolation - Whether to interpolate between frames
|
|
314
|
+
* @param {boolean} params.useAveragePosition - Whether to use average face position for entire video duration
|
|
315
|
+
* @param {boolean} params.centerHorizontally - Whether to only center horizontally (X axis), not vertically (Y axis)
|
|
316
|
+
* @returns {Object} Object-position styles and debug info
|
|
317
|
+
*/
|
|
318
|
+
export var calculateFaceCenteredObjectPosition = function calculateFaceCenteredObjectPosition(_ref2) {
|
|
319
|
+
var _faceMetadata$metadat4, _faceMetadata$metadat5;
|
|
320
|
+
var faceMetadata = _ref2.faceMetadata,
|
|
321
|
+
targetWidth = _ref2.targetWidth,
|
|
322
|
+
targetHeight = _ref2.targetHeight,
|
|
323
|
+
_ref2$currentFrame = _ref2.currentFrame,
|
|
324
|
+
currentFrame = _ref2$currentFrame === void 0 ? null : _ref2$currentFrame,
|
|
325
|
+
_ref2$enableInterpola = _ref2.enableInterpolation,
|
|
326
|
+
enableInterpolation = _ref2$enableInterpola === void 0 ? true : _ref2$enableInterpola,
|
|
327
|
+
_ref2$useAveragePosit = _ref2.useAveragePosition,
|
|
328
|
+
useAveragePosition = _ref2$useAveragePosit === void 0 ? false : _ref2$useAveragePosit,
|
|
329
|
+
_ref2$centerHorizonta = _ref2.centerHorizontally,
|
|
330
|
+
centerHorizontally = _ref2$centerHorizonta === void 0 ? false : _ref2$centerHorizonta;
|
|
331
|
+
// Get current frame if not provided
|
|
332
|
+
var frameIndex = currentFrame;
|
|
333
|
+
if (frameIndex === null) {
|
|
334
|
+
try {
|
|
335
|
+
var remotionFrame = useCurrentFrame();
|
|
336
|
+
frameIndex = remotionFrame;
|
|
337
|
+
} catch (error) {
|
|
338
|
+
// useCurrentFrame not available (e.g., in testing environment)
|
|
339
|
+
frameIndex = 0;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Validate inputs
|
|
344
|
+
if (!(faceMetadata !== null && faceMetadata !== void 0 && (_faceMetadata$metadat4 = faceMetadata.metadata) !== null && _faceMetadata$metadat4 !== void 0 && _faceMetadata$metadat4.frames) || !(faceMetadata !== null && faceMetadata !== void 0 && (_faceMetadata$metadat5 = faceMetadata.metadata) !== null && _faceMetadata$metadat5 !== void 0 && _faceMetadata$metadat5.videoProperties)) {
|
|
345
|
+
return {
|
|
346
|
+
objectPosition: "center center",
|
|
347
|
+
debugInfo: {
|
|
348
|
+
error: "Invalid face metadata"
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
var _faceMetadata$metadat6 = faceMetadata.metadata,
|
|
353
|
+
frames = _faceMetadata$metadat6.frames,
|
|
354
|
+
videoProperties = _faceMetadata$metadat6.videoProperties;
|
|
355
|
+
var sourceWidth = videoProperties.width,
|
|
356
|
+
sourceHeight = videoProperties.height;
|
|
357
|
+
|
|
358
|
+
// Get face data for current frame or use average position
|
|
359
|
+
var faceData = useAveragePosition ? getAverageFaceData(frames) : getFaceDataForFrame(frames, frameIndex, enableInterpolation);
|
|
360
|
+
if (!faceData) {
|
|
361
|
+
return {
|
|
362
|
+
objectPosition: "center center",
|
|
363
|
+
debugInfo: {
|
|
364
|
+
error: "No face data available"
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Convert absolute face coordinates to relative (0-1 range)
|
|
370
|
+
var relativeFaceX = faceData.face_center[0] / sourceWidth;
|
|
371
|
+
var relativeFaceY = faceData.face_center[1] / sourceHeight;
|
|
372
|
+
|
|
373
|
+
// Calculate source and target aspect ratios
|
|
374
|
+
var sourceAspectRatio = sourceWidth / sourceHeight;
|
|
375
|
+
var targetAspectRatio = targetWidth / targetHeight;
|
|
376
|
+
|
|
377
|
+
// Calculate object-position values
|
|
378
|
+
var objectPositionX, objectPositionY;
|
|
379
|
+
if (sourceAspectRatio > targetAspectRatio) {
|
|
380
|
+
// Source is wider than target - video will be cropped horizontally
|
|
381
|
+
// The video height fills the container, width is cropped
|
|
382
|
+
// We need to calculate which part of the horizontal area to show
|
|
383
|
+
|
|
384
|
+
// Calculate the visible width as a fraction of the source width
|
|
385
|
+
var visibleWidthFraction = targetAspectRatio / sourceAspectRatio;
|
|
386
|
+
|
|
387
|
+
// For object-position, we need to think about it differently:
|
|
388
|
+
// object-position 0% shows the left edge, 100% shows the right edge
|
|
389
|
+
// We want to position the video so the face appears centered in the visible area
|
|
390
|
+
|
|
391
|
+
// Calculate how much we need to shift the video to center the face
|
|
392
|
+
// If face is at center (0.5), no shift needed -> 50%
|
|
393
|
+
// If face is at 0.25, we need to shift right -> less than 50%
|
|
394
|
+
// If face is at 0.75, we need to shift left -> more than 50%
|
|
395
|
+
|
|
396
|
+
// The key insight: object-position percentage represents where in the source
|
|
397
|
+
// video corresponds to the center of the target container
|
|
398
|
+
|
|
399
|
+
// To center the face, we want the face position to be at the center of the visible area
|
|
400
|
+
// So object-position should be set to the face's relative position
|
|
401
|
+
objectPositionX = Math.max(0, Math.min(100, relativeFaceX * 100));
|
|
402
|
+
objectPositionY = centerHorizontally ? 50 : relativeFaceY * 100;
|
|
403
|
+
} else {
|
|
404
|
+
// Source is taller than target - video will be cropped vertically
|
|
405
|
+
// The video width fills the container, height is cropped
|
|
406
|
+
|
|
407
|
+
// Calculate the visible height as a fraction of the source height
|
|
408
|
+
var visibleHeightFraction = sourceAspectRatio / targetAspectRatio;
|
|
409
|
+
|
|
410
|
+
// Calculate the face position within the visible area
|
|
411
|
+
var facePositionInVisibleArea = relativeFaceY / visibleHeightFraction;
|
|
412
|
+
|
|
413
|
+
// Convert to object-position percentage
|
|
414
|
+
objectPositionX = relativeFaceX * 100;
|
|
415
|
+
objectPositionY = centerHorizontally ? 50 : Math.max(0, Math.min(100, (facePositionInVisibleArea - 0.5) * 100 + 50));
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Clamp values to valid range
|
|
419
|
+
objectPositionX = Math.max(0, Math.min(100, objectPositionX));
|
|
420
|
+
objectPositionY = Math.max(0, Math.min(100, objectPositionY));
|
|
421
|
+
var objectPosition = "".concat(objectPositionX.toFixed(1), "% ").concat(objectPositionY.toFixed(1), "%");
|
|
422
|
+
return {
|
|
423
|
+
objectPosition: objectPosition,
|
|
424
|
+
debugInfo: {
|
|
425
|
+
frameIndex: useAveragePosition ? "AVERAGE" : frameIndex,
|
|
426
|
+
relativeFaceX: relativeFaceX.toFixed(3),
|
|
427
|
+
relativeFaceY: relativeFaceY.toFixed(3),
|
|
428
|
+
objectPositionX: objectPositionX.toFixed(1),
|
|
429
|
+
objectPositionY: objectPositionY.toFixed(1),
|
|
430
|
+
sourceAspectRatio: sourceAspectRatio.toFixed(3),
|
|
431
|
+
targetAspectRatio: targetAspectRatio.toFixed(3),
|
|
432
|
+
useAveragePosition: useAveragePosition,
|
|
433
|
+
centerHorizontally: centerHorizontally
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Helper function to get transforms for specific aspect ratios
|
|
440
|
+
*/
|
|
441
|
+
export var getFaceCenteredTransformsForAspectRatio = function getFaceCenteredTransformsForAspectRatio(aspectRatio, faceMetadata) {
|
|
442
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
443
|
+
var preset = ASPECT_RATIO_PRESETS[aspectRatio.toUpperCase()];
|
|
444
|
+
if (!preset) {
|
|
445
|
+
throw new Error("Unknown aspect ratio: ".concat(aspectRatio, ". Use LANDSCAPE, SQUARE, or PORTRAIT."));
|
|
446
|
+
}
|
|
447
|
+
return calculateFaceCenteredTransforms(_objectSpread({
|
|
448
|
+
faceMetadata: faceMetadata,
|
|
449
|
+
targetWidth: preset.width,
|
|
450
|
+
targetHeight: preset.height
|
|
451
|
+
}, options));
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Helper function to get object-position for specific aspect ratios
|
|
456
|
+
*/
|
|
457
|
+
export var getFaceCenteredObjectPositionForAspectRatio = function getFaceCenteredObjectPositionForAspectRatio(aspectRatio, faceMetadata) {
|
|
458
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
459
|
+
var preset = ASPECT_RATIO_PRESETS[aspectRatio.toUpperCase()];
|
|
460
|
+
if (!preset) {
|
|
461
|
+
throw new Error("Unknown aspect ratio: ".concat(aspectRatio, ". Use LANDSCAPE, SQUARE, or PORTRAIT."));
|
|
462
|
+
}
|
|
463
|
+
return calculateFaceCenteredObjectPosition(_objectSpread({
|
|
464
|
+
faceMetadata: faceMetadata,
|
|
465
|
+
targetWidth: preset.width,
|
|
466
|
+
targetHeight: preset.height
|
|
467
|
+
}, options));
|
|
468
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export var getContrastColor = function getContrastColor(hexColor) {
|
|
2
|
+
if (!hexColor) {
|
|
3
|
+
return hexColor;
|
|
4
|
+
}
|
|
5
|
+
// Convert hex color value to RGB values
|
|
6
|
+
var red = parseInt(hexColor.substring(1, 3), 16);
|
|
7
|
+
var green = parseInt(hexColor.substring(3, 5), 16);
|
|
8
|
+
var blue = parseInt(hexColor.substring(5, 7), 16);
|
|
9
|
+
|
|
10
|
+
// Calculate relative luminance of the color
|
|
11
|
+
var luminance = (0.2126 * red + 0.7152 * green + 0.0722 * blue) / 255;
|
|
12
|
+
|
|
13
|
+
// Choose white or black font color based on luminance
|
|
14
|
+
return luminance > 0.5 ? "#000000" : "#FFFFFF";
|
|
15
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
var videoOrientationTypes = {
|
|
8
|
+
SQUARE: "square",
|
|
9
|
+
PORTRAIT: "portrait",
|
|
10
|
+
LANDSCAPE: "landscape"
|
|
11
|
+
};
|
|
12
|
+
export var getVideoOrientation = function getVideoOrientation() {
|
|
13
|
+
var aspectRatio = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
|
|
14
|
+
var _aspectRatio$split = aspectRatio.split(":"),
|
|
15
|
+
_aspectRatio$split2 = _slicedToArray(_aspectRatio$split, 2),
|
|
16
|
+
width = _aspectRatio$split2[0],
|
|
17
|
+
height = _aspectRatio$split2[1];
|
|
18
|
+
if (!width || !height) return videoOrientationTypes.LANDSCAPE; // this is a legacy fallback
|
|
19
|
+
|
|
20
|
+
return Number(width) === Number(height) ? videoOrientationTypes.SQUARE : Number(width) > Number(height) ? videoOrientationTypes.LANDSCAPE : videoOrientationTypes.PORTRAIT;
|
|
21
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Utility to convert HEX to RGB array
|
|
2
|
+
export var hexToRGB = function hexToRGB(hex, alpha) {
|
|
3
|
+
var cleanedHex = hex.replace("#", "");
|
|
4
|
+
var bigint = parseInt(cleanedHex, 16);
|
|
5
|
+
var r = (bigint >> 16 & 255) / 255;
|
|
6
|
+
var g = (bigint >> 8 & 255) / 255;
|
|
7
|
+
var b = (bigint & 255) / 255;
|
|
8
|
+
return alpha ? [r, g, b, alpha] : [r, g, b];
|
|
9
|
+
};
|
|
10
|
+
export var hexToRgbHtml = function hexToRgbHtml(hex, alpha) {
|
|
11
|
+
return "rgba(".concat(hexToRGB(hex, alpha).map(function (color, index) {
|
|
12
|
+
return index === 3 ? color : color * 255;
|
|
13
|
+
}).join(","), ")");
|
|
14
|
+
};
|
|
15
|
+
function getBrightness(_ref) {
|
|
16
|
+
var r = _ref.r,
|
|
17
|
+
g = _ref.g,
|
|
18
|
+
b = _ref.b;
|
|
19
|
+
return 0.299 * r + 0.587 * g + 0.114 * b;
|
|
20
|
+
}
|
|
21
|
+
var compareHexColors = function compareHexColors(color1, color2) {
|
|
22
|
+
var rgb1 = hexToRGB(color1);
|
|
23
|
+
var rgb2 = hexToRGB(color2);
|
|
24
|
+
var brightness1 = getBrightness(rgb1);
|
|
25
|
+
var brightness2 = getBrightness(rgb2);
|
|
26
|
+
if (Math.abs(brightness1 - brightness2) < 0.0001) {
|
|
27
|
+
// They are essentially the same brightness
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
return brightness1 > brightness2 ? 1 : -1;
|
|
31
|
+
};
|
|
32
|
+
export var getBrighterColor = function getBrighterColor(color1, color2) {
|
|
33
|
+
var result = compareHexColors(color1, color2);
|
|
34
|
+
switch (result) {
|
|
35
|
+
case -1:
|
|
36
|
+
{
|
|
37
|
+
return color2;
|
|
38
|
+
}
|
|
39
|
+
case 0:
|
|
40
|
+
{
|
|
41
|
+
return color1;
|
|
42
|
+
}
|
|
43
|
+
case 1:
|
|
44
|
+
{
|
|
45
|
+
return color1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { hexToRGB } from "../helpers/hexToRgb.js";
|
|
2
|
+
var updateLottieColors = function updateLottieColors(data, layerKey, color) {
|
|
3
|
+
if (data && data.layers) {
|
|
4
|
+
var _data$assets$, _data$assets$$layers;
|
|
5
|
+
(_data$assets$ = data.assets[0]) === null || _data$assets$ === void 0 ? void 0 : (_data$assets$$layers = _data$assets$.layers) === null || _data$assets$$layers === void 0 ? void 0 : _data$assets$$layers.forEach(function (layer) {
|
|
6
|
+
var _layer$nm;
|
|
7
|
+
if (!((_layer$nm = layer.nm) !== null && _layer$nm !== void 0 && _layer$nm.includes(layerKey))) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (layer.shapes) {
|
|
11
|
+
layer.shapes.forEach(function (shape) {
|
|
12
|
+
if (shape.ty === "fl") {
|
|
13
|
+
// 'fl' stands for fill
|
|
14
|
+
shape.c.k = hexToRGB(color);
|
|
15
|
+
}
|
|
16
|
+
if (shape.ty === "st") {
|
|
17
|
+
// 'st' stands for stroke
|
|
18
|
+
shape.c.k = hexToRGB(color);
|
|
19
|
+
}
|
|
20
|
+
// Handle nested groups
|
|
21
|
+
if (shape.it) {
|
|
22
|
+
shape.it.forEach(function (item) {
|
|
23
|
+
if (item.ty === "fl") {
|
|
24
|
+
item.c.k = hexToRGB(color);
|
|
25
|
+
}
|
|
26
|
+
if (item.ty === "st") {
|
|
27
|
+
item.c.k = hexToRGB(color);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
export var useLottieReplaceColor = function useLottieReplaceColor(_ref) {
|
|
37
|
+
var animationData = _ref.animationData,
|
|
38
|
+
dynamicColors = _ref.dynamicColors;
|
|
39
|
+
var primaryColorKey = "PrimaryColor";
|
|
40
|
+
var accentColorKey = "AccentColor";
|
|
41
|
+
if (animationData && dynamicColors[primaryColorKey] && dynamicColors[accentColorKey]) {
|
|
42
|
+
updateLottieColors(animationData, primaryColorKey, dynamicColors[primaryColorKey]);
|
|
43
|
+
updateLottieColors(animationData, accentColorKey, dynamicColors[accentColorKey]);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useVideoConfig } from "remotion";
|
|
2
|
+
export var useOrientationBased = function useOrientationBased(perOrientationStyles) {
|
|
3
|
+
var _useVideoConfig = useVideoConfig(),
|
|
4
|
+
_useVideoConfig$props = _useVideoConfig.props.output,
|
|
5
|
+
_useVideoConfig$props2 = _useVideoConfig$props === void 0 ? {
|
|
6
|
+
orientation: window.screenplayProps.output.orientation
|
|
7
|
+
} : _useVideoConfig$props,
|
|
8
|
+
orientation = _useVideoConfig$props2.orientation;
|
|
9
|
+
var result;
|
|
10
|
+
switch (orientation) {
|
|
11
|
+
case "portrait":
|
|
12
|
+
{
|
|
13
|
+
result = perOrientationStyles.portrait;
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
case "square":
|
|
17
|
+
{
|
|
18
|
+
result = perOrientationStyles.square;
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
case "landscape":
|
|
22
|
+
{
|
|
23
|
+
result = perOrientationStyles.landscape;
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
result.orientation = orientation;
|
|
28
|
+
return result;
|
|
29
|
+
};
|