@twick/timeline 0.14.3 → 0.14.4
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/context/timeline-context.d.ts +8 -2
- package/dist/core/addOns/animation.d.ts +3 -0
- package/dist/core/editor/timeline.editor.d.ts +3 -3
- package/dist/core/elements/base.element.d.ts +4 -0
- package/dist/core/elements/circle.element.d.ts +4 -0
- package/dist/core/elements/icon.element.d.ts +8 -3
- package/dist/core/elements/rect.element.d.ts +8 -0
- package/dist/core/track/track.d.ts +4 -3
- package/dist/index.js +123 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +123 -24
- package/dist/index.mjs.map +1 -1
- package/dist/types/index.d.ts +12 -157
- package/dist/types.d.ts +128 -0
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -482,7 +482,9 @@ class TrackElement {
|
|
|
482
482
|
this.type = type;
|
|
483
483
|
this.props = {
|
|
484
484
|
x: 0,
|
|
485
|
-
y: 0
|
|
485
|
+
y: 0,
|
|
486
|
+
opacity: 1,
|
|
487
|
+
rotation: 0
|
|
486
488
|
};
|
|
487
489
|
}
|
|
488
490
|
getId() {
|
|
@@ -519,6 +521,12 @@ class TrackElement {
|
|
|
519
521
|
y: ((_b = this.props) == null ? void 0 : _b.y) ?? 0
|
|
520
522
|
};
|
|
521
523
|
}
|
|
524
|
+
getRotation() {
|
|
525
|
+
return this.props.rotation ?? 0;
|
|
526
|
+
}
|
|
527
|
+
getOpacity() {
|
|
528
|
+
return this.props.opacity ?? 1;
|
|
529
|
+
}
|
|
522
530
|
setId(id) {
|
|
523
531
|
this.id = id;
|
|
524
532
|
return this;
|
|
@@ -552,6 +560,14 @@ class TrackElement {
|
|
|
552
560
|
this.props.y = position.y;
|
|
553
561
|
return this;
|
|
554
562
|
}
|
|
563
|
+
setRotation(rotation) {
|
|
564
|
+
this.props.rotation = rotation;
|
|
565
|
+
return this;
|
|
566
|
+
}
|
|
567
|
+
setOpacity(opacity) {
|
|
568
|
+
this.props.opacity = opacity;
|
|
569
|
+
return this;
|
|
570
|
+
}
|
|
555
571
|
setProps(props) {
|
|
556
572
|
this.props = structuredClone(props);
|
|
557
573
|
return this;
|
|
@@ -1040,13 +1056,35 @@ class CaptionElement extends TrackElement {
|
|
|
1040
1056
|
}
|
|
1041
1057
|
}
|
|
1042
1058
|
class IconElement extends TrackElement {
|
|
1043
|
-
constructor(src, size) {
|
|
1059
|
+
constructor(src, size, fill = "#866bbf") {
|
|
1044
1060
|
super(TIMELINE_ELEMENT_TYPE.ICON);
|
|
1045
1061
|
this.props = {
|
|
1046
1062
|
src,
|
|
1063
|
+
fill,
|
|
1047
1064
|
size
|
|
1048
1065
|
};
|
|
1049
1066
|
}
|
|
1067
|
+
getSrc() {
|
|
1068
|
+
return this.props.src;
|
|
1069
|
+
}
|
|
1070
|
+
getFill() {
|
|
1071
|
+
return this.props.fill;
|
|
1072
|
+
}
|
|
1073
|
+
getSize() {
|
|
1074
|
+
return this.props.size;
|
|
1075
|
+
}
|
|
1076
|
+
setSrc(src) {
|
|
1077
|
+
this.props.src = src;
|
|
1078
|
+
return this;
|
|
1079
|
+
}
|
|
1080
|
+
setFill(fill) {
|
|
1081
|
+
this.props.fill = fill;
|
|
1082
|
+
return this;
|
|
1083
|
+
}
|
|
1084
|
+
setSize(size) {
|
|
1085
|
+
this.props.size = size;
|
|
1086
|
+
return this;
|
|
1087
|
+
}
|
|
1050
1088
|
accept(visitor) {
|
|
1051
1089
|
return visitor.visitIconElement(this);
|
|
1052
1090
|
}
|
|
@@ -1056,7 +1094,9 @@ class CircleElement extends TrackElement {
|
|
|
1056
1094
|
super(TIMELINE_ELEMENT_TYPE.CIRCLE);
|
|
1057
1095
|
this.props = {
|
|
1058
1096
|
radius,
|
|
1059
|
-
fill
|
|
1097
|
+
fill,
|
|
1098
|
+
strokeColor: fill,
|
|
1099
|
+
lineWidth: 1
|
|
1060
1100
|
};
|
|
1061
1101
|
}
|
|
1062
1102
|
getFill() {
|
|
@@ -1065,6 +1105,12 @@ class CircleElement extends TrackElement {
|
|
|
1065
1105
|
getRadius() {
|
|
1066
1106
|
return this.props.radius;
|
|
1067
1107
|
}
|
|
1108
|
+
getStrokeColor() {
|
|
1109
|
+
return this.props.strokeColor || this.props.fill;
|
|
1110
|
+
}
|
|
1111
|
+
getLineWidth() {
|
|
1112
|
+
return this.props.lineWidth ?? 0;
|
|
1113
|
+
}
|
|
1068
1114
|
setFill(fill) {
|
|
1069
1115
|
this.props.fill = fill;
|
|
1070
1116
|
return this;
|
|
@@ -1073,6 +1119,14 @@ class CircleElement extends TrackElement {
|
|
|
1073
1119
|
this.props.radius = radius;
|
|
1074
1120
|
return this;
|
|
1075
1121
|
}
|
|
1122
|
+
setStrokeColor(strokeColor) {
|
|
1123
|
+
this.props.strokeColor = strokeColor;
|
|
1124
|
+
return this;
|
|
1125
|
+
}
|
|
1126
|
+
setLineWidth(lineWidth) {
|
|
1127
|
+
this.props.lineWidth = lineWidth;
|
|
1128
|
+
return this;
|
|
1129
|
+
}
|
|
1076
1130
|
accept(visitor) {
|
|
1077
1131
|
return visitor.visitCircleElement(this);
|
|
1078
1132
|
}
|
|
@@ -1083,18 +1137,48 @@ class RectElement extends TrackElement {
|
|
|
1083
1137
|
this.props = {
|
|
1084
1138
|
width: size.width,
|
|
1085
1139
|
height: size.height,
|
|
1086
|
-
fill
|
|
1140
|
+
fill,
|
|
1141
|
+
radius: 0,
|
|
1142
|
+
strokeColor: fill,
|
|
1143
|
+
lineWidth: 1
|
|
1087
1144
|
};
|
|
1088
1145
|
}
|
|
1146
|
+
getFill() {
|
|
1147
|
+
return this.props.fill;
|
|
1148
|
+
}
|
|
1089
1149
|
setFill(fill) {
|
|
1090
1150
|
this.props.fill = fill;
|
|
1091
1151
|
return this;
|
|
1092
1152
|
}
|
|
1153
|
+
getSize() {
|
|
1154
|
+
return { width: this.props.width, height: this.props.height };
|
|
1155
|
+
}
|
|
1156
|
+
getCornerRadius() {
|
|
1157
|
+
return this.props.radius;
|
|
1158
|
+
}
|
|
1159
|
+
getStrokeColor() {
|
|
1160
|
+
return this.props.strokeColor || this.props.fill;
|
|
1161
|
+
}
|
|
1162
|
+
getLineWidth() {
|
|
1163
|
+
return this.props.lineWidth ?? 0;
|
|
1164
|
+
}
|
|
1093
1165
|
setSize(size) {
|
|
1094
1166
|
this.props.width = size.width;
|
|
1095
1167
|
this.props.height = size.height;
|
|
1096
1168
|
return this;
|
|
1097
1169
|
}
|
|
1170
|
+
setCornerRadius(cornerRadius) {
|
|
1171
|
+
this.props.radius = cornerRadius;
|
|
1172
|
+
return this;
|
|
1173
|
+
}
|
|
1174
|
+
setStrokeColor(strokeColor) {
|
|
1175
|
+
this.props.strokeColor = strokeColor;
|
|
1176
|
+
return this;
|
|
1177
|
+
}
|
|
1178
|
+
setLineWidth(lineWidth) {
|
|
1179
|
+
this.props.lineWidth = lineWidth;
|
|
1180
|
+
return this;
|
|
1181
|
+
}
|
|
1098
1182
|
accept(visitor) {
|
|
1099
1183
|
return visitor.visitRectElement(this);
|
|
1100
1184
|
}
|
|
@@ -1103,6 +1187,7 @@ class ElementAnimation {
|
|
|
1103
1187
|
constructor(name) {
|
|
1104
1188
|
__publicField(this, "name");
|
|
1105
1189
|
__publicField(this, "interval");
|
|
1190
|
+
__publicField(this, "duration");
|
|
1106
1191
|
__publicField(this, "intensity");
|
|
1107
1192
|
__publicField(this, "animate");
|
|
1108
1193
|
__publicField(this, "mode");
|
|
@@ -1115,6 +1200,9 @@ class ElementAnimation {
|
|
|
1115
1200
|
getInterval() {
|
|
1116
1201
|
return this.interval;
|
|
1117
1202
|
}
|
|
1203
|
+
getDuration() {
|
|
1204
|
+
return this.duration;
|
|
1205
|
+
}
|
|
1118
1206
|
getIntensity() {
|
|
1119
1207
|
return this.intensity;
|
|
1120
1208
|
}
|
|
@@ -1131,6 +1219,10 @@ class ElementAnimation {
|
|
|
1131
1219
|
this.interval = interval;
|
|
1132
1220
|
return this;
|
|
1133
1221
|
}
|
|
1222
|
+
setDuration(duration) {
|
|
1223
|
+
this.duration = duration;
|
|
1224
|
+
return this;
|
|
1225
|
+
}
|
|
1134
1226
|
setIntensity(intensity) {
|
|
1135
1227
|
this.intensity = intensity;
|
|
1136
1228
|
return this;
|
|
@@ -1151,6 +1243,7 @@ class ElementAnimation {
|
|
|
1151
1243
|
return {
|
|
1152
1244
|
name: this.name,
|
|
1153
1245
|
interval: this.interval,
|
|
1246
|
+
duration: this.duration,
|
|
1154
1247
|
intensity: this.intensity,
|
|
1155
1248
|
animate: this.animate,
|
|
1156
1249
|
mode: this.mode,
|
|
@@ -1160,6 +1253,7 @@ class ElementAnimation {
|
|
|
1160
1253
|
static fromJSON(json) {
|
|
1161
1254
|
const animation = new ElementAnimation(json.name);
|
|
1162
1255
|
animation.setInterval(json.interval);
|
|
1256
|
+
animation.setDuration(json.duration);
|
|
1163
1257
|
animation.setIntensity(json.intensity);
|
|
1164
1258
|
animation.setAnimate(json.animate);
|
|
1165
1259
|
animation.setMode(json.mode);
|
|
@@ -1245,7 +1339,7 @@ class ElementTextEffect {
|
|
|
1245
1339
|
return {
|
|
1246
1340
|
name: this.name,
|
|
1247
1341
|
delay: this.delay,
|
|
1248
|
-
duration: this.duration,
|
|
1342
|
+
duration: this.duration ?? 1,
|
|
1249
1343
|
bufferTime: this.bufferTime
|
|
1250
1344
|
};
|
|
1251
1345
|
}
|
|
@@ -1313,11 +1407,12 @@ class ElementDeserializer {
|
|
|
1313
1407
|
return captionElement;
|
|
1314
1408
|
}
|
|
1315
1409
|
static deserializeIconElement(json) {
|
|
1316
|
-
var _a, _b;
|
|
1317
|
-
const size = ((_a = json.props) == null ? void 0 : _a.size)
|
|
1410
|
+
var _a, _b, _c;
|
|
1411
|
+
const size = ((_a = json.props) == null ? void 0 : _a.size) ?? { width: 100, height: 100 };
|
|
1318
1412
|
const iconElement = new IconElement(
|
|
1319
1413
|
((_b = json.props) == null ? void 0 : _b.src) || "",
|
|
1320
|
-
size
|
|
1414
|
+
size,
|
|
1415
|
+
(_c = json.props) == null ? void 0 : _c.fill
|
|
1321
1416
|
);
|
|
1322
1417
|
ElementDeserializer.deserializeBaseElement(iconElement, json);
|
|
1323
1418
|
return iconElement;
|
|
@@ -1553,10 +1648,6 @@ class ElementValidator {
|
|
|
1553
1648
|
const basicValidation = this.validateBasicProperties(element);
|
|
1554
1649
|
const errors = [...basicValidation.errors];
|
|
1555
1650
|
const warnings = [...basicValidation.warnings];
|
|
1556
|
-
const props = element.getProps();
|
|
1557
|
-
if (!(props == null ? void 0 : props.icon)) {
|
|
1558
|
-
errors.push("Icon element must have an icon name");
|
|
1559
|
-
}
|
|
1560
1651
|
return { errors, warnings };
|
|
1561
1652
|
}
|
|
1562
1653
|
validateCircleElement(element) {
|
|
@@ -1712,15 +1803,16 @@ class Track {
|
|
|
1712
1803
|
* Creates a new Track instance.
|
|
1713
1804
|
*
|
|
1714
1805
|
* @param name - The display name for the track
|
|
1806
|
+
* @param type - The type of the track
|
|
1715
1807
|
* @param id - Optional unique identifier (auto-generated if not provided)
|
|
1716
1808
|
*
|
|
1717
1809
|
* @example
|
|
1718
1810
|
* ```js
|
|
1719
1811
|
* const track = new Track("My Video Track");
|
|
1720
|
-
* const trackWithId = new Track("Audio Track", "
|
|
1812
|
+
* const trackWithId = new Track("Audio Track", "element", "video-track-1");
|
|
1721
1813
|
* ```
|
|
1722
1814
|
*/
|
|
1723
|
-
constructor(name, id) {
|
|
1815
|
+
constructor(name, type = "element", id) {
|
|
1724
1816
|
__publicField(this, "id");
|
|
1725
1817
|
__publicField(this, "name");
|
|
1726
1818
|
__publicField(this, "type");
|
|
@@ -1728,7 +1820,7 @@ class Track {
|
|
|
1728
1820
|
__publicField(this, "validator");
|
|
1729
1821
|
this.name = name;
|
|
1730
1822
|
this.id = id ?? `t-${generateShortUuid}`;
|
|
1731
|
-
this.type =
|
|
1823
|
+
this.type = type;
|
|
1732
1824
|
this.elements = [];
|
|
1733
1825
|
this.validator = new ElementValidator();
|
|
1734
1826
|
}
|
|
@@ -1819,7 +1911,7 @@ class Track {
|
|
|
1819
1911
|
*
|
|
1820
1912
|
* @example
|
|
1821
1913
|
* ```js
|
|
1822
|
-
* const track = new Track("My Track", "track-123");
|
|
1914
|
+
* const track = new Track("My Track", "element", "track-123");
|
|
1823
1915
|
* const id = track.getId(); // "track-123"
|
|
1824
1916
|
* ```
|
|
1825
1917
|
*/
|
|
@@ -2161,7 +2253,7 @@ class Track {
|
|
|
2161
2253
|
* ```
|
|
2162
2254
|
*/
|
|
2163
2255
|
static fromJSON(json) {
|
|
2164
|
-
const track = new Track(json.name, json.id);
|
|
2256
|
+
const track = new Track(json.name, json.type ?? "element", json.id);
|
|
2165
2257
|
track.type = json.type;
|
|
2166
2258
|
track.elements = (json.elements || []).map(ElementDeserializer.fromJSON);
|
|
2167
2259
|
return track;
|
|
@@ -2583,7 +2675,8 @@ class ElementCloner {
|
|
|
2583
2675
|
visitIconElement(element) {
|
|
2584
2676
|
const clonedElement = new IconElement(
|
|
2585
2677
|
element.getProps().src,
|
|
2586
|
-
element.getProps().size
|
|
2678
|
+
element.getProps().size,
|
|
2679
|
+
element.getProps().fill
|
|
2587
2680
|
);
|
|
2588
2681
|
this.cloneElementProperties(element, clonedElement);
|
|
2589
2682
|
return clonedElement;
|
|
@@ -2772,10 +2865,10 @@ class TimelineEditor {
|
|
|
2772
2865
|
this.context.updateChangeLog();
|
|
2773
2866
|
return updatedTimelineData;
|
|
2774
2867
|
}
|
|
2775
|
-
addTrack(name) {
|
|
2868
|
+
addTrack(name, type = "element") {
|
|
2776
2869
|
const prevTimelineData = this.getTimelineData();
|
|
2777
2870
|
const id = `t-${generateShortUuid()}`;
|
|
2778
|
-
const track = new Track(name, id);
|
|
2871
|
+
const track = new Track(name, type, id);
|
|
2779
2872
|
const updatedTimelines = [...(prevTimelineData == null ? void 0 : prevTimelineData.tracks) || [], track];
|
|
2780
2873
|
this.setTimelineData(updatedTimelines);
|
|
2781
2874
|
return track;
|
|
@@ -2862,12 +2955,12 @@ class TimelineEditor {
|
|
|
2862
2955
|
/**
|
|
2863
2956
|
* Update an element in a specific track using the visitor pattern
|
|
2864
2957
|
* @param element The updated element
|
|
2865
|
-
* @returns
|
|
2958
|
+
* @returns TrackElement the updated element
|
|
2866
2959
|
*/
|
|
2867
2960
|
updateElement(element) {
|
|
2868
2961
|
const track = this.getTrackById(element.getTrackId());
|
|
2869
2962
|
if (!track) {
|
|
2870
|
-
return
|
|
2963
|
+
return element;
|
|
2871
2964
|
}
|
|
2872
2965
|
try {
|
|
2873
2966
|
const elementUpdater = new ElementUpdater(track);
|
|
@@ -2878,9 +2971,9 @@ class TimelineEditor {
|
|
|
2878
2971
|
this.setTimelineData(currentData.tracks);
|
|
2879
2972
|
}
|
|
2880
2973
|
}
|
|
2881
|
-
return
|
|
2974
|
+
return element;
|
|
2882
2975
|
} catch (error) {
|
|
2883
|
-
return
|
|
2976
|
+
return element;
|
|
2884
2977
|
}
|
|
2885
2978
|
}
|
|
2886
2979
|
/**
|
|
@@ -7693,6 +7786,7 @@ const TimelineContext = createContext(
|
|
|
7693
7786
|
const TimelineProviderInner = ({
|
|
7694
7787
|
contextId,
|
|
7695
7788
|
children,
|
|
7789
|
+
resolution,
|
|
7696
7790
|
initialData
|
|
7697
7791
|
}) => {
|
|
7698
7792
|
const [timelineAction, setTimelineActionState] = useState({
|
|
@@ -7702,6 +7796,7 @@ const TimelineProviderInner = ({
|
|
|
7702
7796
|
const [selectedItem, setSelectedItem] = useState(
|
|
7703
7797
|
null
|
|
7704
7798
|
);
|
|
7799
|
+
const [videoResolution, setVideoResolution] = useState(resolution ?? { width: 720, height: 1280 });
|
|
7705
7800
|
const [totalDuration, setTotalDuration] = useState(0);
|
|
7706
7801
|
const [changeLog, setChangeLog] = useState(0);
|
|
7707
7802
|
const undoRedoContext = useUndoRedo();
|
|
@@ -7756,9 +7851,11 @@ const TimelineProviderInner = ({
|
|
|
7756
7851
|
timelineAction,
|
|
7757
7852
|
totalDuration,
|
|
7758
7853
|
changeLog,
|
|
7854
|
+
videoResolution,
|
|
7759
7855
|
present: undoRedoContext.present,
|
|
7760
7856
|
canUndo: undoRedoContext.canUndo,
|
|
7761
7857
|
canRedo: undoRedoContext.canRedo,
|
|
7858
|
+
setVideoResolution,
|
|
7762
7859
|
setSelectedItem,
|
|
7763
7860
|
setTimelineAction,
|
|
7764
7861
|
editor
|
|
@@ -7769,6 +7866,7 @@ const TimelineProviderInner = ({
|
|
|
7769
7866
|
const TimelineProvider = ({
|
|
7770
7867
|
contextId,
|
|
7771
7868
|
children,
|
|
7869
|
+
resolution = { width: 720, height: 1280 },
|
|
7772
7870
|
initialData,
|
|
7773
7871
|
undoRedoPersistenceKey,
|
|
7774
7872
|
maxHistorySize
|
|
@@ -7790,6 +7888,7 @@ const TimelineProvider = ({
|
|
|
7790
7888
|
children: /* @__PURE__ */ jsx(
|
|
7791
7889
|
TimelineProviderInner,
|
|
7792
7890
|
{
|
|
7891
|
+
resolution,
|
|
7793
7892
|
initialData,
|
|
7794
7893
|
contextId,
|
|
7795
7894
|
undoRedoPersistenceKey,
|