27
27
*/
28
28
29
29
30
- /*global setSelections, setBoundingBox, moveBoundingBox, bounding_box */
30
+ /*global App, timeline, secondsToTime, setSelections, setBoundingBox, moveBoundingBox, bounding_box */
31
31
// Variables for panning by middle click
32
32
var is_scrolling = false ;
33
33
var starting_scrollbar = { x : 0 , y : 0 } ;
@@ -39,7 +39,6 @@ var scroll_left_pixels = 0;
39
39
40
40
// This container allows for tracks to be scrolled (with synced ruler)
41
41
// and allows for panning of the timeline with the middle mouse button
42
- /*global App, timeline, secondsToTime*/
43
42
App . directive ( "tlScrollableTracks" , function ( ) {
44
43
return {
45
44
restrict : "A" ,
@@ -154,11 +153,24 @@ App.directive("tlRuler", function ($timeout) {
154
153
return {
155
154
restrict : "A" ,
156
155
link : function ( scope , element , attrs ) {
157
- //on click of the ruler canvas, jump playhead to the clicked spot
156
+ var isDragging = false ;
157
+
158
+ // Start dragging when mousedown on the ruler
158
159
element . on ( "mousedown" , function ( e ) {
160
+ // Set bounding box for the playhead position
161
+ setBoundingBox ( scope , $ ( "#playhead" ) , "playhead" ) ;
162
+ isDragging = true ;
163
+
164
+ if ( scope . Qt ) {
165
+ // Disable caching thread during scrubbing
166
+ timeline . DisableCacheThread ( ) ;
167
+ }
168
+
159
169
// Get playhead position
160
170
var playhead_left = e . pageX - element . offset ( ) . left ;
161
171
var playhead_seconds = snapToFPSGridTime ( scope , pixelToTime ( scope , playhead_left ) ) ;
172
+ playhead_seconds = Math . min ( Math . max ( 0.0 , playhead_seconds ) , scope . project . duration ) ;
173
+ var playhead_snapped_target = playhead_seconds * scope . pixelsPerSecond ;
162
174
163
175
// Immediately preview frame (don't wait for animated playhead)
164
176
scope . previewFrame ( playhead_seconds ) ;
@@ -170,8 +182,8 @@ App.directive("tlRuler", function ($timeout) {
170
182
171
183
// Animate to new position (and then update scope)
172
184
scope . playhead_animating = true ;
173
- $ ( ".playhead-line" ) . animate ( { left : playhead_left } , 200 ) ;
174
- $ ( ".playhead-top" ) . animate ( { left : playhead_left } , 200 , function ( ) {
185
+ $ ( ".playhead-line" ) . animate ( { left : playhead_snapped_target } , 150 ) ;
186
+ $ ( ".playhead-top" ) . animate ( { left : playhead_snapped_target } , 150 , function ( ) {
175
187
// Update playhead
176
188
scope . movePlayhead ( playhead_seconds ) ;
177
189
@@ -182,30 +194,14 @@ App.directive("tlRuler", function ($timeout) {
182
194
} ) ;
183
195
} ) ;
184
196
185
- element . on ( "mousedown" , function ( e ) {
186
- // Set bounding box for the playhead position
187
- setBoundingBox ( scope , $ ( "#playhead" ) , "playhead" ) ;
188
- if ( scope . Qt ) {
189
- // Disable caching thread during scrubbing
190
- timeline . DisableCacheThread ( ) ;
191
- }
192
- } ) ;
193
-
194
- element . on ( "contextmenu" , function ( e ) {
195
- if ( scope . Qt ) {
196
- // Enable caching thread after scrubbing
197
- timeline . EnableCacheThread ( ) ;
198
- }
199
- } ) ;
200
-
201
- // Move playhead to new position (if it's not currently being animated)
202
- element . on ( "mousemove" , function ( e ) {
203
- if ( e . which === 1 && ! scope . playhead_animating && ! scope . getDragging ( ) ) { // left button
197
+ // Global mousemove listener
198
+ $ ( document ) . on ( "mousemove" , function ( e ) {
199
+ if ( isDragging && e . which === 1 && ! scope . playhead_animating && ! scope . getDragging ( ) ) { // left button is held
204
200
// Calculate the playhead bounding box movement
205
201
let cursor_position = e . pageX - $ ( "#ruler" ) . offset ( ) . left ;
206
202
let new_position = cursor_position ;
207
203
if ( e . shiftKey ) {
208
- // Only apply playhead shapping when SHIFT is pressed
204
+ // Only apply playhead snapping when SHIFT is pressed
209
205
let results = moveBoundingBox ( scope , bounding_box . left , bounding_box . top ,
210
206
cursor_position - bounding_box . left , cursor_position - bounding_box . top ,
211
207
cursor_position , cursor_position , "playhead" ) ;
@@ -216,11 +212,24 @@ App.directive("tlRuler", function ($timeout) {
216
212
217
213
// Move playhead
218
214
let playhead_seconds = new_position / scope . pixelsPerSecond ;
215
+ playhead_seconds = Math . min ( Math . max ( 0.0 , playhead_seconds ) , scope . project . duration ) ;
219
216
scope . movePlayhead ( playhead_seconds ) ;
220
217
scope . previewFrame ( playhead_seconds ) ;
221
218
}
222
219
} ) ;
223
220
221
+ // Global mouseup listener to stop dragging
222
+ $ ( document ) . on ( "mouseup" , function ( e ) {
223
+ if ( isDragging ) {
224
+ isDragging = false ;
225
+
226
+ if ( scope . Qt ) {
227
+ // Enable caching thread after scrubbing
228
+ timeline . EnableCacheThread ( ) ;
229
+ }
230
+ }
231
+ } ) ;
232
+
224
233
/**
225
234
* Draw frame precision alternating banding on each track (when zoomed in)
226
235
*/
0 commit comments