scrolltube 2.0.15
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/AGENTS.md +46 -0
- package/CLAUDE.md +1 -0
- package/README.md +148 -0
- package/dist/cli/_not_used_api.d.ts +1 -0
- package/dist/cli/_not_used_api.js +21 -0
- package/dist/core/CoreEngine.d.ts +74 -0
- package/dist/core/CoreOrchestrator.d.ts +39 -0
- package/dist/core/WebGLRenderer.d.ts +20 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/scrolltube.umd.min.js +14 -0
- package/dist/core/types.d.ts +102 -0
- package/dist/core/types.js +8 -0
- package/dist/pipeline/browser-driver.d.ts +31 -0
- package/dist/pipeline/browser-driver.js +184 -0
- package/dist/pipeline/cloud-service.d.ts +17 -0
- package/dist/pipeline/cloud-service.js +109 -0
- package/dist/pipeline/index.d.ts +21 -0
- package/dist/pipeline/index.js +227 -0
- package/dist/pipeline/node-driver.d.ts +18 -0
- package/dist/pipeline/node-driver.js +108 -0
- package/dist/pipeline/types.d.ts +43 -0
- package/dist/pipeline/types.js +2 -0
- package/dist/react/ScrollTubeProvider.d.ts +49 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +14 -0
- package/docs/ai-integration.md +72 -0
- package/docs/architecture.md +55 -0
- package/docs/asset-pipeline.md +105 -0
- package/docs/react-integration.md +89 -0
- package/package.json +99 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AssetPipeline = void 0;
|
|
37
|
+
const cloud_service_1 = require("./cloud-service");
|
|
38
|
+
class AssetPipeline {
|
|
39
|
+
driver;
|
|
40
|
+
options;
|
|
41
|
+
cloud;
|
|
42
|
+
constructor(options = {}) {
|
|
43
|
+
this.options = options;
|
|
44
|
+
this.cloud = new cloud_service_1.CloudService({ apiKey: options.apiKey, proxyUrl: options.proxyUrl });
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* INITIALIZE DRIVER
|
|
48
|
+
* Detects environment and loads the appropriate driver dynamically.
|
|
49
|
+
*/
|
|
50
|
+
async init() {
|
|
51
|
+
if (this.driver)
|
|
52
|
+
return;
|
|
53
|
+
if (typeof window !== 'undefined') {
|
|
54
|
+
// Browser Environment
|
|
55
|
+
try {
|
|
56
|
+
// @ts-ignore - Assuming BrowserDriver will exist in same folder
|
|
57
|
+
const { BrowserDriver } = await Promise.resolve().then(() => __importStar(require('./browser-driver')));
|
|
58
|
+
this.driver = new BrowserDriver();
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
throw new Error('Could not load BrowserDriver. Ensure @scrolltube/pipeline/browser is available.');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Node Environment
|
|
66
|
+
try {
|
|
67
|
+
const { NodeDriver } = await Promise.resolve().then(() => __importStar(require('./node-driver')));
|
|
68
|
+
this.driver = new NodeDriver();
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
throw new Error('Could not load NodeDriver. Ensure @scrolltube/pipeline/node (sharp, ffmpeg) is installed.');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
report(step, percent, message) {
|
|
76
|
+
if (this.options.onProgress) {
|
|
77
|
+
this.options.onProgress({ step, percent, message });
|
|
78
|
+
}
|
|
79
|
+
console.log(`[${step}] ${percent}% - ${message}`);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* THE MAIN ORCHESTRATOR
|
|
83
|
+
*/
|
|
84
|
+
async create(opts) {
|
|
85
|
+
await this.init();
|
|
86
|
+
const { input, name, track, depth, step = 1 } = opts;
|
|
87
|
+
const outDir = this.driver.resolve(name);
|
|
88
|
+
const tempDir = this.driver.join(outDir, '.temp-frames');
|
|
89
|
+
const framesDir = this.driver.join(tempDir, 'frames');
|
|
90
|
+
const depthsDir = this.driver.join(tempDir, 'depths');
|
|
91
|
+
this.report('initializing', 0, `Creating project: ${name}`);
|
|
92
|
+
await this.driver.mkdir(outDir);
|
|
93
|
+
await this.driver.mkdir(tempDir);
|
|
94
|
+
await this.driver.mkdir(framesDir);
|
|
95
|
+
await this.driver.mkdir(depthsDir);
|
|
96
|
+
// 1. FRAME EXTRACTION
|
|
97
|
+
this.report('extracting', 10, 'Extracting frames from source...');
|
|
98
|
+
await this.driver.extractFrames(input, framesDir);
|
|
99
|
+
// 2. AI TRACKING & DEPTH
|
|
100
|
+
let trackingData = [];
|
|
101
|
+
let isDepthActive = false;
|
|
102
|
+
if (track || depth) {
|
|
103
|
+
this.report('tracking', 30, 'Performing AI analysis...');
|
|
104
|
+
if (track) {
|
|
105
|
+
trackingData = await this.cloud.trackSubject(input, this.driver, track);
|
|
106
|
+
}
|
|
107
|
+
if (depth) {
|
|
108
|
+
this.report('depth', 40, 'Generating depth maps...');
|
|
109
|
+
const depthVideoUrl = await this.cloud.generateDepthMap(input, this.driver);
|
|
110
|
+
// Download and extract depth frames
|
|
111
|
+
const response = await fetch(depthVideoUrl);
|
|
112
|
+
const buffer = await response.arrayBuffer();
|
|
113
|
+
const depthVideoPath = this.driver.join(tempDir, 'depth_video.mp4');
|
|
114
|
+
await this.driver.writeFile(depthVideoPath, new Uint8Array(buffer));
|
|
115
|
+
await this.driver.extractFrames(depthVideoPath, depthsDir);
|
|
116
|
+
isDepthActive = true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Default tracking if none
|
|
120
|
+
if (trackingData.length === 0) {
|
|
121
|
+
const files = await this.driver.readdir(framesDir);
|
|
122
|
+
const frameFiles = files.filter(f => f.startsWith('frame_'));
|
|
123
|
+
trackingData = frameFiles.map((_, i) => ({ frame: i, x: 0.5, y: 0.5, scale: 0 }));
|
|
124
|
+
}
|
|
125
|
+
// 3. VARIANT GENERATION
|
|
126
|
+
this.report('processing', 60, 'Generating optimized variants...');
|
|
127
|
+
const variants = await this.processVariants(tempDir, trackingData, {
|
|
128
|
+
step,
|
|
129
|
+
depth: isDepthActive,
|
|
130
|
+
variants: this.normalizeVariants(opts.variants),
|
|
131
|
+
outDir
|
|
132
|
+
});
|
|
133
|
+
// 4. SAVE CONFIG
|
|
134
|
+
this.report('saving', 90, 'Finalizing project configuration...');
|
|
135
|
+
const config = await this.saveConfig(variants, outDir);
|
|
136
|
+
// Cleanup
|
|
137
|
+
await this.driver.remove(tempDir);
|
|
138
|
+
this.report('saving', 100, 'Project ready!');
|
|
139
|
+
if (opts.outputZip && this.driver.zipProject) {
|
|
140
|
+
return await this.driver.zipProject(outDir);
|
|
141
|
+
}
|
|
142
|
+
return config;
|
|
143
|
+
}
|
|
144
|
+
normalizeVariants(v) {
|
|
145
|
+
if (v.length === 0)
|
|
146
|
+
return [];
|
|
147
|
+
if (typeof v[0] === 'object')
|
|
148
|
+
return v;
|
|
149
|
+
// Convert numbers to baseline portrait/landscape pairs
|
|
150
|
+
const res = v;
|
|
151
|
+
const normalized = [];
|
|
152
|
+
res.forEach(r => {
|
|
153
|
+
normalized.push({
|
|
154
|
+
id: `${r}p_p`, width: r, height: Math.round(r * (16 / 9)),
|
|
155
|
+
orientation: 'portrait', aspectRatio: '9:16', media: '(orientation: portrait)'
|
|
156
|
+
});
|
|
157
|
+
normalized.push({
|
|
158
|
+
id: `${r}p_l`, width: Math.round(r * (16 / 9)), height: r,
|
|
159
|
+
orientation: 'landscape', aspectRatio: '16:9', media: '(orientation: landscape)'
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
return normalized;
|
|
163
|
+
}
|
|
164
|
+
async processVariants(tempDir, trackingData, options) {
|
|
165
|
+
const { step, outDir } = options;
|
|
166
|
+
const framesDir = this.driver.join(tempDir, 'frames');
|
|
167
|
+
const depthsDir = this.driver.join(tempDir, 'depths');
|
|
168
|
+
const allFiles = await this.driver.readdir(framesDir);
|
|
169
|
+
const allFrames = allFiles.filter(f => f.startsWith('frame_')).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
|
|
170
|
+
const framesToProcess = allFrames.filter((_, i) => i % step === 0);
|
|
171
|
+
const assetVariants = [];
|
|
172
|
+
for (const config of options.variants) {
|
|
173
|
+
const variantDir = this.driver.join(outDir, config.id);
|
|
174
|
+
await this.driver.mkdir(variantDir);
|
|
175
|
+
const variantTracking = [];
|
|
176
|
+
for (let i = 0; i < framesToProcess.length; i++) {
|
|
177
|
+
const originalIndex = i * step;
|
|
178
|
+
const frameName = framesToProcess[i];
|
|
179
|
+
const framePath = this.driver.join(framesDir, frameName);
|
|
180
|
+
const targetPath = this.driver.join(variantDir, `index_${i}.webp`);
|
|
181
|
+
const subject = trackingData.find(f => f.frame === originalIndex) || { frame: originalIndex, x: 0.5, y: 0.5, scale: 0 };
|
|
182
|
+
const imageBuffer = await this.driver.processImage(framePath, config, {});
|
|
183
|
+
await this.driver.writeFile(targetPath, imageBuffer);
|
|
184
|
+
if (options.depth) {
|
|
185
|
+
const depthPath = this.driver.join(depthsDir, frameName);
|
|
186
|
+
if (await this.driver.exists(depthPath)) {
|
|
187
|
+
const depthBuffer = await this.driver.processImage(depthPath, config, { grayscale: true, blur: 2 });
|
|
188
|
+
await this.driver.writeFile(this.driver.join(variantDir, `index_${i}_depth.webp`), depthBuffer);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
variantTracking.push({ ...subject, frame: i });
|
|
192
|
+
}
|
|
193
|
+
await this.driver.writeFile(this.driver.join(variantDir, '000_tracking-main.json'), JSON.stringify(variantTracking, null, 2));
|
|
194
|
+
assetVariants.push({
|
|
195
|
+
id: config.id,
|
|
196
|
+
media: config.media,
|
|
197
|
+
width: config.width,
|
|
198
|
+
height: config.height,
|
|
199
|
+
orientation: config.orientation,
|
|
200
|
+
aspectRatio: config.aspectRatio,
|
|
201
|
+
path: `./${config.id}`,
|
|
202
|
+
frameCount: framesToProcess.length,
|
|
203
|
+
hasDepthMap: options.depth,
|
|
204
|
+
subjects: ['main']
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return assetVariants;
|
|
208
|
+
}
|
|
209
|
+
async saveConfig(variants, outDir) {
|
|
210
|
+
const pkg = require('../../package.json');
|
|
211
|
+
const config = {
|
|
212
|
+
version: pkg.version,
|
|
213
|
+
settings: { baseResolution: { width: 1920, height: 1080 }, scrollMode: 'vh' },
|
|
214
|
+
assets: [{ id: "main-sequence", strategy: "adaptive", variants: variants }],
|
|
215
|
+
timeline: {
|
|
216
|
+
totalDuration: "300vh",
|
|
217
|
+
scenes: [{
|
|
218
|
+
id: "scene-1", assetId: "main-sequence", startProgress: 0, duration: 1,
|
|
219
|
+
assetRange: [0, variants[0].frameCount - 1], layers: []
|
|
220
|
+
}]
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
await this.driver.writeFile(this.driver.join(outDir, 'scrolltube.json'), JSON.stringify(config, null, 2));
|
|
224
|
+
return config;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
exports.AssetPipeline = AssetPipeline;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IPipelineDriver, VariantConfig } from './types';
|
|
2
|
+
export declare class NodeDriver implements IPipelineDriver {
|
|
3
|
+
private ffmpegPath;
|
|
4
|
+
constructor();
|
|
5
|
+
readFile(filePath: string): Promise<Uint8Array>;
|
|
6
|
+
writeFile(filePath: string, data: Uint8Array | string): Promise<void>;
|
|
7
|
+
mkdir(dirPath: string): Promise<void>;
|
|
8
|
+
exists(filePath: string): Promise<boolean>;
|
|
9
|
+
readdir(dirPath: string): Promise<string[]>;
|
|
10
|
+
remove(filePath: string): Promise<void>;
|
|
11
|
+
join(...parts: string[]): string;
|
|
12
|
+
resolve(...parts: string[]): string;
|
|
13
|
+
extractFrames(videoSource: string, outputDir: string, onProgress?: (percent: number) => void): Promise<void>;
|
|
14
|
+
processImage(input: Uint8Array | string, config: VariantConfig, options?: {
|
|
15
|
+
grayscale?: boolean;
|
|
16
|
+
blur?: number;
|
|
17
|
+
}): Promise<Uint8Array>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.NodeDriver = void 0;
|
|
40
|
+
const fs = __importStar(require("fs-extra"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const sharp_1 = __importDefault(require("sharp"));
|
|
43
|
+
const child_process_1 = require("child_process");
|
|
44
|
+
const ffmpeg_static_1 = __importDefault(require("ffmpeg-static"));
|
|
45
|
+
class NodeDriver {
|
|
46
|
+
ffmpegPath;
|
|
47
|
+
constructor() {
|
|
48
|
+
this.ffmpegPath = ffmpeg_static_1.default || 'ffmpeg';
|
|
49
|
+
}
|
|
50
|
+
async readFile(filePath) {
|
|
51
|
+
return await fs.readFile(filePath);
|
|
52
|
+
}
|
|
53
|
+
async writeFile(filePath, data) {
|
|
54
|
+
if (typeof data === 'string') {
|
|
55
|
+
await fs.writeFile(filePath, data);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
await fs.writeFile(filePath, Buffer.from(data));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async mkdir(dirPath) {
|
|
62
|
+
await fs.ensureDir(dirPath);
|
|
63
|
+
}
|
|
64
|
+
async exists(filePath) {
|
|
65
|
+
return await fs.pathExists(filePath);
|
|
66
|
+
}
|
|
67
|
+
async readdir(dirPath) {
|
|
68
|
+
return await fs.readdir(dirPath);
|
|
69
|
+
}
|
|
70
|
+
async remove(filePath) {
|
|
71
|
+
await fs.remove(filePath);
|
|
72
|
+
}
|
|
73
|
+
join(...parts) {
|
|
74
|
+
return path.join(...parts);
|
|
75
|
+
}
|
|
76
|
+
resolve(...parts) {
|
|
77
|
+
return path.resolve(...parts);
|
|
78
|
+
}
|
|
79
|
+
async extractFrames(videoSource, outputDir, onProgress) {
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
// For simplicity, we use execSync in a promise or spawn for progress
|
|
82
|
+
try {
|
|
83
|
+
// ffmpeg -i input output%04d.png
|
|
84
|
+
// For now, let's keep it simple like existing CLI
|
|
85
|
+
(0, child_process_1.execSync)(`"${this.ffmpegPath}" -i "${videoSource}" "${outputDir}/frame_%04d.png"`, { stdio: 'inherit' });
|
|
86
|
+
resolve();
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
reject(err);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async processImage(input, config, options = {}) {
|
|
94
|
+
let pipeline = (0, sharp_1.default)(input)
|
|
95
|
+
.resize(config.width, config.height, {
|
|
96
|
+
fit: 'cover',
|
|
97
|
+
position: 'center' // Placeholder for smart-crop logic if we move it here
|
|
98
|
+
});
|
|
99
|
+
if (options.grayscale) {
|
|
100
|
+
pipeline = pipeline.grayscale();
|
|
101
|
+
}
|
|
102
|
+
if (options.blur) {
|
|
103
|
+
pipeline = pipeline.blur(options.blur);
|
|
104
|
+
}
|
|
105
|
+
return await pipeline.webp({ quality: 80 }).toBuffer();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.NodeDriver = NodeDriver;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface PipelineProgress {
|
|
2
|
+
percent: number;
|
|
3
|
+
message: string;
|
|
4
|
+
step: 'initializing' | 'extracting' | 'tracking' | 'depth' | 'processing' | 'saving';
|
|
5
|
+
}
|
|
6
|
+
export interface VariantConfig {
|
|
7
|
+
id: string;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
media: string;
|
|
11
|
+
orientation: 'portrait' | 'landscape';
|
|
12
|
+
aspectRatio: string;
|
|
13
|
+
}
|
|
14
|
+
export interface IPipelineDriver {
|
|
15
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
16
|
+
writeFile(path: string, data: Uint8Array | string): Promise<void>;
|
|
17
|
+
mkdir(path: string): Promise<void>;
|
|
18
|
+
exists(path: string): Promise<boolean>;
|
|
19
|
+
readdir(path: string): Promise<string[]>;
|
|
20
|
+
remove(path: string): Promise<void>;
|
|
21
|
+
join(...parts: string[]): string;
|
|
22
|
+
resolve(...parts: string[]): string;
|
|
23
|
+
extractFrames(videoSource: string | File | Blob, outputDir: string, onProgress?: (percent: number) => void): Promise<void>;
|
|
24
|
+
processImage(input: Uint8Array | string, config: VariantConfig, options: {
|
|
25
|
+
grayscale?: boolean;
|
|
26
|
+
blur?: number;
|
|
27
|
+
}): Promise<Uint8Array>;
|
|
28
|
+
zipProject?(outDir: string): Promise<Uint8Array>;
|
|
29
|
+
}
|
|
30
|
+
export interface PipelineOptions {
|
|
31
|
+
apiKey?: string;
|
|
32
|
+
proxyUrl?: string;
|
|
33
|
+
onProgress?: (progress: PipelineProgress) => void;
|
|
34
|
+
}
|
|
35
|
+
export interface CreateCommandOptions {
|
|
36
|
+
input: string | File | Blob;
|
|
37
|
+
name: string;
|
|
38
|
+
track?: string;
|
|
39
|
+
depth?: boolean;
|
|
40
|
+
variants: number[] | VariantConfig[];
|
|
41
|
+
step?: number;
|
|
42
|
+
outputZip?: boolean;
|
|
43
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CoreEngine } from '../core';
|
|
3
|
+
interface STUBEContext {
|
|
4
|
+
progress: number;
|
|
5
|
+
frame: number;
|
|
6
|
+
engine: CoreEngine | null;
|
|
7
|
+
}
|
|
8
|
+
export interface ScrollTubeProviderProps {
|
|
9
|
+
type?: string;
|
|
10
|
+
containerHeight?: string;
|
|
11
|
+
sceneHeight?: string;
|
|
12
|
+
sceneTop?: string | 0;
|
|
13
|
+
offset?: any;
|
|
14
|
+
scrub?: number;
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
export declare const ScrollTubeProvider: React.FC<ScrollTubeProviderProps>;
|
|
18
|
+
export declare const ScrollTubeCanvas: React.FC<{
|
|
19
|
+
project: string;
|
|
20
|
+
depthtilt?: number | string;
|
|
21
|
+
width?: string;
|
|
22
|
+
height?: string;
|
|
23
|
+
style?: React.CSSProperties;
|
|
24
|
+
}>;
|
|
25
|
+
export declare const ScrollTubeLayer: React.FC<{
|
|
26
|
+
align?: string;
|
|
27
|
+
style?: React.CSSProperties;
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
}>;
|
|
30
|
+
export declare const ScrollTubeLayerTracking: React.FC<{
|
|
31
|
+
id?: string;
|
|
32
|
+
offset?: {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
};
|
|
36
|
+
style?: React.CSSProperties;
|
|
37
|
+
children: React.ReactNode;
|
|
38
|
+
}>;
|
|
39
|
+
export declare const SubjectLayer: React.FC<{
|
|
40
|
+
id?: string;
|
|
41
|
+
offset?: {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
};
|
|
45
|
+
style?: React.CSSProperties;
|
|
46
|
+
children: React.ReactNode;
|
|
47
|
+
}>;
|
|
48
|
+
export declare const useScrollTube: () => STUBEContext;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ScrollTubeProvider, ScrollTubeCanvas, ScrollTubeLayer, ScrollTubeLayerTracking, SubjectLayer, useScrollTube } from './ScrollTubeProvider';
|