@make-pictures/kits 0.0.0-stage → 2.0.0
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/LICENSE +21 -0
- package/README.md +49 -2
- package/dist/chunk-3SUIELJV.mjs +601 -0
- package/dist/chunk-4Z3G6FPZ.mjs +485 -0
- package/dist/chunk-AHA23PHC.mjs +678 -0
- package/dist/chunk-CW623YVB.mjs +1124 -0
- package/dist/chunk-NNA7XXQB.mjs +1059 -0
- package/dist/chunk-S4CHTWOS.mjs +1237 -0
- package/dist/chunk-WAA7P5FT.mjs +912 -0
- package/dist/data-storytelling/AnimatedBarRace.d.ts +37 -0
- package/dist/data-storytelling/MetricComparisonCard.d.ts +29 -0
- package/dist/data-storytelling/TimelineTrack.d.ts +29 -0
- package/dist/data-storytelling/index.cjs +1224 -0
- package/dist/data-storytelling/index.d.ts +3 -0
- package/dist/data-storytelling/index.mjs +10 -0
- package/dist/index.cjs +6010 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.mjs +108 -0
- package/dist/isometric-3d/IsometricStudioEnvironment.d.ts +8 -0
- package/dist/isometric-3d/Stylized3DCharacter.d.ts +29 -0
- package/dist/isometric-3d/index.cjs +611 -0
- package/dist/isometric-3d/index.d.ts +2 -0
- package/dist/isometric-3d/index.mjs +8 -0
- package/dist/kinetic-typography/AnimatedMetricCounter.d.ts +36 -0
- package/dist/kinetic-typography/ImpactKeywordCard.d.ts +31 -0
- package/dist/kinetic-typography/WordByWordStage.d.ts +47 -0
- package/dist/kinetic-typography/index.cjs +665 -0
- package/dist/kinetic-typography/index.d.ts +3 -0
- package/dist/kinetic-typography/index.mjs +14 -0
- package/dist/motion-diagrams-2d/CameraRig.d.ts +34 -0
- package/dist/motion-diagrams-2d/CodePayloadToast.d.ts +14 -0
- package/dist/motion-diagrams-2d/DataFlowEdge.d.ts +24 -0
- package/dist/motion-diagrams-2d/NodeBox.d.ts +65 -0
- package/dist/motion-diagrams-2d/SystemNode.d.ts +21 -0
- package/dist/motion-diagrams-2d/index.cjs +1137 -0
- package/dist/motion-diagrams-2d/index.d.ts +5 -0
- package/dist/motion-diagrams-2d/index.mjs +28 -0
- package/dist/paper-diorama-3d/ImageCutout3D.d.ts +47 -0
- package/dist/paper-diorama-3d/PaperCutout3D.d.ts +62 -0
- package/dist/paper-diorama-3d/PaperPopUpBook3D.d.ts +51 -0
- package/dist/paper-diorama-3d/PaperStageLighting3D.d.ts +12 -0
- package/dist/paper-diorama-3d/index.cjs +1087 -0
- package/dist/paper-diorama-3d/index.d.ts +4 -0
- package/dist/paper-diorama-3d/index.mjs +34 -0
- package/dist/product-frames/BrowserFrame.d.ts +28 -0
- package/dist/product-frames/PhoneFrame.d.ts +23 -0
- package/dist/product-frames/ScreenSpotlightOverlay.d.ts +34 -0
- package/dist/product-frames/frameMedia.d.ts +24 -0
- package/dist/product-frames/index.cjs +507 -0
- package/dist/product-frames/index.d.ts +8 -0
- package/dist/product-frames/index.mjs +12 -0
- package/dist/vfx/CinematicLensOverlay.d.ts +29 -0
- package/dist/vfx/ParticleField.d.ts +18 -0
- package/dist/vfx/SceneTransition.d.ts +24 -0
- package/dist/vfx/StagePostProcessing3D.d.ts +44 -0
- package/dist/vfx/index.cjs +933 -0
- package/dist/vfx/index.d.ts +4 -0
- package/dist/vfx/index.mjs +14 -0
- package/package.json +95 -4
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ImageCutout3D,
|
|
3
|
+
PaperBookPageTurn3D,
|
|
4
|
+
PaperCameraRig3D,
|
|
5
|
+
PaperCloudCutout3D,
|
|
6
|
+
PaperCutout3D,
|
|
7
|
+
PaperMountainBackdrop3D,
|
|
8
|
+
PaperPineTree3D,
|
|
9
|
+
PaperStageLighting3D,
|
|
10
|
+
PopUpBookBase3D,
|
|
11
|
+
PopUpHinge3D,
|
|
12
|
+
buildPaperCutoutCompositeKey,
|
|
13
|
+
getFloorTexture,
|
|
14
|
+
getPaperTextureCacheStats,
|
|
15
|
+
prunePaperTextureCache,
|
|
16
|
+
serializePaperCutoutDeps
|
|
17
|
+
} from "../chunk-NNA7XXQB.mjs";
|
|
18
|
+
export {
|
|
19
|
+
ImageCutout3D,
|
|
20
|
+
PaperBookPageTurn3D,
|
|
21
|
+
PaperCameraRig3D,
|
|
22
|
+
PaperCloudCutout3D,
|
|
23
|
+
PaperCutout3D,
|
|
24
|
+
PaperMountainBackdrop3D,
|
|
25
|
+
PaperPineTree3D,
|
|
26
|
+
PaperStageLighting3D,
|
|
27
|
+
PopUpBookBase3D,
|
|
28
|
+
PopUpHinge3D,
|
|
29
|
+
buildPaperCutoutCompositeKey,
|
|
30
|
+
getFloorTexture,
|
|
31
|
+
getPaperTextureCacheStats,
|
|
32
|
+
prunePaperTextureCache,
|
|
33
|
+
serializePaperCutoutDeps
|
|
34
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type FrameMediaProps } from './frameMedia';
|
|
3
|
+
export interface BrowserFrameProps extends FrameMediaProps {
|
|
4
|
+
/** Address bar text, e.g. `'app.make.pictures/studio'` */
|
|
5
|
+
url?: string;
|
|
6
|
+
/** Optional tab / window title */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** Window chrome style (default `'macos'`) */
|
|
9
|
+
variant?: 'macos' | 'arc' | 'minimal';
|
|
10
|
+
/** Chrome theme (default `'dark'`) */
|
|
11
|
+
theme?: 'dark' | 'light';
|
|
12
|
+
/** Outer window width in px (default `1360`) */
|
|
13
|
+
width?: number;
|
|
14
|
+
/** Viewport aspect ratio below the toolbar (default `'16 / 10'`, ignored when `height` is set) */
|
|
15
|
+
aspectRatio?: string | number;
|
|
16
|
+
/** Explicit outer window height in px (overrides `aspectRatio`) */
|
|
17
|
+
height?: number;
|
|
18
|
+
/** Entrance frame (default `2`, so `frame === 0` renders `opacity: 0`) */
|
|
19
|
+
enterFrame?: number;
|
|
20
|
+
/** Accent used for the secure-lock dot & focus ring (default `'#38bdf8'`) */
|
|
21
|
+
accentColor?: string;
|
|
22
|
+
style?: React.CSSProperties;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Desktop / SaaS browser window chrome wrapping an `.mp4` screencast (`<OffthreadVideo />`),
|
|
26
|
+
* a screenshot (`<Img />`) or arbitrary children. Deterministic 60 FPS spring entrance.
|
|
27
|
+
*/
|
|
28
|
+
export declare const BrowserFrame: React.FC<BrowserFrameProps>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type FrameMediaProps } from './frameMedia';
|
|
3
|
+
export interface PhoneFrameProps extends FrameMediaProps {
|
|
4
|
+
/** Bezel style (default `'dynamic-island'`) */
|
|
5
|
+
variant?: 'dynamic-island' | 'minimal';
|
|
6
|
+
/** Bezel theme (default `'dark'` titanium) */
|
|
7
|
+
theme?: 'dark' | 'light';
|
|
8
|
+
/** Outer device width in px (default `520` — fits the 9:16 Golden Safe Box `x ∈ [40, 910]`) */
|
|
9
|
+
width?: number;
|
|
10
|
+
/** Device aspect ratio (default `'9 / 19.5'`, ignored when `height` is set) */
|
|
11
|
+
aspectRatio?: string | number;
|
|
12
|
+
/** Explicit outer device height in px */
|
|
13
|
+
height?: number;
|
|
14
|
+
/** Entrance frame (default `2`, so `frame === 0` renders `opacity: 0`) */
|
|
15
|
+
enterFrame?: number;
|
|
16
|
+
style?: React.CSSProperties;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Mobile 9:16 device bezel (titanium frame, Dynamic Island, home indicator) wrapping
|
|
20
|
+
* an `.mp4` screencast, screenshot or children. Default `520×1127` fits inside the
|
|
21
|
+
* vertical Golden Safe Box (`y ∈ [220, 1380]` → 1160 px tall).
|
|
22
|
+
*/
|
|
23
|
+
export declare const PhoneFrame: React.FC<PhoneFrameProps>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ScreenSpotlightOverlayProps {
|
|
3
|
+
/** Highlight left edge (percent `0..100` of parent by default, or px with `unit="px"`) */
|
|
4
|
+
x: number;
|
|
5
|
+
/** Highlight top edge */
|
|
6
|
+
y: number;
|
|
7
|
+
/** Highlight width */
|
|
8
|
+
width: number;
|
|
9
|
+
/** Highlight height */
|
|
10
|
+
height: number;
|
|
11
|
+
/** Coordinate unit (default `'percent'` — resolution-independent over any `.mp4`) */
|
|
12
|
+
unit?: 'percent' | 'px';
|
|
13
|
+
/** Frame (local to parent `<Sequence>`) when the spotlight starts */
|
|
14
|
+
startFrame: number;
|
|
15
|
+
/** Optional frame when the spotlight dismisses */
|
|
16
|
+
endFrame?: number;
|
|
17
|
+
/** Short 2–3 word callout pill */
|
|
18
|
+
label?: string;
|
|
19
|
+
/** Ring & pill accent (default `'#38bdf8'`) */
|
|
20
|
+
accentColor?: string;
|
|
21
|
+
/** Darkening applied outside the highlight (default `0.45`) */
|
|
22
|
+
dimOpacity?: number;
|
|
23
|
+
/** Highlight corner radius in px (default `14`) */
|
|
24
|
+
borderRadius?: number;
|
|
25
|
+
/** Label placement relative to the highlight (default `'auto'`) */
|
|
26
|
+
labelPosition?: 'auto' | 'top' | 'bottom';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Screen-Studio-style deterministic spotlight callout. Place as a child of
|
|
30
|
+
* `<BrowserFrame>` / `<PhoneFrame>` over a `.mp4` screencast. Dims everything outside
|
|
31
|
+
* the target rect (CSS `box-shadow` spread inside the parent's `overflow: hidden`),
|
|
32
|
+
* draws a breathing accent ring, and pops a short label pill.
|
|
33
|
+
*/
|
|
34
|
+
export declare const ScreenSpotlightOverlay: React.FC<ScreenSpotlightOverlayProps>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface FrameMediaProps {
|
|
3
|
+
/** `.mp4` / `.webm` screen recording (rendered via Remotion `<OffthreadVideo />`) */
|
|
4
|
+
videoSrc?: string;
|
|
5
|
+
/** Static screenshot (rendered via Remotion `<Img />`) */
|
|
6
|
+
imageSrc?: string;
|
|
7
|
+
/** Trim start of `videoSrc` in frames */
|
|
8
|
+
startFrom?: number;
|
|
9
|
+
/** Trim end of `videoSrc` in frames */
|
|
10
|
+
endAt?: number;
|
|
11
|
+
playbackRate?: number;
|
|
12
|
+
/** Mute embedded video audio (default `true` — screencasts rarely carry useful audio) */
|
|
13
|
+
muted?: boolean;
|
|
14
|
+
volume?: number;
|
|
15
|
+
/** CSS `object-fit` for media (default `'cover'`) */
|
|
16
|
+
objectFit?: React.CSSProperties['objectFit'];
|
|
17
|
+
/** Optional overlays (e.g. `<ScreenSpotlightOverlay />`) layered above the media */
|
|
18
|
+
children?: React.ReactNode;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Shared media viewport for `BrowserFrame` & `PhoneFrame`: video OR image OR children,
|
|
22
|
+
* with `children` always layered on top so callouts can annotate a live `.mp4`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const FrameMedia: React.FC<FrameMediaProps>;
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// packages/kits/src/product-frames/index.ts
|
|
21
|
+
var product_frames_exports = {};
|
|
22
|
+
__export(product_frames_exports, {
|
|
23
|
+
BrowserFrame: () => BrowserFrame,
|
|
24
|
+
FrameMedia: () => FrameMedia,
|
|
25
|
+
PhoneFrame: () => PhoneFrame,
|
|
26
|
+
ScreenSpotlightOverlay: () => ScreenSpotlightOverlay
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(product_frames_exports);
|
|
29
|
+
|
|
30
|
+
// packages/kits/src/product-frames/BrowserFrame.tsx
|
|
31
|
+
var import_remotion2 = require("remotion");
|
|
32
|
+
var import_core = require("@make-pictures/core");
|
|
33
|
+
|
|
34
|
+
// packages/kits/src/product-frames/frameMedia.tsx
|
|
35
|
+
var import_remotion = require("remotion");
|
|
36
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
37
|
+
var FrameMedia = ({
|
|
38
|
+
videoSrc,
|
|
39
|
+
imageSrc,
|
|
40
|
+
startFrom,
|
|
41
|
+
endAt,
|
|
42
|
+
playbackRate = 1,
|
|
43
|
+
muted = true,
|
|
44
|
+
volume = 1,
|
|
45
|
+
objectFit = "cover",
|
|
46
|
+
children
|
|
47
|
+
}) => {
|
|
48
|
+
const mediaStyle = {
|
|
49
|
+
width: "100%",
|
|
50
|
+
height: "100%",
|
|
51
|
+
objectFit,
|
|
52
|
+
display: "block"
|
|
53
|
+
};
|
|
54
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_remotion.AbsoluteFill, { style: { overflow: "hidden" }, children: [
|
|
55
|
+
videoSrc ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
56
|
+
import_remotion.OffthreadVideo,
|
|
57
|
+
{
|
|
58
|
+
src: videoSrc,
|
|
59
|
+
startFrom,
|
|
60
|
+
endAt,
|
|
61
|
+
playbackRate,
|
|
62
|
+
muted,
|
|
63
|
+
volume: muted ? 0 : volume,
|
|
64
|
+
style: mediaStyle
|
|
65
|
+
}
|
|
66
|
+
) : imageSrc ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_remotion.Img, { src: imageSrc, style: mediaStyle }) : null,
|
|
67
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_remotion.AbsoluteFill, { style: { overflow: "hidden" }, children }) : null
|
|
68
|
+
] });
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// packages/kits/src/product-frames/BrowserFrame.tsx
|
|
72
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
73
|
+
var TOOLBAR_HEIGHT = {
|
|
74
|
+
macos: 52,
|
|
75
|
+
arc: 46,
|
|
76
|
+
minimal: 36
|
|
77
|
+
};
|
|
78
|
+
function parseAspectRatio(ar) {
|
|
79
|
+
if (typeof ar === "number") return ar > 0 ? ar : 1.6;
|
|
80
|
+
const parts = ar.split("/").map((p) => parseFloat(p.trim()));
|
|
81
|
+
if (parts.length === 2 && parts[0] > 0 && parts[1] > 0) {
|
|
82
|
+
return parts[0] / parts[1];
|
|
83
|
+
}
|
|
84
|
+
const single = parseFloat(ar);
|
|
85
|
+
return single > 0 ? single : 1.6;
|
|
86
|
+
}
|
|
87
|
+
var BrowserFrame = ({
|
|
88
|
+
url,
|
|
89
|
+
title,
|
|
90
|
+
variant = "macos",
|
|
91
|
+
theme = "dark",
|
|
92
|
+
width = 1360,
|
|
93
|
+
aspectRatio = "16 / 10",
|
|
94
|
+
height,
|
|
95
|
+
enterFrame = 2,
|
|
96
|
+
accentColor = "#38bdf8",
|
|
97
|
+
style,
|
|
98
|
+
...media
|
|
99
|
+
}) => {
|
|
100
|
+
const frame = (0, import_remotion2.useCurrentFrame)();
|
|
101
|
+
const { fps } = (0, import_remotion2.useVideoConfig)();
|
|
102
|
+
(0, import_core.useStudioFontsReady)();
|
|
103
|
+
const enter = (0, import_remotion2.spring)({
|
|
104
|
+
frame: frame - Math.max(2, enterFrame),
|
|
105
|
+
fps,
|
|
106
|
+
config: import_core.SPRING_PRESETS.snappy
|
|
107
|
+
});
|
|
108
|
+
const isDark = theme === "dark";
|
|
109
|
+
const toolbarH = TOOLBAR_HEIGHT[variant];
|
|
110
|
+
const viewportH = typeof height === "number" ? Math.max(40, height - toolbarH) : Math.round(width / parseAspectRatio(aspectRatio));
|
|
111
|
+
const outerH = viewportH + toolbarH;
|
|
112
|
+
const chromeBg = isDark ? "#14161F" : "#F1F5F9";
|
|
113
|
+
const chromeBorder = isDark ? "rgba(255,255,255,0.08)" : "rgba(15,23,42,0.08)";
|
|
114
|
+
const pillBg = isDark ? "rgba(255,255,255,0.06)" : "#FFFFFF";
|
|
115
|
+
const textColor = isDark ? "#CBD5E1" : "#334155";
|
|
116
|
+
const mutedText = isDark ? "#64748B" : "#94A3B8";
|
|
117
|
+
const radius = variant === "arc" ? 22 : variant === "minimal" ? 14 : 18;
|
|
118
|
+
const translateY = (0, import_remotion2.interpolate)(enter, [0, 1], [36, 0]);
|
|
119
|
+
const scale = (0, import_remotion2.interpolate)(enter, [0, 1], [0.94, 1]);
|
|
120
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
121
|
+
"div",
|
|
122
|
+
{
|
|
123
|
+
style: {
|
|
124
|
+
position: "relative",
|
|
125
|
+
width,
|
|
126
|
+
height: outerH,
|
|
127
|
+
borderRadius: radius,
|
|
128
|
+
overflow: "hidden",
|
|
129
|
+
boxSizing: "border-box",
|
|
130
|
+
backgroundColor: isDark ? "#0B0D14" : "#FFFFFF",
|
|
131
|
+
border: `1px solid ${chromeBorder}`,
|
|
132
|
+
boxShadow: isDark ? "0 50px 120px -20px rgba(0,0,0,0.75), 0 0 0 1px rgba(255,255,255,0.04) inset" : "0 40px 100px -20px rgba(15,23,42,0.28), 0 8px 24px -8px rgba(15,23,42,0.12)",
|
|
133
|
+
opacity: enter,
|
|
134
|
+
transform: `translate3d(0, ${translateY.toFixed(2)}px, 0) scale(${scale.toFixed(4)})`,
|
|
135
|
+
transformOrigin: "center center",
|
|
136
|
+
...style
|
|
137
|
+
},
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
140
|
+
"div",
|
|
141
|
+
{
|
|
142
|
+
style: {
|
|
143
|
+
position: "absolute",
|
|
144
|
+
left: 0,
|
|
145
|
+
right: 0,
|
|
146
|
+
top: 0,
|
|
147
|
+
height: toolbarH,
|
|
148
|
+
display: "flex",
|
|
149
|
+
alignItems: "center",
|
|
150
|
+
gap: 14,
|
|
151
|
+
padding: "0 18px",
|
|
152
|
+
boxSizing: "border-box",
|
|
153
|
+
backgroundColor: variant === "arc" ? "transparent" : chromeBg,
|
|
154
|
+
borderBottom: variant === "arc" ? "none" : `1px solid ${chromeBorder}`,
|
|
155
|
+
fontFamily: import_core.FONTS.sans
|
|
156
|
+
},
|
|
157
|
+
children: [
|
|
158
|
+
variant !== "minimal" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: 8, flexShrink: 0 }, children: ["#FF5F57", "#FEBC2E", "#28C840"].map((c) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
159
|
+
"div",
|
|
160
|
+
{
|
|
161
|
+
style: {
|
|
162
|
+
width: 13,
|
|
163
|
+
height: 13,
|
|
164
|
+
borderRadius: 9999,
|
|
165
|
+
backgroundColor: c,
|
|
166
|
+
boxShadow: "inset 0 0 0 0.5px rgba(0,0,0,0.25)"
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
c
|
|
170
|
+
)) }),
|
|
171
|
+
title && variant === "macos" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
172
|
+
"div",
|
|
173
|
+
{
|
|
174
|
+
style: {
|
|
175
|
+
fontSize: 14,
|
|
176
|
+
fontWeight: 600,
|
|
177
|
+
color: mutedText,
|
|
178
|
+
whiteSpace: "nowrap",
|
|
179
|
+
maxWidth: 220,
|
|
180
|
+
overflow: "hidden",
|
|
181
|
+
textOverflow: "ellipsis"
|
|
182
|
+
},
|
|
183
|
+
children: title
|
|
184
|
+
}
|
|
185
|
+
),
|
|
186
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { flex: 1, display: "flex", justifyContent: "center" }, children: (url || variant !== "minimal") && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
187
|
+
"div",
|
|
188
|
+
{
|
|
189
|
+
style: {
|
|
190
|
+
display: "flex",
|
|
191
|
+
alignItems: "center",
|
|
192
|
+
gap: 8,
|
|
193
|
+
height: variant === "minimal" ? 22 : 30,
|
|
194
|
+
minWidth: Math.min(520, width * 0.42),
|
|
195
|
+
maxWidth: width * 0.6,
|
|
196
|
+
padding: "0 16px",
|
|
197
|
+
borderRadius: 9999,
|
|
198
|
+
backgroundColor: pillBg,
|
|
199
|
+
border: `1px solid ${chromeBorder}`,
|
|
200
|
+
boxSizing: "border-box",
|
|
201
|
+
fontFamily: import_core.FONTS.mono,
|
|
202
|
+
fontSize: variant === "minimal" ? 12 : 14,
|
|
203
|
+
fontWeight: 500,
|
|
204
|
+
color: textColor,
|
|
205
|
+
justifyContent: "center",
|
|
206
|
+
whiteSpace: "nowrap",
|
|
207
|
+
overflow: "hidden"
|
|
208
|
+
},
|
|
209
|
+
children: [
|
|
210
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
211
|
+
"span",
|
|
212
|
+
{
|
|
213
|
+
style: {
|
|
214
|
+
width: 8,
|
|
215
|
+
height: 8,
|
|
216
|
+
borderRadius: 9999,
|
|
217
|
+
backgroundColor: accentColor,
|
|
218
|
+
flexShrink: 0
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
),
|
|
222
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: url ?? title ?? "" })
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
) }),
|
|
226
|
+
variant !== "minimal" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { width: 55, flexShrink: 0 } })
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
),
|
|
230
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
231
|
+
"div",
|
|
232
|
+
{
|
|
233
|
+
style: {
|
|
234
|
+
position: "absolute",
|
|
235
|
+
left: variant === "arc" ? 8 : 0,
|
|
236
|
+
right: variant === "arc" ? 8 : 0,
|
|
237
|
+
bottom: variant === "arc" ? 8 : 0,
|
|
238
|
+
top: toolbarH,
|
|
239
|
+
borderRadius: variant === "arc" ? 14 : 0,
|
|
240
|
+
overflow: "hidden",
|
|
241
|
+
backgroundColor: isDark ? "#05060A" : "#F8FAFC"
|
|
242
|
+
},
|
|
243
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FrameMedia, { ...media })
|
|
244
|
+
}
|
|
245
|
+
)
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// packages/kits/src/product-frames/PhoneFrame.tsx
|
|
252
|
+
var import_remotion3 = require("remotion");
|
|
253
|
+
var import_core2 = require("@make-pictures/core");
|
|
254
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
255
|
+
function parseAspectRatio2(ar) {
|
|
256
|
+
if (typeof ar === "number") return ar > 0 ? ar : 9 / 19.5;
|
|
257
|
+
const parts = ar.split("/").map((p) => parseFloat(p.trim()));
|
|
258
|
+
if (parts.length === 2 && parts[0] > 0 && parts[1] > 0) {
|
|
259
|
+
return parts[0] / parts[1];
|
|
260
|
+
}
|
|
261
|
+
const single = parseFloat(ar);
|
|
262
|
+
return single > 0 ? single : 9 / 19.5;
|
|
263
|
+
}
|
|
264
|
+
var PhoneFrame = ({
|
|
265
|
+
variant = "dynamic-island",
|
|
266
|
+
theme = "dark",
|
|
267
|
+
width = 520,
|
|
268
|
+
aspectRatio = "9 / 19.5",
|
|
269
|
+
height,
|
|
270
|
+
enterFrame = 2,
|
|
271
|
+
style,
|
|
272
|
+
...media
|
|
273
|
+
}) => {
|
|
274
|
+
const frame = (0, import_remotion3.useCurrentFrame)();
|
|
275
|
+
const { fps } = (0, import_remotion3.useVideoConfig)();
|
|
276
|
+
const enter = (0, import_remotion3.spring)({
|
|
277
|
+
frame: frame - Math.max(2, enterFrame),
|
|
278
|
+
fps,
|
|
279
|
+
config: import_core2.SPRING_PRESETS.snappy
|
|
280
|
+
});
|
|
281
|
+
const isDark = theme === "dark";
|
|
282
|
+
const outerH = typeof height === "number" ? height : Math.round(width / parseAspectRatio2(aspectRatio));
|
|
283
|
+
const bezel = Math.max(10, Math.round(width * 0.03));
|
|
284
|
+
const outerRadius = Math.round(width * 0.135);
|
|
285
|
+
const innerRadius = Math.max(8, outerRadius - bezel);
|
|
286
|
+
const titanium = isDark ? "linear-gradient(145deg, #3A3D46 0%, #1C1E24 40%, #2A2C33 70%, #45484F 100%)" : "linear-gradient(145deg, #F1F2F4 0%, #C9CCD2 45%, #E4E6EA 75%, #FFFFFF 100%)";
|
|
287
|
+
const translateY = (0, import_remotion3.interpolate)(enter, [0, 1], [42, 0]);
|
|
288
|
+
const scale = (0, import_remotion3.interpolate)(enter, [0, 1], [0.93, 1]);
|
|
289
|
+
const islandW = Math.round(width * 0.3);
|
|
290
|
+
const islandH = Math.round(width * 0.068);
|
|
291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
292
|
+
"div",
|
|
293
|
+
{
|
|
294
|
+
style: {
|
|
295
|
+
position: "relative",
|
|
296
|
+
width,
|
|
297
|
+
height: outerH,
|
|
298
|
+
borderRadius: outerRadius,
|
|
299
|
+
padding: bezel,
|
|
300
|
+
boxSizing: "border-box",
|
|
301
|
+
background: titanium,
|
|
302
|
+
boxShadow: isDark ? "0 60px 120px -24px rgba(0,0,0,0.75), inset 0 0 0 1.5px rgba(255,255,255,0.12)" : "0 50px 110px -24px rgba(15,23,42,0.32), inset 0 0 0 1.5px rgba(255,255,255,0.8)",
|
|
303
|
+
opacity: enter,
|
|
304
|
+
transform: `translate3d(0, ${translateY.toFixed(2)}px, 0) scale(${scale.toFixed(4)})`,
|
|
305
|
+
transformOrigin: "center center",
|
|
306
|
+
...style
|
|
307
|
+
},
|
|
308
|
+
children: [
|
|
309
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
310
|
+
"div",
|
|
311
|
+
{
|
|
312
|
+
style: {
|
|
313
|
+
position: "absolute",
|
|
314
|
+
left: -3,
|
|
315
|
+
top: outerH * 0.2,
|
|
316
|
+
width: 4,
|
|
317
|
+
height: outerH * 0.06,
|
|
318
|
+
borderRadius: 4,
|
|
319
|
+
background: isDark ? "#2A2C33" : "#C9CCD2"
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
),
|
|
323
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
324
|
+
"div",
|
|
325
|
+
{
|
|
326
|
+
style: {
|
|
327
|
+
position: "absolute",
|
|
328
|
+
right: -3,
|
|
329
|
+
top: outerH * 0.26,
|
|
330
|
+
width: 4,
|
|
331
|
+
height: outerH * 0.1,
|
|
332
|
+
borderRadius: 4,
|
|
333
|
+
background: isDark ? "#2A2C33" : "#C9CCD2"
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
),
|
|
337
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
338
|
+
"div",
|
|
339
|
+
{
|
|
340
|
+
style: {
|
|
341
|
+
position: "relative",
|
|
342
|
+
width: "100%",
|
|
343
|
+
height: "100%",
|
|
344
|
+
borderRadius: innerRadius,
|
|
345
|
+
overflow: "hidden",
|
|
346
|
+
backgroundColor: "#000000"
|
|
347
|
+
},
|
|
348
|
+
children: [
|
|
349
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FrameMedia, { ...media }),
|
|
350
|
+
variant === "dynamic-island" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
351
|
+
"div",
|
|
352
|
+
{
|
|
353
|
+
style: {
|
|
354
|
+
position: "absolute",
|
|
355
|
+
top: Math.round(width * 0.03),
|
|
356
|
+
left: "50%",
|
|
357
|
+
width: islandW,
|
|
358
|
+
height: islandH,
|
|
359
|
+
marginLeft: -islandW / 2,
|
|
360
|
+
borderRadius: 9999,
|
|
361
|
+
backgroundColor: "#000000",
|
|
362
|
+
boxShadow: "0 0 0 1px rgba(255,255,255,0.04)",
|
|
363
|
+
zIndex: 5
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
),
|
|
367
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
368
|
+
"div",
|
|
369
|
+
{
|
|
370
|
+
style: {
|
|
371
|
+
position: "absolute",
|
|
372
|
+
bottom: Math.round(width * 0.022),
|
|
373
|
+
left: "50%",
|
|
374
|
+
width: Math.round(width * 0.34),
|
|
375
|
+
height: Math.max(4, Math.round(width * 0.011)),
|
|
376
|
+
marginLeft: -Math.round(width * 0.17),
|
|
377
|
+
borderRadius: 9999,
|
|
378
|
+
backgroundColor: "rgba(255,255,255,0.82)",
|
|
379
|
+
boxShadow: "0 0 0 0.5px rgba(0,0,0,0.3)",
|
|
380
|
+
zIndex: 5
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
)
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
)
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
);
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
// packages/kits/src/product-frames/ScreenSpotlightOverlay.tsx
|
|
393
|
+
var import_remotion4 = require("remotion");
|
|
394
|
+
var import_core3 = require("@make-pictures/core");
|
|
395
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
396
|
+
var ScreenSpotlightOverlay = ({
|
|
397
|
+
x,
|
|
398
|
+
y,
|
|
399
|
+
width,
|
|
400
|
+
height,
|
|
401
|
+
unit = "percent",
|
|
402
|
+
startFrame,
|
|
403
|
+
endFrame,
|
|
404
|
+
label,
|
|
405
|
+
accentColor = "#38bdf8",
|
|
406
|
+
dimOpacity = 0.45,
|
|
407
|
+
borderRadius = 14,
|
|
408
|
+
labelPosition = "auto"
|
|
409
|
+
}) => {
|
|
410
|
+
const frame = (0, import_remotion4.useCurrentFrame)();
|
|
411
|
+
const { fps } = (0, import_remotion4.useVideoConfig)();
|
|
412
|
+
(0, import_core3.useStudioFontsReady)();
|
|
413
|
+
const effectiveStart = Math.max(2, startFrame);
|
|
414
|
+
const enter = (0, import_remotion4.spring)({
|
|
415
|
+
frame: frame - effectiveStart,
|
|
416
|
+
fps,
|
|
417
|
+
config: import_core3.SPRING_PRESETS.smooth
|
|
418
|
+
});
|
|
419
|
+
const exit = typeof endFrame === "number" ? (0, import_remotion4.spring)({ frame: frame - endFrame, fps, config: import_core3.SPRING_PRESETS.smooth }) : 0;
|
|
420
|
+
const visibility = Math.max(0, Math.min(1, enter * (1 - exit)));
|
|
421
|
+
if (visibility <= 5e-3) {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
const u = unit === "percent" ? "%" : "px";
|
|
425
|
+
const grow = (0, import_remotion4.interpolate)(enter, [0, 1], [unit === "percent" ? 3 : 24, 0]);
|
|
426
|
+
const left = x - grow;
|
|
427
|
+
const top = y - grow;
|
|
428
|
+
const w = width + grow * 2;
|
|
429
|
+
const h = height + grow * 2;
|
|
430
|
+
const f60 = frame * (60 / Math.max(1, fps));
|
|
431
|
+
const breathe = 0.5 + 0.5 * Math.sin(f60 * 0.045);
|
|
432
|
+
const ringGlow = 14 + breathe * 10;
|
|
433
|
+
const labelPop = (0, import_remotion4.spring)({
|
|
434
|
+
frame: frame - effectiveStart - 8,
|
|
435
|
+
fps,
|
|
436
|
+
config: import_core3.SPRING_PRESETS.snappy
|
|
437
|
+
});
|
|
438
|
+
const placeTop = labelPosition === "top" || labelPosition === "auto" && (unit === "percent" ? y > 18 : y > 90);
|
|
439
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
440
|
+
"div",
|
|
441
|
+
{
|
|
442
|
+
style: {
|
|
443
|
+
position: "absolute",
|
|
444
|
+
inset: 0,
|
|
445
|
+
overflow: "hidden",
|
|
446
|
+
pointerEvents: "none",
|
|
447
|
+
zIndex: 10
|
|
448
|
+
},
|
|
449
|
+
children: [
|
|
450
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
451
|
+
"div",
|
|
452
|
+
{
|
|
453
|
+
style: {
|
|
454
|
+
position: "absolute",
|
|
455
|
+
left: `${left}${u}`,
|
|
456
|
+
top: `${top}${u}`,
|
|
457
|
+
width: `${w}${u}`,
|
|
458
|
+
height: `${h}${u}`,
|
|
459
|
+
borderRadius,
|
|
460
|
+
boxShadow: `0 0 0 9999px rgba(2, 6, 23, ${(dimOpacity * visibility).toFixed(3)})`
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
),
|
|
464
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
465
|
+
"div",
|
|
466
|
+
{
|
|
467
|
+
style: {
|
|
468
|
+
position: "absolute",
|
|
469
|
+
left: `${left}${u}`,
|
|
470
|
+
top: `${top}${u}`,
|
|
471
|
+
width: `${w}${u}`,
|
|
472
|
+
height: `${h}${u}`,
|
|
473
|
+
borderRadius,
|
|
474
|
+
border: `3px solid ${accentColor}`,
|
|
475
|
+
boxSizing: "border-box",
|
|
476
|
+
boxShadow: `0 0 ${ringGlow.toFixed(1)}px ${accentColor}AA, inset 0 0 ${(ringGlow * 0.6).toFixed(1)}px ${accentColor}55`,
|
|
477
|
+
opacity: visibility
|
|
478
|
+
},
|
|
479
|
+
children: label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
480
|
+
"div",
|
|
481
|
+
{
|
|
482
|
+
style: {
|
|
483
|
+
position: "absolute",
|
|
484
|
+
left: "50%",
|
|
485
|
+
...placeTop ? { bottom: "100%", marginBottom: 12 } : { top: "100%", marginTop: 12 },
|
|
486
|
+
transform: `translateX(-50%) translateY(${(0, import_remotion4.interpolate)(labelPop, [0, 1], [placeTop ? 8 : -8, 0]).toFixed(2)}px) scale(${(0, import_remotion4.interpolate)(labelPop, [0, 1], [0.85, 1]).toFixed(3)})`,
|
|
487
|
+
opacity: labelPop * visibility,
|
|
488
|
+
padding: "7px 16px",
|
|
489
|
+
borderRadius: 9999,
|
|
490
|
+
backgroundColor: accentColor,
|
|
491
|
+
color: "#020617",
|
|
492
|
+
fontFamily: import_core3.FONTS.sans,
|
|
493
|
+
fontSize: 18,
|
|
494
|
+
fontWeight: 800,
|
|
495
|
+
letterSpacing: "-0.01em",
|
|
496
|
+
whiteSpace: "nowrap",
|
|
497
|
+
boxShadow: `0 10px 28px ${accentColor}66`
|
|
498
|
+
},
|
|
499
|
+
children: label
|
|
500
|
+
}
|
|
501
|
+
)
|
|
502
|
+
}
|
|
503
|
+
)
|
|
504
|
+
]
|
|
505
|
+
}
|
|
506
|
+
);
|
|
507
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { BrowserFrame } from './BrowserFrame';
|
|
2
|
+
export type { BrowserFrameProps } from './BrowserFrame';
|
|
3
|
+
export { PhoneFrame } from './PhoneFrame';
|
|
4
|
+
export type { PhoneFrameProps } from './PhoneFrame';
|
|
5
|
+
export { ScreenSpotlightOverlay } from './ScreenSpotlightOverlay';
|
|
6
|
+
export type { ScreenSpotlightOverlayProps } from './ScreenSpotlightOverlay';
|
|
7
|
+
export { FrameMedia } from './frameMedia';
|
|
8
|
+
export type { FrameMediaProps } from './frameMedia';
|