7
7
Setter ,
8
8
Show ,
9
9
batch ,
10
+ createEffect ,
10
11
createRoot ,
11
12
createSignal ,
12
13
on ,
@@ -300,101 +301,111 @@ function ClipTrack(props: Pick<ComponentProps<"div">, "ref">) {
300
301
return (
301
302
< TrackRoot ref = { props . ref } >
302
303
< For each = { segments ( ) } >
303
- { ( segment , i ) => (
304
- < SegmentRoot
305
- class = "border-blue-300"
306
- innerClass = "ring-blue-300"
307
- segment = { segment }
308
- onMouseDown = { ( e ) => {
309
- if ( ! split ( ) ) return ;
310
- e . stopPropagation ( ) ;
304
+ { ( segment , i ) => {
305
+ const prevDuration = ( ) =>
306
+ segments ( )
307
+ . slice ( 0 , i ( ) )
308
+ . reduce ( ( t , s ) => t + ( s . end - s . start ) / s . timescale , 0 ) ;
311
309
312
- const rect = e . currentTarget . getBoundingClientRect ( ) ;
313
- const fraction = ( e . clientX - rect . left ) / rect . width ;
314
-
315
- const splitTime =
316
- segment . start + fraction * ( segment . end - segment . start ) ;
317
-
318
- setProject (
319
- "timeline" ,
320
- "segments" ,
321
- produce ( ( segments ) => {
322
- segments . splice ( i ( ) + 1 , 0 , {
323
- start : splitTime ,
324
- end : segment . end ,
325
- timescale : 1 ,
326
- recordingSegment : segment . recordingSegment ,
327
- } ) ;
328
- segments [ i ( ) ] . end = splitTime ;
329
- } )
330
- ) ;
331
- } }
332
- >
333
- < SegmentHandle
334
- class = "bg-blue-300"
335
- onMouseDown = { ( downEvent ) => {
336
- const start = segment . start ;
337
-
338
- const maxSegmentDuration =
339
- editorInstance . recordings . segments [
340
- segment . recordingSegment ?? 0
341
- ] . display . duration ;
342
-
343
- const availableTimelineDuration =
344
- editorInstance . recordingDuration -
345
- segments ( ) . reduce (
346
- ( acc , segment , segmentI ) =>
347
- segmentI === i ( )
348
- ? acc
349
- : acc +
350
- ( segment . end - segment . start ) / segment . timescale ,
351
- 0
352
- ) ;
310
+ return (
311
+ < SegmentRoot
312
+ class = "border-blue-300"
313
+ innerClass = "ring-blue-300"
314
+ segment = { {
315
+ ...segment ,
316
+ start : prevDuration ( ) ,
317
+ end : segment . end - segment . start + prevDuration ( ) ,
318
+ } }
319
+ onMouseDown = { ( e ) => {
320
+ if ( ! split ( ) ) return ;
321
+ e . stopPropagation ( ) ;
353
322
354
- const maxDuration = Math . min (
355
- maxSegmentDuration ,
356
- availableTimelineDuration
323
+ const rect = e . currentTarget . getBoundingClientRect ( ) ;
324
+ const fraction = ( e . clientX - rect . left ) / rect . width ;
325
+
326
+ const splitTime =
327
+ segment . start + fraction * ( segment . end - segment . start ) ;
328
+
329
+ setProject (
330
+ "timeline" ,
331
+ "segments" ,
332
+ produce ( ( segments ) => {
333
+ segments . splice ( i ( ) + 1 , 0 , {
334
+ start : splitTime ,
335
+ end : segment . end ,
336
+ timescale : 1 ,
337
+ recordingSegment : segment . recordingSegment ,
338
+ } ) ;
339
+ segments [ i ( ) ] . end = splitTime ;
340
+ } )
357
341
) ;
342
+ } }
343
+ >
344
+ < SegmentHandle
345
+ class = "bg-blue-300"
346
+ onMouseDown = { ( downEvent ) => {
347
+ const start = segment . start ;
348
+
349
+ const maxSegmentDuration =
350
+ editorInstance . recordings . segments [
351
+ segment . recordingSegment ?? 0
352
+ ] . display . duration ;
353
+
354
+ const availableTimelineDuration =
355
+ editorInstance . recordingDuration -
356
+ segments ( ) . reduce (
357
+ ( acc , segment , segmentI ) =>
358
+ segmentI === i ( )
359
+ ? acc
360
+ : acc +
361
+ ( segment . end - segment . start ) / segment . timescale ,
362
+ 0
363
+ ) ;
358
364
359
- function update ( event : MouseEvent ) {
360
- const newStart =
361
- start +
362
- ( event . clientX - downEvent . clientX ) * secsPerPixel ( ) ;
363
-
364
- setProject (
365
- "timeline" ,
366
- "segments" ,
367
- i ( ) ,
368
- "start" ,
369
- Math . min (
370
- Math . max (
371
- Math . max ( newStart , 0 ) ,
372
- segment . end - maxDuration
373
- ) ,
374
- segment . end - 1
375
- )
365
+ const maxDuration = Math . min (
366
+ maxSegmentDuration ,
367
+ availableTimelineDuration
376
368
) ;
377
- }
378
369
379
- const resumeHistory = history . pause ( ) ;
380
- createRoot ( ( dispose ) => {
381
- createEventListenerMap ( window , {
382
- mousemove : update ,
383
- mouseup : ( e ) => {
384
- dispose ( ) ;
385
- resumeHistory ( ) ;
386
- update ( e ) ;
387
- onHandleReleased ( ) ;
388
- } ,
370
+ function update ( event : MouseEvent ) {
371
+ const newStart =
372
+ start +
373
+ ( event . clientX - downEvent . clientX ) * secsPerPixel ( ) ;
374
+
375
+ setProject (
376
+ "timeline" ,
377
+ "segments" ,
378
+ i ( ) ,
379
+ "start" ,
380
+ Math . min (
381
+ Math . max (
382
+ Math . max ( newStart , 0 ) ,
383
+ segment . end - maxDuration
384
+ ) ,
385
+ segment . end - 1
386
+ )
387
+ ) ;
388
+ }
389
+
390
+ const resumeHistory = history . pause ( ) ;
391
+ createRoot ( ( dispose ) => {
392
+ createEventListenerMap ( window , {
393
+ mousemove : update ,
394
+ mouseup : ( e ) => {
395
+ dispose ( ) ;
396
+ resumeHistory ( ) ;
397
+ update ( e ) ;
398
+ onHandleReleased ( ) ;
399
+ } ,
400
+ } ) ;
389
401
} ) ;
390
- } ) ;
391
- } }
392
- />
393
- < SegmentContent class = "bg-blue-50 justify-between" >
394
- < span class = "text-black-transparent-60 text-[0.625rem] mt-auto" >
395
- { formatTime ( segment . start ) }
396
- </ span >
397
- { /* <Show when={segments().length > 1}>
402
+ } }
403
+ />
404
+ < SegmentContent class = "bg-blue-50 justify-between" >
405
+ < span class = "text-black-transparent-60 text-[0.625rem] mt-auto" >
406
+ { formatTime ( segment . start ) }
407
+ </ span >
408
+ { /* <Show when={segments().length > 1}>
398
409
<button
399
410
onClick={() => {
400
411
setProject(
@@ -410,67 +421,69 @@ function ClipTrack(props: Pick<ComponentProps<"div">, "ref">) {
410
421
<IconCapTrash class="size-4 text-gray-400 group-hover/button:text-gray-500 transition-colors" />
411
422
</button>
412
423
</Show> */ }
413
- < span class = "text-black-transparent-60 text-[0.625rem] mt-auto" >
414
- { formatTime ( segment . end ) }
415
- </ span >
416
- </ SegmentContent >
417
- < SegmentHandle
418
- class = "bg-blue-300"
419
- onMouseDown = { ( downEvent ) => {
420
- const end = segment . end ;
421
-
422
- const maxSegmentDuration =
423
- editorInstance . recordings . segments [
424
- segment . recordingSegment ?? 0
425
- ] . display . duration ;
426
-
427
- const availableTimelineDuration =
428
- editorInstance . recordingDuration -
429
- segments ( ) . reduce (
430
- ( acc , segment , segmentI ) =>
431
- segmentI === i ( )
432
- ? acc
433
- : acc +
434
- ( segment . end - segment . start ) / segment . timescale ,
435
- 0
436
- ) ;
424
+ < span class = "text-black-transparent-60 text-[0.625rem] mt-auto" >
425
+ { formatTime ( segment . end ) }
426
+ </ span >
427
+ </ SegmentContent >
428
+ < SegmentHandle
429
+ class = "bg-blue-300"
430
+ onMouseDown = { ( downEvent ) => {
431
+ const end = segment . end ;
432
+
433
+ const maxSegmentDuration =
434
+ editorInstance . recordings . segments [
435
+ segment . recordingSegment ?? 0
436
+ ] . display . duration ;
437
+
438
+ const availableTimelineDuration =
439
+ editorInstance . recordingDuration -
440
+ segments ( ) . reduce (
441
+ ( acc , segment , segmentI ) =>
442
+ segmentI === i ( )
443
+ ? acc
444
+ : acc +
445
+ ( segment . end - segment . start ) / segment . timescale ,
446
+ 0
447
+ ) ;
437
448
438
- function update ( event : MouseEvent ) {
439
- const newEnd =
440
- end + ( event . clientX - downEvent . clientX ) * secsPerPixel ( ) ;
441
-
442
- setProject (
443
- "timeline" ,
444
- "segments" ,
445
- i ( ) ,
446
- "end" ,
447
- Math . max (
448
- Math . min (
449
- newEnd ,
450
- maxSegmentDuration ,
451
- availableTimelineDuration
452
- ) ,
453
- segment . start + 1
454
- )
455
- ) ;
456
- }
449
+ function update ( event : MouseEvent ) {
450
+ const newEnd =
451
+ end +
452
+ ( event . clientX - downEvent . clientX ) * secsPerPixel ( ) ;
457
453
458
- const resumeHistory = history . pause ( ) ;
459
- createRoot ( ( dispose ) => {
460
- createEventListenerMap ( window , {
461
- mousemove : update ,
462
- mouseup : ( e ) => {
463
- dispose ( ) ;
464
- resumeHistory ( ) ;
465
- update ( e ) ;
466
- onHandleReleased ( ) ;
467
- } ,
454
+ setProject (
455
+ "timeline" ,
456
+ "segments" ,
457
+ i ( ) ,
458
+ "end" ,
459
+ Math . max (
460
+ Math . min (
461
+ newEnd ,
462
+ maxSegmentDuration ,
463
+ availableTimelineDuration
464
+ ) ,
465
+ segment . start + 1
466
+ )
467
+ ) ;
468
+ }
469
+
470
+ const resumeHistory = history . pause ( ) ;
471
+ createRoot ( ( dispose ) => {
472
+ createEventListenerMap ( window , {
473
+ mousemove : update ,
474
+ mouseup : ( e ) => {
475
+ dispose ( ) ;
476
+ resumeHistory ( ) ;
477
+ update ( e ) ;
478
+ onHandleReleased ( ) ;
479
+ } ,
480
+ } ) ;
468
481
} ) ;
469
- } ) ;
470
- } }
471
- / >
472
- </ SegmentRoot >
473
- ) }
482
+ } }
483
+ />
484
+ </ SegmentRoot >
485
+ ) ;
486
+ } }
474
487
</ For >
475
488
</ TrackRoot >
476
489
) ;
@@ -492,7 +505,6 @@ function ZoomTrack(props: {
492
505
< div class = "h-2 w-full" />
493
506
494
507
< TrackRoot
495
- isFreeForm
496
508
onMouseMove = { ( e ) => {
497
509
if ( hoveringSegment ( ) ) {
498
510
setHoveredTime ( undefined ) ;
@@ -823,14 +835,11 @@ function ZoomTrack(props: {
823
835
) ;
824
836
}
825
837
826
- function TrackRoot ( props : ComponentProps < "div" > & { isFreeForm ?: boolean } ) {
838
+ function TrackRoot ( props : ComponentProps < "div" > ) {
827
839
const [ ref , setRef ] = createSignal < HTMLDivElement > ( ) ;
828
840
829
841
return (
830
- < TrackContextProvider
831
- ref = { ref }
832
- isFreeForm = { ( ) => props . isFreeForm ?? false }
833
- >
842
+ < TrackContextProvider ref = { ref } >
834
843
< div
835
844
{ ...props }
836
845
ref = { mergeRefs ( setRef , props . ref ) }
@@ -851,7 +860,7 @@ function SegmentRoot(
851
860
) => void ;
852
861
}
853
862
) {
854
- const { isFreeForm , secsPerPixel } = useTrackContext ( ) ;
863
+ const { secsPerPixel } = useTrackContext ( ) ;
855
864
const { state, project } = useEditorContext ( ) ;
856
865
857
866
const isSelected = createMemo ( ( ) => {
@@ -868,7 +877,7 @@ function SegmentRoot(
868
877
const translateX = createMemo ( ( ) => {
869
878
const base = state . timelineTransform . position ;
870
879
871
- const delta = ! isFreeForm ( ) ? 0 : props . segment . start ;
880
+ const delta = props . segment . start ;
872
881
873
882
return ( delta - base ) / secsPerPixel ( ) ;
874
883
} ) ;
0 commit comments