@shotstack/shotstack-studio 1.4.1 → 1.5.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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Container } from 'pixi.js';
1
2
  import * as pixi from 'pixi.js';
2
3
  import { z } from 'zod';
3
4
  import * as zod from 'zod';
@@ -45,6 +46,7 @@ export declare class Canvas {
45
46
  private readonly inspector;
46
47
  private container?;
47
48
  private background?;
49
+ private timeline?;
48
50
  private minZoom;
49
51
  private maxZoom;
50
52
  private currentZoom;
@@ -54,14 +56,30 @@ export declare class Canvas {
54
56
  centerEdit(): void;
55
57
  zoomToFit(): void;
56
58
  setZoom(zoom: number): void;
59
+ registerTimeline(timeline: Timeline): void;
57
60
  private registerExtensions;
58
61
  private configureApplication;
59
62
  private onTick;
60
63
  private configureStage;
61
64
  private onClick;
65
+ private onBackgroundClick;
62
66
  dispose(): void;
63
67
  }
64
68
 
69
+ declare type Clip = zod.infer<typeof ClipSchema>;
70
+
71
+ declare type ClipConfig = z.infer<typeof ClipSchema>;
72
+
73
+ declare interface ClipInfo {
74
+ trackIndex: number;
75
+ clipIndex: number;
76
+ clipConfig: ClipConfig;
77
+ x: number;
78
+ y: number;
79
+ width: number;
80
+ height: number;
81
+ }
82
+
65
83
  declare const ClipSchema: zod.ZodObject<{
66
84
  asset: zod.ZodEffects<zod.ZodUnion<[zod.ZodObject<{
67
85
  type: zod.ZodLiteral<"text">;
@@ -1241,6 +1259,34 @@ declare const ClipSchema: zod.ZodObject<{
1241
1259
 
1242
1260
  declare type ClipType = z.infer<typeof ClipSchema>;
1243
1261
 
1262
+ declare type ClipType_2 = z.infer<typeof ClipSchema>;
1263
+
1264
+ declare type CommandContext = {
1265
+ getClips(): Player[];
1266
+ getTracks(): Player[][];
1267
+ getTrack(trackIndex: number): Player[] | null;
1268
+ getContainer(): Container;
1269
+ addPlayer(trackIdx: number, player: Player): Promise<void>;
1270
+ addPlayerToContainer(trackIdx: number, player: Player): void;
1271
+ createPlayerFromAssetType(clipConfiguration: ClipType_2): Player;
1272
+ queueDisposeClip(player: Player): void;
1273
+ disposeClips(): void;
1274
+ undeleteClip(trackIdx: number, clip: Player): void;
1275
+ setUpdatedClip(clip: Player): void;
1276
+ restoreClipConfiguration(clip: Player, previousConfig: ClipType_2): void;
1277
+ updateDuration(): void;
1278
+ emitEvent(name: string, data: unknown): void;
1279
+ findClipIndices(player: Player): {
1280
+ trackIndex: number;
1281
+ clipIndex: number;
1282
+ } | null;
1283
+ getClipAt(trackIndex: number, clipIndex: number): Player | null;
1284
+ getSelectedClip(): Player | null;
1285
+ setSelectedClip(clip: Player | null): void;
1286
+ movePlayerToTrackContainer(player: Player, fromTrackIdx: number, toTrackIdx: number): void;
1287
+ getEditState(): EditType_2;
1288
+ };
1289
+
1244
1290
  export declare class Controls {
1245
1291
  private edit;
1246
1292
  private seekDistance;
@@ -1252,6 +1298,10 @@ export declare class Controls {
1252
1298
  private handleKeyUp;
1253
1299
  }
1254
1300
 
1301
+ declare type DeepPartial<T> = {
1302
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
1303
+ };
1304
+
1255
1305
  export declare class Edit extends Entity {
1256
1306
  private static readonly ZIndexPadding;
1257
1307
  assetLoader: AssetLoader;
@@ -1274,13 +1324,16 @@ export declare class Edit extends Entity {
1274
1324
  getEdit(): EditType;
1275
1325
  addClip(trackIdx: number, clip: ClipType): void;
1276
1326
  getClip(trackIdx: number, clipIdx: number): ClipType | null;
1327
+ getPlayerClip(trackIdx: number, clipIdx: number): Player | null;
1277
1328
  deleteClip(trackIdx: number, clipIdx: number): void;
1329
+ splitClip(trackIndex: number, clipIndex: number, splitTime: number): void;
1278
1330
  addTrack(trackIdx: number, track: TrackType): void;
1279
1331
  getTrack(trackIdx: number): TrackType | null;
1280
1332
  deleteTrack(trackIdx: number): void;
1281
1333
  getTotalDuration(): number;
1282
1334
  undo(): void;
1283
1335
  redo(): void;
1336
+ executeEditCommand(command: EditCommand): void | Promise<void>;
1284
1337
  private executeCommand;
1285
1338
  private createCommandContext;
1286
1339
  private queueDisposeClip;
@@ -1289,10 +1342,34 @@ export declare class Edit extends Entity {
1289
1342
  private unloadClipAssets;
1290
1343
  protected clearClips(): void;
1291
1344
  private updateTotalDuration;
1345
+ private addPlayerToContainer;
1346
+ private movePlayerToTrackContainer;
1292
1347
  private createPlayerFromAssetType;
1293
1348
  private addPlayer;
1349
+ selectClip(trackIndex: number, clipIndex: number): void;
1350
+ clearSelection(): void;
1351
+ isClipSelected(trackIndex: number, clipIndex: number): boolean;
1352
+ getSelectedClipInfo(): {
1353
+ trackIndex: number;
1354
+ clipIndex: number;
1355
+ player: Player;
1356
+ } | null;
1357
+ findClipIndices(player: Player): {
1358
+ trackIndex: number;
1359
+ clipIndex: number;
1360
+ } | null;
1361
+ getClipAt(trackIndex: number, clipIndex: number): Player | null;
1362
+ selectPlayer(player: Player): void;
1363
+ isPlayerSelected(player: Player): boolean;
1364
+ private setupIntentListeners;
1294
1365
  }
1295
1366
 
1367
+ declare type EditCommand = {
1368
+ execute(context?: CommandContext): void | Promise<void>;
1369
+ undo?(context?: CommandContext): void | Promise<void>;
1370
+ readonly name: string;
1371
+ };
1372
+
1296
1373
  declare const EditSchema: zod.ZodObject<{
1297
1374
  timeline: zod.ZodObject<{
1298
1375
  background: zod.ZodOptional<zod.ZodString>;
@@ -3494,6 +3571,10 @@ declare const EditSchema: zod.ZodObject<{
3494
3571
 
3495
3572
  declare type EditType = z.infer<typeof EditSchema>;
3496
3573
 
3574
+ declare type EditType_2 = z.infer<typeof EditSchema>;
3575
+
3576
+ declare type EditType_3 = z.infer<typeof EditSchema>;
3577
+
3497
3578
  declare abstract class Entity {
3498
3579
  private readonly container;
3499
3580
  constructor();
@@ -3513,11 +3594,328 @@ declare type EventPayloadMap<TPayload = any> = Record<string, TPayload>;
3513
3594
 
3514
3595
  declare type Listener<TPayload = any> = (payload: TPayload) => void;
3515
3596
 
3597
+ /**
3598
+ * TODO: Move handles on UI level (screen space)
3599
+ * TODO: Handle overlapping frames - ex: length of a clip is 1.5s but there's an in (1s) and out (1s) transition
3600
+ * TODO: Scale X and Y needs to be implemented separately for getFitScale cover
3601
+ * TODO: Move animation effects and transitions out of player
3602
+ * TODO: On pointer down and custom keyframe, add a keyframe at the current time. Get current and time and push a keyframe into the state, and then reconfigure the keyframes.
3603
+ * TODO: Move bounding box to a separate entity
3604
+ */
3605
+ declare abstract class Player extends Entity {
3606
+ private static readonly SnapThreshold;
3607
+ private static readonly DiscardedFrameCount;
3608
+ private static readonly ScaleHandleRadius;
3609
+ private static readonly RotationHandleRadius;
3610
+ private static readonly RotationHandleOffset;
3611
+ private static readonly OutlineWidth;
3612
+ private static readonly MinScale;
3613
+ private static readonly MaxScale;
3614
+ layer: number;
3615
+ shouldDispose: boolean;
3616
+ protected edit: Edit;
3617
+ clipConfiguration: Clip;
3618
+ private positionBuilder;
3619
+ private offsetXKeyframeBuilder?;
3620
+ private offsetYKeyframeBuilder?;
3621
+ private scaleKeyframeBuilder?;
3622
+ private opacityKeyframeBuilder?;
3623
+ private rotationKeyframeBuilder?;
3624
+ private outline;
3625
+ private topLeftScaleHandle;
3626
+ private topRightScaleHandle;
3627
+ private bottomLeftScaleHandle;
3628
+ private bottomRightScaleHandle;
3629
+ private rotationHandle;
3630
+ private isHovering;
3631
+ private isDragging;
3632
+ private dragOffset;
3633
+ private scaleDirection;
3634
+ private scaleStart;
3635
+ private scaleOffset;
3636
+ private isRotating;
3637
+ private rotationStart;
3638
+ private rotationOffset;
3639
+ private initialClipConfiguration;
3640
+ protected contentContainer: pixi.Container;
3641
+ constructor(edit: Edit, clipConfiguration: Clip);
3642
+ reconfigureAfterRestore(): void;
3643
+ protected configureKeyframes(): void;
3644
+ load(): Promise<void>;
3645
+ update(_: number, __: number): void;
3646
+ draw(): void;
3647
+ dispose(): void;
3648
+ getStart(): number;
3649
+ getLength(): number;
3650
+ getEnd(): number;
3651
+ getPlaybackTime(): number;
3652
+ abstract getSize(): Size;
3653
+ getOpacity(): number;
3654
+ getPosition(): Vector;
3655
+ getPivot(): Vector;
3656
+ protected getFitScale(): number;
3657
+ getScale(): number;
3658
+ getRotation(): number;
3659
+ isActive(): boolean;
3660
+ shouldDiscardFrame(): boolean;
3661
+ private onPointerStart;
3662
+ private onPointerMove;
3663
+ private onPointerUp;
3664
+ private onPointerOver;
3665
+ private onPointerOut;
3666
+ private clipHasPresets;
3667
+ private clipHasKeyframes;
3668
+ private hasStateChanged;
3669
+ }
3670
+
3671
+ declare interface SelectionBounds {
3672
+ x: number;
3673
+ y: number;
3674
+ width: number;
3675
+ height: number;
3676
+ cornerRadius: number;
3677
+ borderWidth: number;
3678
+ }
3679
+
3680
+ declare class SelectionOverlayRenderer {
3681
+ private overlay;
3682
+ private theme;
3683
+ private selectionGraphics;
3684
+ constructor(overlay: pixi.Container, theme: TimelineTheme);
3685
+ renderSelection(clipId: string, bounds: SelectionBounds, isSelected: boolean): void;
3686
+ clearSelection(clipId: string): void;
3687
+ clearAllSelections(): void;
3688
+ updateTheme(theme: TimelineTheme): void;
3689
+ getOverlay(): pixi.Container;
3690
+ dispose(): void;
3691
+ }
3692
+
3516
3693
  declare type Size = {
3517
3694
  width: number;
3518
3695
  height: number;
3519
3696
  };
3520
3697
 
3698
+ export declare class Timeline extends Entity {
3699
+ private edit;
3700
+ private currentEditType;
3701
+ private layout;
3702
+ private theme;
3703
+ private lastPlaybackTime;
3704
+ private static readonly TIMELINE_BUFFER_MULTIPLIER;
3705
+ private interaction;
3706
+ private dragPreviewManager;
3707
+ private viewportManager;
3708
+ private visualTrackManager;
3709
+ private eventHandler;
3710
+ private renderer;
3711
+ private featureManager;
3712
+ private optionsManager;
3713
+ constructor(edit: Edit, size: {
3714
+ width: number;
3715
+ height: number;
3716
+ }, themeOptions?: TimelineThemeOptions);
3717
+ private initializeManagers;
3718
+ load(): Promise<void>;
3719
+ private setupViewport;
3720
+ private setupTimelineFeatures;
3721
+ private recreateTimelineFeatures;
3722
+ setScroll(x: number, y: number): void;
3723
+ setZoom(zoom: number): void;
3724
+ getViewport(): {
3725
+ x: number;
3726
+ y: number;
3727
+ zoom: number;
3728
+ };
3729
+ getClipData(trackIndex: number, clipIndex: number): ClipConfig | null;
3730
+ getLayout(): TimelineLayout;
3731
+ getVisualTracks(): VisualTrack[];
3732
+ getEdit(): Edit;
3733
+ getExtendedTimelineWidth(): number;
3734
+ hideDragGhost(): void;
3735
+ showDragGhost(trackIndex: number, time: number, freeY?: number): void;
3736
+ setPlayheadTime(time: number): void;
3737
+ getPlayheadTime(): number;
3738
+ getActualEditDuration(): number;
3739
+ findClipAtPosition(x: number, y: number): ClipInfo | null;
3740
+ setTheme(themeOptions: TimelineThemeOptions): void;
3741
+ getTheme(): TimelineTheme;
3742
+ getCurrentEditType(): EditType_3 | null;
3743
+ getOptions(): TimelineOptions;
3744
+ setOptions(options: Partial<TimelineOptions>): void;
3745
+ getTimeDisplay(): {
3746
+ updateTimeDisplay(): void;
3747
+ };
3748
+ updateTime(time: number, emit?: boolean): void;
3749
+ get timeRange(): {
3750
+ startTime: number;
3751
+ endTime: number;
3752
+ };
3753
+ get viewportHeight(): number;
3754
+ get zoomLevelIndex(): number;
3755
+ zoomIn(): void;
3756
+ zoomOut(): void;
3757
+ private onZoomChanged;
3758
+ }
3759
+
3760
+ declare class TimelineLayout {
3761
+ private options;
3762
+ private theme?;
3763
+ static readonly TOOLBAR_HEIGHT_RATIO: 0.12;
3764
+ static readonly RULER_HEIGHT_RATIO: 0.133;
3765
+ static readonly TOOLBAR_HEIGHT_DEFAULT: 36;
3766
+ static readonly RULER_HEIGHT_DEFAULT: 40;
3767
+ static readonly TRACK_HEIGHT_DEFAULT: 80;
3768
+ static readonly CLIP_PADDING: 4;
3769
+ static readonly BORDER_WIDTH: 2;
3770
+ static readonly CORNER_RADIUS: 4;
3771
+ static readonly LABEL_PADDING: 8;
3772
+ static readonly TRACK_PADDING: 2;
3773
+ private config;
3774
+ constructor(options: Required<TimelineOptions>, theme?: TimelineTheme | undefined);
3775
+ private calculateLayout;
3776
+ get toolbarHeight(): number;
3777
+ get toolbarY(): number;
3778
+ get rulerHeight(): number;
3779
+ get trackHeight(): number;
3780
+ get rulerY(): number;
3781
+ get tracksY(): number;
3782
+ get gridY(): number;
3783
+ get playheadY(): number;
3784
+ get viewportY(): number;
3785
+ positionTrack(trackIndex: number): number;
3786
+ positionClip(startTime: number): number;
3787
+ calculateClipWidth(duration: number): number;
3788
+ calculateDropPosition(globalX: number, globalY: number): {
3789
+ track: number;
3790
+ time: number;
3791
+ x: number;
3792
+ y: number;
3793
+ };
3794
+ getTrackAtY(y: number): number;
3795
+ getTimeAtX(x: number): number;
3796
+ getXAtTime(time: number): number;
3797
+ getYAtTrack(trackIndex: number): number;
3798
+ getGridHeight(): number;
3799
+ getRulerWidth(): number;
3800
+ getGridWidth(): number;
3801
+ calculateViewportPosition(scrollX: number, scrollY: number): {
3802
+ x: number;
3803
+ y: number;
3804
+ };
3805
+ updateOptions(options: Required<TimelineOptions>, theme?: TimelineTheme): void;
3806
+ isPointInToolbar(_x: number, y: number): boolean;
3807
+ isPointInRuler(_x: number, y: number): boolean;
3808
+ isPointInTracks(_x: number, y: number): boolean;
3809
+ getVisibleTrackRange(scrollY: number, viewportHeight: number): {
3810
+ start: number;
3811
+ end: number;
3812
+ };
3813
+ }
3814
+
3815
+ declare interface TimelineOptions {
3816
+ width?: number;
3817
+ height?: number;
3818
+ pixelsPerSecond?: number;
3819
+ trackHeight?: number;
3820
+ backgroundColor?: number;
3821
+ antialias?: boolean;
3822
+ resolution?: number;
3823
+ }
3824
+
3825
+ export declare interface TimelineTheme {
3826
+ timeline: {
3827
+ background: number;
3828
+ divider: number;
3829
+ toolbar: {
3830
+ background: number;
3831
+ surface: number;
3832
+ hover: number;
3833
+ active: number;
3834
+ divider: number;
3835
+ icon: number;
3836
+ text: number;
3837
+ height: number;
3838
+ };
3839
+ ruler: {
3840
+ background: number;
3841
+ text: number;
3842
+ markers: number;
3843
+ height: number;
3844
+ };
3845
+ tracks: {
3846
+ surface: number;
3847
+ surfaceAlt: number;
3848
+ border: number;
3849
+ height: number;
3850
+ };
3851
+ clips: {
3852
+ video: number;
3853
+ audio: number;
3854
+ image: number;
3855
+ text: number;
3856
+ shape: number;
3857
+ html: number;
3858
+ luma: number;
3859
+ default: number;
3860
+ selected: number;
3861
+ radius: number;
3862
+ };
3863
+ playhead: number;
3864
+ snapGuide: number;
3865
+ dropZone: number;
3866
+ trackInsertion: number;
3867
+ };
3868
+ }
3869
+
3870
+ export declare interface TimelineThemeInput {
3871
+ timeline: {
3872
+ background: string;
3873
+ divider: string;
3874
+ toolbar: {
3875
+ background: string;
3876
+ surface: string;
3877
+ hover: string;
3878
+ active: string;
3879
+ divider: string;
3880
+ icon: string;
3881
+ text: string;
3882
+ height?: number;
3883
+ };
3884
+ ruler: {
3885
+ background: string;
3886
+ text: string;
3887
+ markers: string;
3888
+ height?: number;
3889
+ };
3890
+ tracks: {
3891
+ surface: string;
3892
+ surfaceAlt: string;
3893
+ border: string;
3894
+ height?: number;
3895
+ };
3896
+ clips: {
3897
+ video: string;
3898
+ audio: string;
3899
+ image: string;
3900
+ text: string;
3901
+ shape: string;
3902
+ html: string;
3903
+ luma: string;
3904
+ default: string;
3905
+ selected: string;
3906
+ radius?: number;
3907
+ };
3908
+ playhead: string;
3909
+ snapGuide: string;
3910
+ dropZone: string;
3911
+ trackInsertion: string;
3912
+ };
3913
+ }
3914
+
3915
+ declare interface TimelineThemeOptions {
3916
+ theme?: TimelineThemeInput | DeepPartial<TimelineThemeInput>;
3917
+ }
3918
+
3521
3919
  declare const TrackSchema: zod.ZodObject<{
3522
3920
  clips: zod.ZodArray<zod.ZodObject<{
3523
3921
  asset: zod.ZodEffects<zod.ZodUnion<[zod.ZodObject<{
@@ -5011,6 +5409,13 @@ declare const TrackSchema: zod.ZodObject<{
5011
5409
 
5012
5410
  declare type TrackType = z.infer<typeof TrackSchema>;
5013
5411
 
5412
+ declare type TrackType_2 = z.infer<typeof TrackSchema>;
5413
+
5414
+ declare type Vector = {
5415
+ x: number;
5416
+ y: number;
5417
+ };
5418
+
5014
5419
  export declare class VideoExporter {
5015
5420
  private readonly ffmpeg;
5016
5421
  private isReady;
@@ -5027,4 +5432,97 @@ export declare class VideoExporter {
5027
5432
  private removeProgressOverlay;
5028
5433
  }
5029
5434
 
5435
+ declare class VisualClip extends Entity {
5436
+ private clipConfig;
5437
+ private options;
5438
+ private graphics;
5439
+ private background;
5440
+ private text;
5441
+ private selectionRenderer;
5442
+ private lastGlobalX;
5443
+ private lastGlobalY;
5444
+ private readonly CLIP_PADDING;
5445
+ private readonly BORDER_WIDTH;
5446
+ private get CORNER_RADIUS();
5447
+ constructor(clipConfig: ClipConfig, options: VisualClipOptions);
5448
+ load(): Promise<void>;
5449
+ private setupContainer;
5450
+ private setupGraphics;
5451
+ updateFromConfig(newConfig: ClipConfig): void;
5452
+ private setVisualState;
5453
+ private getEffectiveWidth;
5454
+ private drawClipBackground;
5455
+ private drawClipBorder;
5456
+ private updateSelectionState;
5457
+ private getClipColor;
5458
+ private getStateStyles;
5459
+ setSelected(selected: boolean): void;
5460
+ setDragging(dragging: boolean): void;
5461
+ setResizing(resizing: boolean): void;
5462
+ setPreviewWidth(width: number | null): void;
5463
+ setPixelsPerSecond(pixelsPerSecond: number): void;
5464
+ updateOptions(updates: Partial<VisualClipOptions>): void;
5465
+ getClipConfig(): ClipConfig;
5466
+ getOptions(): VisualClipOptions;
5467
+ getVisualState(): {
5468
+ mode: "normal" | "selected" | "dragging" | "resizing";
5469
+ previewWidth?: number;
5470
+ };
5471
+ getSelected(): boolean;
5472
+ getClipId(): string;
5473
+ getDragging(): boolean;
5474
+ getRightEdgeX(): number;
5475
+ }
5476
+
5477
+ declare interface VisualClipOptions {
5478
+ pixelsPerSecond: number;
5479
+ trackHeight: number;
5480
+ trackIndex: number;
5481
+ clipIndex: number;
5482
+ theme: TimelineTheme;
5483
+ selectionRenderer?: SelectionOverlayRenderer;
5484
+ }
5485
+
5486
+ declare class VisualTrack extends Entity {
5487
+ private clips;
5488
+ private options;
5489
+ private background;
5490
+ private readonly TRACK_PADDING;
5491
+ private readonly LABEL_PADDING;
5492
+ constructor(options: VisualTrackOptions);
5493
+ load(): Promise<void>;
5494
+ private setupContainer;
5495
+ rebuildFromTrackData(trackData: TrackType_2, pixelsPerSecond: number): void;
5496
+ private addClip;
5497
+ private clearAllClips;
5498
+ removeClip(clipIndex: number): void;
5499
+ updateClip(clipIndex: number, newClipConfig: ClipConfig): void;
5500
+ setPixelsPerSecond(pixelsPerSecond: number): void;
5501
+ setWidth(width: number): void;
5502
+ setTrackIndex(trackIndex: number): void;
5503
+ selectClip(clipIndex: number): void;
5504
+ clearAllSelections(): void;
5505
+ getSelectedClip(): VisualClip | null;
5506
+ getSelectedClipIndex(): number;
5507
+ getClips(): VisualClip[];
5508
+ getClip(clipIndex: number): VisualClip | null;
5509
+ getClipCount(): number;
5510
+ getTrackIndex(): number;
5511
+ getTrackHeight(): number;
5512
+ getOptions(): VisualTrackOptions;
5513
+ findClipAtPosition(x: number, y: number): {
5514
+ clip: VisualClip;
5515
+ clipIndex: number;
5516
+ } | null;
5517
+ }
5518
+
5519
+ declare interface VisualTrackOptions {
5520
+ pixelsPerSecond: number;
5521
+ trackHeight: number;
5522
+ trackIndex: number;
5523
+ width: number;
5524
+ theme: TimelineTheme;
5525
+ selectionRenderer?: SelectionOverlayRenderer;
5526
+ }
5527
+
5030
5528
  export { }