Skip to content

Commit c3d2790

Browse files
committed
Adding new keyframe SVG icons to timeline (circle for bezier, diamond for linear, square for constant). Adding click on keyframe point (to seek to that spot), improving performance on some Angular keframe getting..., Fixing keyframe HTML to be better organized, and better styled.
1 parent 5143e0f commit c3d2790

File tree

8 files changed

+321
-33
lines changed

8 files changed

+321
-33
lines changed

src/timeline/index.html

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
<div ng-repeat="layer in project.layers.slice().reverse()" id="track_static_{{layer.number}}" ng-right-click="showTrackMenu(layer.id)" class="track_name">
7070
<div class="track_top">
7171
<div tl-clip-menu class="track_menu" ng-mousedown="showTrackMenu(layer.id)"></div>
72-
<span class="track_label">{{getTrackName(layer.label, project.layers.length - $index)}}</span><span ng-show="layer.lock" class="track_lock"></span>
72+
<span class="track_label">{{getTrackName(layer.label, project.layers.length - $index)}}</span><span ng-if="layer.lock" class="track_lock"></span>
7373
</div>
7474
</div>
7575
<br>
@@ -84,42 +84,48 @@
8484
<!-- CLIPS -->
8585
<div ng-hide tl-clip ng-repeat="clip in project.clips" id="clip_{{clip.id}}" ng-click="selectClip(clip.id, true, $event)" ng-right-click="showClipMenu(clip.id, $event)" class="clip droppable" ng-class="getClipStyle(clip)" style="width:{{(clip.end - clip.start) * pixelsPerSecond}}px; left:{{clip.position * pixelsPerSecond}}px; top:{{getTrackTop(clip.layer)}}px;z-index:{{1000 + $index}};">
8686
<div class="clip_top">
87-
<div tl-clip-menu class="clip_menu" ng-show="!enable_razor" ng-mousedown="showClipMenu(clip.id, $event)" tooltip-enable="!enable_razor" tooltip="{{clip.title}}" tooltip-placement="bottom" tooltip-popup-delay="400"></div>
87+
<div tl-clip-menu class="clip_menu" ng-if="!enable_razor" ng-mousedown="showClipMenu(clip.id, $event)" tooltip-enable="!enable_razor" tooltip="{{clip.title}}" tooltip-placement="bottom" tooltip-popup-delay="400"></div>
8888

8989
<!-- CLIP EFFECTS -->
90-
<div ng-show="!enable_razor" class="effect-container" id="effects_{{clip.id}}">
90+
<div ng-if="!enable_razor" class="effect-container" id="effects_{{clip.id}}">
9191
<div class="clip_effects" ng-repeat="effect in clip.effects" id="effect_{{effect.id}}" style="background-color: {{ getEffectColor(effect.type) }};" ng-click="selectEffect(effect.id); $event.stopPropagation();" ng-right-click="showEffectMenu(effect.id); $event.stopPropagation();" tooltip="{{effect.type}} ({{$index+1}}/{{clip.effects.length}})" tooltip-placement="bottom" tooltip-popup-delay="400">
9292
{{effect.type[0]}}
9393
</div>
9494
</div>
9595

96-
<!-- CLIP KEYFRAME POINTS -->
97-
<div ng-repeat="(point, value) in getKeyframes(clip)" id="point_{{clip.id}}_{{point}}_{{$index}}" style="left: {{(((point - 1) / (project.fps.num / project.fps.den) - clip.start) * pixelsPerSecond)}}px;" class="point_region" ng-show="clip.selected "><div class="point_icon"></div></div>
98-
9996
<!-- CLIP LABEL -->
10097
<div class="clip_label" ng-class="getClipLabelStyle(clip)" tooltip-enable="!enable_razor" tooltip="{{clip.title}}" tooltip-placement="bottom" tooltip-popup-delay="400">{{clip.title}}</div>
101-
<br class="cleared">
98+
<br class="cleared">
10299
</div>
103100
<br class="cleared">
104-
<div ng-show="!clip.show_audio" class="thumb-container">
105-
<img class="thumb thumb-start" ng-show="getThumbPath(clip)" ng-src="{{ getThumbPath(clip) }}"/>
101+
102+
<div ng-if="!clip.show_audio" class="thumb-container">
103+
<img class="thumb thumb-start" ng-if="getThumbPath(clip)" ng-src="{{ getThumbPath(clip) }}"/>
106104
</div>
107-
<div ng-show="clip.show_audio" class="audio-container">
105+
<div ng-if="clip.show_audio" class="audio-container">
108106
<canvas tl-audio height="46px" width="{{canvasMaxWidth((clip.end - clip.start) * pixelsPerSecond)}}px" class="audio"></canvas>
109107
</div>
108+
109+
<!-- CLIP KEYFRAME POINTS -->
110+
<div class="point_region" ng-if="clip.selected">
111+
<div ng-repeat="(point, value) in getKeyframes(clip)" ng-click="selectPoint(clip, point)" id="point_{{clip.id}}_{{point}}_{{$index}}" class="point point_{{ value }}" style="left: {{(((point - 1) / (project.fps.num / project.fps.den) - clip.start) * pixelsPerSecond)}}px;"></div>
112+
</div>
110113
</div>
111114

