@twick/timeline 0.14.2 → 0.14.3
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/README.md +86 -0
- package/dist/context/timeline-context.d.ts +103 -0
- package/dist/core/track/track.d.ts +323 -18
- package/dist/core/visitor/element-adder.d.ts +122 -2
- package/dist/index.js +441 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +441 -18
- package/dist/index.mjs.map +1 -1
- package/dist/utils/constants.d.ts +172 -35
- package/dist/utils/timeline.utils.d.ts +112 -0
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -4,13 +4,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import React, { useState, createContext, useContext, useRef, useMemo, useEffect } from "react";
|
|
6
6
|
const PLAYER_STATE = {
|
|
7
|
+
/** Player is refreshing/reloading content */
|
|
7
8
|
REFRESH: "Refresh",
|
|
9
|
+
/** Player is actively playing content */
|
|
8
10
|
PLAYING: "Playing",
|
|
11
|
+
/** Player is paused */
|
|
9
12
|
PAUSED: "Paused"
|
|
10
13
|
};
|
|
11
14
|
const CAPTION_STYLE = {
|
|
15
|
+
/** Highlights background of each word */
|
|
12
16
|
WORD_BG_HIGHLIGHT: "highlight_bg",
|
|
17
|
+
/** Animates text word by word */
|
|
13
18
|
WORD_BY_WORD: "word_by_word",
|
|
19
|
+
/** Animates text word by word with background highlighting */
|
|
14
20
|
WORD_BY_WORD_WITH_BG: "word_by_word_with_bg"
|
|
15
21
|
};
|
|
16
22
|
const CAPTION_STYLE_OPTIONS = {
|
|
@@ -28,34 +34,54 @@ const CAPTION_STYLE_OPTIONS = {
|
|
|
28
34
|
}
|
|
29
35
|
};
|
|
30
36
|
const CAPTION_FONT = {
|
|
37
|
+
/** Font size in pixels */
|
|
31
38
|
size: 40
|
|
32
39
|
};
|
|
33
40
|
const CAPTION_COLOR = {
|
|
41
|
+
/** Text color in hex format */
|
|
34
42
|
text: "#ffffff",
|
|
43
|
+
/** Highlight color in hex format */
|
|
35
44
|
highlight: "#ff4081",
|
|
45
|
+
/** Background color in hex format */
|
|
36
46
|
bgColor: "#8C52FF"
|
|
37
47
|
};
|
|
38
48
|
const WORDS_PER_PHRASE = 4;
|
|
39
49
|
const TIMELINE_ACTION = {
|
|
50
|
+
/** No action being performed */
|
|
40
51
|
NONE: "none",
|
|
52
|
+
/** Setting the player state (play/pause) */
|
|
41
53
|
SET_PLAYER_STATE: "setPlayerState",
|
|
54
|
+
/** Updating player data */
|
|
42
55
|
UPDATE_PLAYER_DATA: "updatePlayerData",
|
|
56
|
+
/** Player has been updated */
|
|
43
57
|
ON_PLAYER_UPDATED: "onPlayerUpdated"
|
|
44
58
|
};
|
|
45
59
|
const TIMELINE_ELEMENT_TYPE = {
|
|
60
|
+
/** Video element type */
|
|
46
61
|
VIDEO: "video",
|
|
62
|
+
/** Caption element type */
|
|
47
63
|
CAPTION: "caption",
|
|
64
|
+
/** Image element type */
|
|
48
65
|
IMAGE: "image",
|
|
66
|
+
/** Audio element type */
|
|
49
67
|
AUDIO: "audio",
|
|
68
|
+
/** Text element type */
|
|
50
69
|
TEXT: "text",
|
|
70
|
+
/** Rectangle element type */
|
|
51
71
|
RECT: "rect",
|
|
72
|
+
/** Circle element type */
|
|
52
73
|
CIRCLE: "circle",
|
|
74
|
+
/** Icon element type */
|
|
53
75
|
ICON: "icon"
|
|
54
76
|
};
|
|
55
77
|
const PROCESS_STATE = {
|
|
78
|
+
/** Process is idle */
|
|
56
79
|
IDLE: "Idle",
|
|
80
|
+
/** Process is currently running */
|
|
57
81
|
PROCESSING: "Processing",
|
|
82
|
+
/** Process has completed successfully */
|
|
58
83
|
COMPLETED: "Completed",
|
|
84
|
+
/** Process has failed */
|
|
59
85
|
FAILED: "Failed"
|
|
60
86
|
};
|
|
61
87
|
const imageDimensionsCache = {};
|
|
@@ -1682,6 +1708,18 @@ class TrackFriend {
|
|
|
1682
1708
|
}
|
|
1683
1709
|
}
|
|
1684
1710
|
class Track {
|
|
1711
|
+
/**
|
|
1712
|
+
* Creates a new Track instance.
|
|
1713
|
+
*
|
|
1714
|
+
* @param name - The display name for the track
|
|
1715
|
+
* @param id - Optional unique identifier (auto-generated if not provided)
|
|
1716
|
+
*
|
|
1717
|
+
* @example
|
|
1718
|
+
* ```js
|
|
1719
|
+
* const track = new Track("My Video Track");
|
|
1720
|
+
* const trackWithId = new Track("Audio Track", "audio-track-1");
|
|
1721
|
+
* ```
|
|
1722
|
+
*/
|
|
1685
1723
|
constructor(name, id) {
|
|
1686
1724
|
__publicField(this, "id");
|
|
1687
1725
|
__publicField(this, "name");
|
|
@@ -1695,66 +1733,210 @@ class Track {
|
|
|
1695
1733
|
this.validator = new ElementValidator();
|
|
1696
1734
|
}
|
|
1697
1735
|
/**
|
|
1698
|
-
*
|
|
1699
|
-
* This implements the Friend Class Pattern
|
|
1700
|
-
*
|
|
1736
|
+
* Creates a friend instance for explicit access to protected methods.
|
|
1737
|
+
* This implements the Friend Class Pattern to allow controlled access
|
|
1738
|
+
* to protected methods while maintaining encapsulation.
|
|
1739
|
+
*
|
|
1740
|
+
* @returns TrackFriend instance that can access protected methods
|
|
1741
|
+
*
|
|
1742
|
+
* @example
|
|
1743
|
+
* ```js
|
|
1744
|
+
* const track = new Track("My Track");
|
|
1745
|
+
* const friend = track.createFriend();
|
|
1746
|
+
*
|
|
1747
|
+
* // Use friend to add elements
|
|
1748
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
1749
|
+
* friend.addElement(element);
|
|
1750
|
+
* ```
|
|
1701
1751
|
*/
|
|
1702
1752
|
createFriend() {
|
|
1703
1753
|
return new TrackFriend(this);
|
|
1704
1754
|
}
|
|
1705
1755
|
/**
|
|
1706
|
-
* Friend method to add element (called by TrackFriend)
|
|
1707
|
-
*
|
|
1708
|
-
*
|
|
1756
|
+
* Friend method to add element (called by TrackFriend).
|
|
1757
|
+
* Provides controlled access to the protected addElement method.
|
|
1758
|
+
*
|
|
1759
|
+
* @param element - The element to add to the track
|
|
1760
|
+
* @param skipValidation - If true, skips validation (use with caution)
|
|
1709
1761
|
* @returns true if element was added successfully
|
|
1762
|
+
*
|
|
1763
|
+
* @example
|
|
1764
|
+
* ```js
|
|
1765
|
+
* const track = new Track("My Track");
|
|
1766
|
+
* const friend = track.createFriend();
|
|
1767
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
1768
|
+
*
|
|
1769
|
+
* const success = track.addElementViaFriend(element);
|
|
1770
|
+
* // success = true if element was added successfully
|
|
1771
|
+
* ```
|
|
1710
1772
|
*/
|
|
1711
1773
|
addElementViaFriend(element, skipValidation = false) {
|
|
1712
1774
|
return this.addElement(element, skipValidation);
|
|
1713
1775
|
}
|
|
1714
1776
|
/**
|
|
1715
|
-
* Friend method to remove element (called by TrackFriend)
|
|
1716
|
-
*
|
|
1777
|
+
* Friend method to remove element (called by TrackFriend).
|
|
1778
|
+
* Provides controlled access to the protected removeElement method.
|
|
1779
|
+
*
|
|
1780
|
+
* @param element - The element to remove from the track
|
|
1781
|
+
*
|
|
1782
|
+
* @example
|
|
1783
|
+
* ```js
|
|
1784
|
+
* const track = new Track("My Track");
|
|
1785
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
1786
|
+
*
|
|
1787
|
+
* track.removeElementViaFriend(element);
|
|
1788
|
+
* // Element is removed from the track
|
|
1789
|
+
* ```
|
|
1717
1790
|
*/
|
|
1718
1791
|
removeElementViaFriend(element) {
|
|
1719
1792
|
this.removeElement(element);
|
|
1720
1793
|
}
|
|
1721
1794
|
/**
|
|
1722
|
-
* Friend method to update element (called by TrackFriend)
|
|
1723
|
-
*
|
|
1795
|
+
* Friend method to update element (called by TrackFriend).
|
|
1796
|
+
* Provides controlled access to the protected updateElement method.
|
|
1797
|
+
*
|
|
1798
|
+
* @param element - The updated element to replace the existing one
|
|
1724
1799
|
* @returns true if element was updated successfully
|
|
1800
|
+
*
|
|
1801
|
+
* @example
|
|
1802
|
+
* ```js
|
|
1803
|
+
* const track = new Track("My Track");
|
|
1804
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
1805
|
+
*
|
|
1806
|
+
* // Update the element
|
|
1807
|
+
* element.setEnd(15);
|
|
1808
|
+
* const success = track.updateElementViaFriend(element);
|
|
1809
|
+
* // success = true if element was updated successfully
|
|
1810
|
+
* ```
|
|
1725
1811
|
*/
|
|
1726
1812
|
updateElementViaFriend(element) {
|
|
1727
1813
|
return this.updateElement(element);
|
|
1728
1814
|
}
|
|
1815
|
+
/**
|
|
1816
|
+
* Gets the unique identifier of the track.
|
|
1817
|
+
*
|
|
1818
|
+
* @returns The track's unique ID string
|
|
1819
|
+
*
|
|
1820
|
+
* @example
|
|
1821
|
+
* ```js
|
|
1822
|
+
* const track = new Track("My Track", "track-123");
|
|
1823
|
+
* const id = track.getId(); // "track-123"
|
|
1824
|
+
* ```
|
|
1825
|
+
*/
|
|
1729
1826
|
getId() {
|
|
1730
1827
|
return this.id;
|
|
1731
1828
|
}
|
|
1829
|
+
/**
|
|
1830
|
+
* Gets the display name of the track.
|
|
1831
|
+
*
|
|
1832
|
+
* @returns The track's display name
|
|
1833
|
+
*
|
|
1834
|
+
* @example
|
|
1835
|
+
* ```js
|
|
1836
|
+
* const track = new Track("Video Track");
|
|
1837
|
+
* const name = track.getName(); // "Video Track"
|
|
1838
|
+
* ```
|
|
1839
|
+
*/
|
|
1732
1840
|
getName() {
|
|
1733
1841
|
return this.name;
|
|
1734
1842
|
}
|
|
1843
|
+
/**
|
|
1844
|
+
* Gets the type of the track.
|
|
1845
|
+
*
|
|
1846
|
+
* @returns The track's type string
|
|
1847
|
+
*
|
|
1848
|
+
* @example
|
|
1849
|
+
* ```js
|
|
1850
|
+
* const track = new Track("My Track");
|
|
1851
|
+
* const type = track.getType(); // "element"
|
|
1852
|
+
* ```
|
|
1853
|
+
*/
|
|
1735
1854
|
getType() {
|
|
1736
1855
|
return this.type;
|
|
1737
1856
|
}
|
|
1857
|
+
/**
|
|
1858
|
+
* Gets a read-only array of all elements in the track.
|
|
1859
|
+
* Returns a copy of the elements array to prevent external modification.
|
|
1860
|
+
*
|
|
1861
|
+
* @returns Read-only array of track elements
|
|
1862
|
+
*
|
|
1863
|
+
* @example
|
|
1864
|
+
* ```js
|
|
1865
|
+
* const track = new Track("My Track");
|
|
1866
|
+
* const elements = track.getElements();
|
|
1867
|
+
* // elements is a read-only array of TrackElement instances
|
|
1868
|
+
*
|
|
1869
|
+
* elements.forEach(element => {
|
|
1870
|
+
* console.log(`Element: ${element.getId()}, Duration: ${element.getEnd() - element.getStart()}`);
|
|
1871
|
+
* });
|
|
1872
|
+
* ```
|
|
1873
|
+
*/
|
|
1738
1874
|
getElements() {
|
|
1739
1875
|
return [...this.elements];
|
|
1740
1876
|
}
|
|
1741
1877
|
/**
|
|
1742
|
-
* Validates
|
|
1743
|
-
*
|
|
1878
|
+
* Validates a single element using the track's validator.
|
|
1879
|
+
* Checks if the element meets all validation requirements.
|
|
1880
|
+
*
|
|
1881
|
+
* @param element - The element to validate
|
|
1744
1882
|
* @returns true if valid, throws ValidationError if invalid
|
|
1883
|
+
*
|
|
1884
|
+
* @example
|
|
1885
|
+
* ```js
|
|
1886
|
+
* const track = new Track("My Track");
|
|
1887
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
1888
|
+
*
|
|
1889
|
+
* try {
|
|
1890
|
+
* const isValid = track.validateElement(element);
|
|
1891
|
+
* console.log('Element is valid:', isValid);
|
|
1892
|
+
* } catch (error) {
|
|
1893
|
+
* if (error instanceof ValidationError) {
|
|
1894
|
+
* console.log('Validation failed:', error.errors);
|
|
1895
|
+
* }
|
|
1896
|
+
* }
|
|
1897
|
+
* ```
|
|
1745
1898
|
*/
|
|
1746
1899
|
validateElement(element) {
|
|
1747
1900
|
return element.accept(this.validator);
|
|
1748
1901
|
}
|
|
1902
|
+
/**
|
|
1903
|
+
* Gets the total duration of the track.
|
|
1904
|
+
* Calculates the duration based on the end time of the last element.
|
|
1905
|
+
*
|
|
1906
|
+
* @returns The total duration of the track in seconds
|
|
1907
|
+
*
|
|
1908
|
+
* @example
|
|
1909
|
+
* ```js
|
|
1910
|
+
* const track = new Track("My Track");
|
|
1911
|
+
* const duration = track.getTrackDuration(); // 0 if no elements
|
|
1912
|
+
*
|
|
1913
|
+
* // After adding elements
|
|
1914
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 30 });
|
|
1915
|
+
* track.createFriend().addElement(element);
|
|
1916
|
+
* const newDuration = track.getTrackDuration(); // 30
|
|
1917
|
+
* ```
|
|
1918
|
+
*/
|
|
1749
1919
|
getTrackDuration() {
|
|
1750
1920
|
var _a;
|
|
1751
1921
|
return ((_a = this.elements) == null ? void 0 : _a.length) ? this.elements[this.elements.length - 1].getEnd() : 0;
|
|
1752
1922
|
}
|
|
1753
1923
|
/**
|
|
1754
|
-
* Adds an element to the track with validation
|
|
1755
|
-
*
|
|
1756
|
-
*
|
|
1924
|
+
* Adds an element to the track with validation.
|
|
1925
|
+
* Protected method that should be accessed through TrackFriend.
|
|
1926
|
+
*
|
|
1927
|
+
* @param element - The element to add to the track
|
|
1928
|
+
* @param skipValidation - If true, skips validation (use with caution)
|
|
1757
1929
|
* @returns true if element was added successfully, throws ValidationError if validation fails
|
|
1930
|
+
*
|
|
1931
|
+
* @example
|
|
1932
|
+
* ```js
|
|
1933
|
+
* const track = new Track("My Track");
|
|
1934
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
1935
|
+
*
|
|
1936
|
+
* // Use friend to access this protected method
|
|
1937
|
+
* const friend = track.createFriend();
|
|
1938
|
+
* const success = friend.addElement(element);
|
|
1939
|
+
* ```
|
|
1758
1940
|
*/
|
|
1759
1941
|
addElement(element, skipValidation = false) {
|
|
1760
1942
|
element.setTrackId(this.id);
|
|
@@ -1776,6 +1958,22 @@ class Track {
|
|
|
1776
1958
|
}
|
|
1777
1959
|
return false;
|
|
1778
1960
|
}
|
|
1961
|
+
/**
|
|
1962
|
+
* Removes an element from the track.
|
|
1963
|
+
* Protected method that should be accessed through TrackFriend.
|
|
1964
|
+
*
|
|
1965
|
+
* @param element - The element to remove from the track
|
|
1966
|
+
*
|
|
1967
|
+
* @example
|
|
1968
|
+
* ```js
|
|
1969
|
+
* const track = new Track("My Track");
|
|
1970
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
1971
|
+
*
|
|
1972
|
+
* // Use friend to access this protected method
|
|
1973
|
+
* const friend = track.createFriend();
|
|
1974
|
+
* friend.removeElement(element);
|
|
1975
|
+
* ```
|
|
1976
|
+
*/
|
|
1779
1977
|
removeElement(element) {
|
|
1780
1978
|
const index = this.elements.findIndex((e2) => e2.getId() === element.getId());
|
|
1781
1979
|
if (index !== -1) {
|
|
@@ -1783,9 +1981,22 @@ class Track {
|
|
|
1783
1981
|
}
|
|
1784
1982
|
}
|
|
1785
1983
|
/**
|
|
1786
|
-
* Updates an element in the track with validation
|
|
1787
|
-
*
|
|
1984
|
+
* Updates an element in the track with validation.
|
|
1985
|
+
* Protected method that should be accessed through TrackFriend.
|
|
1986
|
+
*
|
|
1987
|
+
* @param element - The updated element to replace the existing one
|
|
1788
1988
|
* @returns true if element was updated successfully, throws ValidationError if validation fails
|
|
1989
|
+
*
|
|
1990
|
+
* @example
|
|
1991
|
+
* ```js
|
|
1992
|
+
* const track = new Track("My Track");
|
|
1993
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
1994
|
+
*
|
|
1995
|
+
* // Use friend to access this protected method
|
|
1996
|
+
* const friend = track.createFriend();
|
|
1997
|
+
* element.setEnd(15);
|
|
1998
|
+
* const success = friend.updateElement(element);
|
|
1999
|
+
* ```
|
|
1789
2000
|
*/
|
|
1790
2001
|
updateElement(element) {
|
|
1791
2002
|
try {
|
|
@@ -1807,14 +2018,55 @@ class Track {
|
|
|
1807
2018
|
}
|
|
1808
2019
|
return false;
|
|
1809
2020
|
}
|
|
2021
|
+
/**
|
|
2022
|
+
* Finds an element in the track by its ID.
|
|
2023
|
+
*
|
|
2024
|
+
* @param id - The unique identifier of the element to find
|
|
2025
|
+
* @returns The found element or undefined if not found
|
|
2026
|
+
*
|
|
2027
|
+
* @example
|
|
2028
|
+
* ```js
|
|
2029
|
+
* const track = new Track("My Track");
|
|
2030
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
2031
|
+
* track.createFriend().addElement(element);
|
|
2032
|
+
*
|
|
2033
|
+
* const foundElement = track.getElementById(element.getId());
|
|
2034
|
+
* // foundElement is the same element instance
|
|
2035
|
+
* ```
|
|
2036
|
+
*/
|
|
1810
2037
|
getElementById(id) {
|
|
1811
2038
|
const element = this.elements.find((e2) => e2.getId() === id);
|
|
1812
2039
|
if (!element) return void 0;
|
|
1813
2040
|
return element;
|
|
1814
2041
|
}
|
|
1815
2042
|
/**
|
|
1816
|
-
* Validates all elements in the track and returns combined result and per-element status
|
|
2043
|
+
* Validates all elements in the track and returns combined result and per-element status.
|
|
2044
|
+
* Provides detailed validation information for each element including errors and warnings.
|
|
2045
|
+
*
|
|
1817
2046
|
* @returns Object with overall isValid and array of per-element validation results
|
|
2047
|
+
*
|
|
2048
|
+
* @example
|
|
2049
|
+
* ```js
|
|
2050
|
+
* const track = new Track("My Track");
|
|
2051
|
+
* const element1 = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
2052
|
+
* const element2 = new TextElement({ text: "Hello", start: 5, end: 15 });
|
|
2053
|
+
*
|
|
2054
|
+
* track.createFriend().addElement(element1);
|
|
2055
|
+
* track.createFriend().addElement(element2);
|
|
2056
|
+
*
|
|
2057
|
+
* const validation = track.validateAllElements();
|
|
2058
|
+
* console.log('Overall valid:', validation.isValid);
|
|
2059
|
+
*
|
|
2060
|
+
* validation.results.forEach(result => {
|
|
2061
|
+
* console.log(`Element ${result.element.getId()}: ${result.isValid ? 'Valid' : 'Invalid'}`);
|
|
2062
|
+
* if (result.errors) {
|
|
2063
|
+
* console.log('Errors:', result.errors);
|
|
2064
|
+
* }
|
|
2065
|
+
* if (result.warnings) {
|
|
2066
|
+
* console.log('Warnings:', result.warnings);
|
|
2067
|
+
* }
|
|
2068
|
+
* });
|
|
2069
|
+
* ```
|
|
1818
2070
|
*/
|
|
1819
2071
|
validateAllElements() {
|
|
1820
2072
|
let validResult = true;
|
|
@@ -1844,6 +2096,30 @@ class Track {
|
|
|
1844
2096
|
});
|
|
1845
2097
|
return { isValid: validResult, results };
|
|
1846
2098
|
}
|
|
2099
|
+
/**
|
|
2100
|
+
* Serializes the track and all its elements to JSON format.
|
|
2101
|
+
* Converts the track structure to a format that can be stored or transmitted.
|
|
2102
|
+
*
|
|
2103
|
+
* @returns TrackJSON object representing the track and its elements
|
|
2104
|
+
*
|
|
2105
|
+
* @example
|
|
2106
|
+
* ```js
|
|
2107
|
+
* const track = new Track("My Track");
|
|
2108
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
2109
|
+
* track.createFriend().addElement(element);
|
|
2110
|
+
*
|
|
2111
|
+
* const trackData = track.serialize();
|
|
2112
|
+
* // trackData = {
|
|
2113
|
+
* // id: "t-abc123",
|
|
2114
|
+
* // name: "My Track",
|
|
2115
|
+
* // type: "element",
|
|
2116
|
+
* // elements: [{ ... }]
|
|
2117
|
+
* // }
|
|
2118
|
+
*
|
|
2119
|
+
* // Save to localStorage
|
|
2120
|
+
* localStorage.setItem('track-data', JSON.stringify(trackData));
|
|
2121
|
+
* ```
|
|
2122
|
+
*/
|
|
1847
2123
|
serialize() {
|
|
1848
2124
|
const serializer = new ElementSerializer();
|
|
1849
2125
|
return {
|
|
@@ -1855,6 +2131,35 @@ class Track {
|
|
|
1855
2131
|
)
|
|
1856
2132
|
};
|
|
1857
2133
|
}
|
|
2134
|
+
/**
|
|
2135
|
+
* Creates a Track instance from JSON data.
|
|
2136
|
+
* Static factory method for deserializing track data.
|
|
2137
|
+
*
|
|
2138
|
+
* @param json - JSON object containing track data
|
|
2139
|
+
* @returns New Track instance with loaded data
|
|
2140
|
+
*
|
|
2141
|
+
* @example
|
|
2142
|
+
* ```js
|
|
2143
|
+
* const trackData = {
|
|
2144
|
+
* id: "t-abc123",
|
|
2145
|
+
* name: "My Track",
|
|
2146
|
+
* type: "element",
|
|
2147
|
+
* elements: [
|
|
2148
|
+
* {
|
|
2149
|
+
* id: "e-def456",
|
|
2150
|
+
* type: "video",
|
|
2151
|
+
* src: "video.mp4",
|
|
2152
|
+
* start: 0,
|
|
2153
|
+
* end: 10
|
|
2154
|
+
* }
|
|
2155
|
+
* ]
|
|
2156
|
+
* };
|
|
2157
|
+
*
|
|
2158
|
+
* const track = Track.fromJSON(trackData);
|
|
2159
|
+
* console.log(track.getName()); // "My Track"
|
|
2160
|
+
* console.log(track.getElements().length); // 1
|
|
2161
|
+
* ```
|
|
2162
|
+
*/
|
|
1858
2163
|
static fromJSON(json) {
|
|
1859
2164
|
const track = new Track(json.name, json.id);
|
|
1860
2165
|
track.type = json.type;
|
|
@@ -1934,12 +2239,37 @@ __publicField(_TimelineContextStore, "instance");
|
|
|
1934
2239
|
let TimelineContextStore = _TimelineContextStore;
|
|
1935
2240
|
const timelineContextStore = TimelineContextStore.getInstance();
|
|
1936
2241
|
class ElementAdder {
|
|
2242
|
+
/**
|
|
2243
|
+
* Creates a new ElementAdder instance for the specified track.
|
|
2244
|
+
*
|
|
2245
|
+
* @param track - The track to add elements to
|
|
2246
|
+
*
|
|
2247
|
+
* @example
|
|
2248
|
+
* ```js
|
|
2249
|
+
* const adder = new ElementAdder(track);
|
|
2250
|
+
* const success = await adder.visitVideoElement(videoElement);
|
|
2251
|
+
* ```
|
|
2252
|
+
*/
|
|
1937
2253
|
constructor(track) {
|
|
1938
2254
|
__publicField(this, "track");
|
|
1939
2255
|
__publicField(this, "trackFriend");
|
|
1940
2256
|
this.track = track;
|
|
1941
2257
|
this.trackFriend = track.createFriend();
|
|
1942
2258
|
}
|
|
2259
|
+
/**
|
|
2260
|
+
* Adds a video element to the track.
|
|
2261
|
+
* Updates video metadata and calculates appropriate start/end times
|
|
2262
|
+
* based on existing track elements.
|
|
2263
|
+
*
|
|
2264
|
+
* @param element - The video element to add
|
|
2265
|
+
* @returns Promise resolving to true if element was added successfully
|
|
2266
|
+
*
|
|
2267
|
+
* @example
|
|
2268
|
+
* ```js
|
|
2269
|
+
* const success = await adder.visitVideoElement(videoElement);
|
|
2270
|
+
* // success = true if element was added successfully
|
|
2271
|
+
* ```
|
|
2272
|
+
*/
|
|
1943
2273
|
async visitVideoElement(element) {
|
|
1944
2274
|
await element.updateVideoMeta();
|
|
1945
2275
|
const elements = this.track.getElements();
|
|
@@ -1952,6 +2282,20 @@ class ElementAdder {
|
|
|
1952
2282
|
}
|
|
1953
2283
|
return this.trackFriend.addElement(element);
|
|
1954
2284
|
}
|
|
2285
|
+
/**
|
|
2286
|
+
* Adds an audio element to the track.
|
|
2287
|
+
* Updates audio metadata and calculates appropriate start/end times
|
|
2288
|
+
* based on existing track elements.
|
|
2289
|
+
*
|
|
2290
|
+
* @param element - The audio element to add
|
|
2291
|
+
* @returns Promise resolving to true if element was added successfully
|
|
2292
|
+
*
|
|
2293
|
+
* @example
|
|
2294
|
+
* ```js
|
|
2295
|
+
* const success = await adder.visitAudioElement(audioElement);
|
|
2296
|
+
* // success = true if element was added successfully
|
|
2297
|
+
* ```
|
|
2298
|
+
*/
|
|
1955
2299
|
async visitAudioElement(element) {
|
|
1956
2300
|
await element.updateAudioMeta();
|
|
1957
2301
|
const elements = this.track.getElements();
|
|
@@ -1964,6 +2308,20 @@ class ElementAdder {
|
|
|
1964
2308
|
}
|
|
1965
2309
|
return this.trackFriend.addElement(element);
|
|
1966
2310
|
}
|
|
2311
|
+
/**
|
|
2312
|
+
* Adds an image element to the track.
|
|
2313
|
+
* Updates image metadata and calculates appropriate start/end times
|
|
2314
|
+
* based on existing track elements.
|
|
2315
|
+
*
|
|
2316
|
+
* @param element - The image element to add
|
|
2317
|
+
* @returns Promise resolving to true if element was added successfully
|
|
2318
|
+
*
|
|
2319
|
+
* @example
|
|
2320
|
+
* ```js
|
|
2321
|
+
* const success = await adder.visitImageElement(imageElement);
|
|
2322
|
+
* // success = true if element was added successfully
|
|
2323
|
+
* ```
|
|
2324
|
+
*/
|
|
1967
2325
|
async visitImageElement(element) {
|
|
1968
2326
|
await element.updateImageMeta();
|
|
1969
2327
|
const elements = this.track.getElements();
|
|
@@ -1976,6 +2334,19 @@ class ElementAdder {
|
|
|
1976
2334
|
}
|
|
1977
2335
|
return this.trackFriend.addElement(element);
|
|
1978
2336
|
}
|
|
2337
|
+
/**
|
|
2338
|
+
* Adds a text element to the track.
|
|
2339
|
+
* Calculates appropriate start/end times based on existing track elements.
|
|
2340
|
+
*
|
|
2341
|
+
* @param element - The text element to add
|
|
2342
|
+
* @returns Promise resolving to true if element was added successfully
|
|
2343
|
+
*
|
|
2344
|
+
* @example
|
|
2345
|
+
* ```js
|
|
2346
|
+
* const success = await adder.visitTextElement(textElement);
|
|
2347
|
+
* // success = true if element was added successfully
|
|
2348
|
+
* ```
|
|
2349
|
+
*/
|
|
1979
2350
|
async visitTextElement(element) {
|
|
1980
2351
|
const elements = this.track.getElements();
|
|
1981
2352
|
const lastEndtime = (elements == null ? void 0 : elements.length) ? elements[elements.length - 1].getEnd() : 0;
|
|
@@ -1987,6 +2358,19 @@ class ElementAdder {
|
|
|
1987
2358
|
}
|
|
1988
2359
|
return this.trackFriend.addElement(element);
|
|
1989
2360
|
}
|
|
2361
|
+
/**
|
|
2362
|
+
* Adds a caption element to the track.
|
|
2363
|
+
* Calculates appropriate start/end times based on existing track elements.
|
|
2364
|
+
*
|
|
2365
|
+
* @param element - The caption element to add
|
|
2366
|
+
* @returns Promise resolving to true if element was added successfully
|
|
2367
|
+
*
|
|
2368
|
+
* @example
|
|
2369
|
+
* ```js
|
|
2370
|
+
* const success = await adder.visitCaptionElement(captionElement);
|
|
2371
|
+
* // success = true if element was added successfully
|
|
2372
|
+
* ```
|
|
2373
|
+
*/
|
|
1990
2374
|
async visitCaptionElement(element) {
|
|
1991
2375
|
const elements = this.track.getElements();
|
|
1992
2376
|
const lastEndtime = (elements == null ? void 0 : elements.length) ? elements[elements.length - 1].getEnd() : 0;
|
|
@@ -1998,6 +2382,19 @@ class ElementAdder {
|
|
|
1998
2382
|
}
|
|
1999
2383
|
return this.trackFriend.addElement(element);
|
|
2000
2384
|
}
|
|
2385
|
+
/**
|
|
2386
|
+
* Adds an icon element to the track.
|
|
2387
|
+
* Calculates appropriate start/end times based on existing track elements.
|
|
2388
|
+
*
|
|
2389
|
+
* @param element - The icon element to add
|
|
2390
|
+
* @returns Promise resolving to true if element was added successfully
|
|
2391
|
+
*
|
|
2392
|
+
* @example
|
|
2393
|
+
* ```js
|
|
2394
|
+
* const success = await adder.visitIconElement(iconElement);
|
|
2395
|
+
* // success = true if element was added successfully
|
|
2396
|
+
* ```
|
|
2397
|
+
*/
|
|
2001
2398
|
async visitIconElement(element) {
|
|
2002
2399
|
const elements = this.track.getElements();
|
|
2003
2400
|
const lastEndtime = (elements == null ? void 0 : elements.length) ? elements[elements.length - 1].getEnd() : 0;
|
|
@@ -2009,6 +2406,19 @@ class ElementAdder {
|
|
|
2009
2406
|
}
|
|
2010
2407
|
return this.trackFriend.addElement(element);
|
|
2011
2408
|
}
|
|
2409
|
+
/**
|
|
2410
|
+
* Adds a circle element to the track.
|
|
2411
|
+
* Calculates appropriate start/end times based on existing track elements.
|
|
2412
|
+
*
|
|
2413
|
+
* @param element - The circle element to add
|
|
2414
|
+
* @returns Promise resolving to true if element was added successfully
|
|
2415
|
+
*
|
|
2416
|
+
* @example
|
|
2417
|
+
* ```js
|
|
2418
|
+
* const success = await adder.visitCircleElement(circleElement);
|
|
2419
|
+
* // success = true if element was added successfully
|
|
2420
|
+
* ```
|
|
2421
|
+
*/
|
|
2012
2422
|
async visitCircleElement(element) {
|
|
2013
2423
|
const elements = this.track.getElements();
|
|
2014
2424
|
const lastEndtime = (elements == null ? void 0 : elements.length) ? elements[elements.length - 1].getEnd() : 0;
|
|
@@ -2020,6 +2430,19 @@ class ElementAdder {
|
|
|
2020
2430
|
}
|
|
2021
2431
|
return this.trackFriend.addElement(element);
|
|
2022
2432
|
}
|
|
2433
|
+
/**
|
|
2434
|
+
* Adds a rectangle element to the track.
|
|
2435
|
+
* Calculates appropriate start/end times based on existing track elements.
|
|
2436
|
+
*
|
|
2437
|
+
* @param element - The rectangle element to add
|
|
2438
|
+
* @returns Promise resolving to true if element was added successfully
|
|
2439
|
+
*
|
|
2440
|
+
* @example
|
|
2441
|
+
* ```js
|
|
2442
|
+
* const success = await adder.visitRectElement(rectElement);
|
|
2443
|
+
* // success = true if element was added successfully
|
|
2444
|
+
* ```
|
|
2445
|
+
*/
|
|
2023
2446
|
async visitRectElement(element) {
|
|
2024
2447
|
const elements = this.track.getElements();
|
|
2025
2448
|
const lastEndtime = (elements == null ? void 0 : elements.length) ? elements[elements.length - 1].getEnd() : 0;
|