112115
<!-- TRANSITIONS -->
113116
<div ng-hide tl-transition ng-repeat="transition in project.effects" id="transition_{{transition.id}}" ng-click="selectTransition(transition.id, true, $event)" ng-right-click="showTransitionMenu(transition.id, $event)" class="transition droppable" ng-class="getClipStyle(transition)" style="width:{{ (transition.end - transition.start) * pixelsPerSecond}}px; left:{{transition.position * pixelsPerSecond}}px; top:{{getTrackTop(transition.layer)}}px;z-index:{{5000 + $index}};">
114117
<div class="transition_top">
115-
<div tl-clip-menu class="transition_menu" ng-show="!enable_razor" ng-mousedown="showTransitionMenu(transition.id, $event)"></div>
116-
<!-- TRANSITION KEYFRAME POINTS -->
117-
<div ng-repeat="(point, value) in getKeyframes(transition)" id="point_{{transition.id}}_{{point}}_{{$index}}" style="left: {{(((point - 1) / (project.fps.num / project.fps.den) - transition.start) * pixelsPerSecond)}}px;" class="point_region" ng-show="transition.selected "><div class="point_icon"></div></div>
118+
<div tl-clip-menu class="transition_menu" ng-if="!enable_razor" ng-mousedown="showTransitionMenu(transition.id, $event)"></div>
118119

119-
<!--div class="transition_label">{{transition.title}}</div-->
120-
<br class="cleared">
120+
<!--div class="transition_label">{{transition.title}}</div-->
121+
<br class="cleared">
121122
</div>
122-
<br class="cleared">
123+
<br class="cleared">
124+
125+
<!-- TRANSITION KEYFRAME POINTS -->
126+
<div class="point_region" ng-if="transition.selected">
127+
<div ng-repeat="(point, value) in getKeyframes(transition)" ng-click="selectPoint(transition, point)" id="point_{{transition.id}}_{{point}}_{{$index}}" class="point point_{{ value }}" style="left: {{(((point - 1) / (project.fps.num / project.fps.den) - transition.start) * pixelsPerSecond)}}px;"></div>
128+
</div>
123129
</div>
124130

125131
</div>
@@ -138,11 +144,11 @@
138144

139145
</script>
140146

141-
<div ng-show="!Qt" class="gear" ng-click="toggleDebug()">
147+
<div ng-if="!Qt" class="gear" ng-click="toggleDebug()">
142148
<img src="media/images/gear.png" width="40">
143149
</div>
144150

145-
<div ng-show="debug" class="debug-window ui-corner-all">
151+
<div ng-if="debug" class="debug-window ui-corner-all">
146152
<div class="debug-text ui-corner-all" style="width: 20%;">PROJECT DATA: <pre>pixels per second: {{pixelsPerSecond}}<br> {{project | json}}</pre></div>
147153
<div class="debug-text ui-corner-all" style="width: 70%;">ACTIONS:<br><br>
148154
<div>

src/timeline/js/controllers.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,28 @@ App.controller("TimelineCtrl", function ($scope) {
138138
}
139139
};
140140

141+
// Get keyframe interpolation type
142+
$scope.lookupInterpolation = function(interpolation_number) {
143+
if (parseInt(interpolation_number) === 0) {
144+
return "bezier";
145+
} else if (parseInt(interpolation_number) === 1) {
146+
return "linear";
147+
} else {
148+
return "constant";
149+
}
150+
}
151+
152+
// Seek to keyframe
153+
$scope.selectPoint = function(object, point) {
154+
var frames_per_second = $scope.project.fps.num / $scope.project.fps.den;
155+
var clip_position_frames = object.position * frames_per_second;
156+
var absolute_seek_frames = clip_position_frames + parseInt(point);
157+
158+
if ($scope.Qt) {
159+
timeline.SeekToKeyframe(absolute_seek_frames)
160+
}
161+
}
162+
141163
// Get an array of keyframe points for the selected clips
142164
$scope.getKeyframes = function (object) {
143165
// List of keyframes
@@ -157,19 +179,21 @@ App.controller("TimelineCtrl", function ($scope) {
157179
if (typeof object[child] === "object" && "Points" in object[child]) {
158180
for (var point = 0; point < object[child].Points.length; point++) {
159181
var co = object[child].Points[point].co;
182+
var interpolation = $scope.lookupInterpolation(object[child].Points[point].interpolation);
160183
if (co.X >= clip_start_x && co.X <= clip_end_x) {
161184
// Only add keyframe coordinates that are within the bounds of the clip
162-
keyframes[co.X] = co.Y;
185+
keyframes[co.X] = interpolation;
163186
}
164187
}
165188
}
166189
// Determine if this property is a Color Keyframe
167190
if (typeof object[child] === "object" && "red" in object[child]) {
168191
for (var color_point = 0; color_point < object[child]["red"].Points.length; color_point++) {
169192
var color_co = object[child]["red"].Points[color_point].co;
193+
var color_interpolation = $scope.lookupInterpolation(object[child]["red"].Points[color_point].interpolation);
170194
if (color_co.X >= clip_start_x && color_co.X <= clip_end_x) {
171195
// Only add keyframe coordinates that are within the bounds of the clip
172-
keyframes[color_co.X] = color_co.Y;
196+
keyframes[color_co.X] = color_interpolation;
173197
}
174198
}
175199
}
@@ -187,25 +211,30 @@ App.controller("TimelineCtrl", function ($scope) {
187211
if (typeof object["effects"][effect][effect_prop] === "object" && "Points" in object["effects"][effect][effect_prop]) {
188212
for (var effect_point = 0; effect_point < object["effects"][effect][effect_prop].Points.length; effect_point++) {
189213
var effect_co = object["effects"][effect][effect_prop].Points[effect_point].co;
214+
var effect_interpolation = $scope.lookupInterpolation(object["effects"][effect][effect_prop].Points[effect_point].interpolation);
190215
if (effect_co.X >= clip_start_x && effect_co.X <= clip_end_x) {
191216
// Only add keyframe coordinates that are within the bounds of the clip
192-
keyframes[effect_co.X] = effect_co.Y;
217+
keyframes[effect_co.X] = effect_interpolation;
193218
}
194219
}
195220
}
196221
// Determine if this property is a Color Keyframe
197222
if (typeof object["effects"][effect][effect_prop] === "object" && "red" in object["effects"][effect][effect_prop]) {
198223
for (var effect_color_point = 0; effect_color_point < object["effects"][effect][effect_prop]["red"].Points.length; effect_color_point++) {
199224
var effect_color_co = object["effects"][effect][effect_prop]["red"].Points[effect_color_point].co;
225+
var effect_color_interpolation = $scope.lookupInterpolation(object["effects"][effect][effect_prop]["red"].Points[effect_color_point].interpolation);
200226
if (effect_color_co.X >= clip_start_x && effect_color_co.X <= clip_end_x) {
201227
// Only add keyframe coordinates that are within the bounds of the clip
202-
keyframes[effect_color_co.X] = effect_color_co.Y;
228+
keyframes[effect_color_co.X] = effect_color_interpolation;
203229
}
204230
}
205231
}
206232
}
207233
}
208234
}
235+
236+
timeline.qt_log("INFO", "object.id: " + object.id + ": " + JSON.stringify(keyframes));
237+
209238
// Return keyframe array
210239
return keyframes;
211240
};
@@ -1466,8 +1495,9 @@ App.controller("TimelineCtrl", function ($scope) {
14661495
show_audio: false,
14671496
alpha: {Points: []},
14681497
location_x: {Points: [
1469-
{co: {X: 1.0, Y: -0.5}},
1470-
{co: {X: 30.0, Y: -0.4}}
1498+
{co: {X: 1.0, Y: -0.5}, interpolation: 0},
1499+
{co: {X: 30.0, Y: -0.4}, interpolation: 1},
1500+
{co: {X: 100.0, Y: -0.4}, interpolation: 2}
14711501
]},
14721502
location_y: {Points: []},
14731503
scale_x: {Points: []},

src/timeline/js/directives/ruler.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ App.directive("tlScrollableTracks", function () {
7171
$("#scrolling_ruler").scrollLeft(element.scrollLeft());
7272
$("#progress_container").scrollLeft(element.scrollLeft());
7373

74-
scope.$apply( () => {
75-
scope.scrollLeft = element[0].scrollLeft;
76-
})
77-
7874
// Send scrollbar position to Qt
7975
if (scope.Qt) {
8076
// Calculate scrollbar positions (left and right edge of scrollbar)

src/timeline/media/css/main.css

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,48 @@ img {
134134
position: absolute;
135135
bottom: 0px;
136136
height: 10px;
137-
width: 10px;
137+
width: 100%;
138138
margin-left: -5px;
139139
margin-bottom: -6px;
140140
overflow: visible;
141141
}
142-
.point_icon {
143-
width: 2px;
142+
.point_bezier {
143+
position: absolute;
144+
width: 10px;
145+
height: 10px;
146+
background-image: url(../images/keyframe-bezier.svg);
147+
background-repeat: no-repeat;
148+
margin: 0;
149+
cursor: pointer;
150+
}
151+
152+
.point_linear {
153+
position: absolute;
154+
width: 10px;
144155
height: 10px;
145-
background: linear-gradient(180deg, #0f08, #0f0);
146-
margin: 0 3px;
156+
background-image: url(../images/keyframe-linear.svg);
157+
background-repeat: no-repeat;
158+
margin: 0;
159+
cursor: pointer;
160+
}
161+
162+
.point_constant {
163+
position: absolute;
164+
width: 10px;
165+
height: 10px;
166+
background-image: url(../images/keyframe-constant.svg);
167+
background-repeat: no-repeat;
168+
margin: 0;
169+
cursor: pointer;
170+
}
171+
172+
.point {
173+
filter: brightness(100%);
174+
transition: 0.3s;
175+
}
176+
177+
.point:hover {
178+
filter: brightness(150%);
147179
}
148180

149181
/* Transitions */
Lines changed: 70 additions & 0 deletions
Loading
Lines changed: 73 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)