From fec8d86a2c05bec7c3ffcae6f513f57a75f70cac Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Mon, 13 Jan 2025 19:13:39 +0800 Subject: [PATCH] improve small timeline zoom segments --- apps/desktop/src/routes/editor/Timeline.tsx | 88 +++++++++++++-------- apps/desktop/src/routes/editor/context.ts | 5 ++ crates/export/src/lib.rs | 4 +- crates/rendering/src/lib.rs | 18 ++--- 4 files changed, 72 insertions(+), 43 deletions(-) diff --git a/apps/desktop/src/routes/editor/Timeline.tsx b/apps/desktop/src/routes/editor/Timeline.tsx index 89e76512..2b0a9df2 100644 --- a/apps/desktop/src/routes/editor/Timeline.tsx +++ b/apps/desktop/src/routes/editor/Timeline.tsx @@ -17,9 +17,11 @@ import { createMemo } from "solid-js"; import { commands, TimelineSegment } from "~/utils/tauri"; import { + SegmentContextProvider, TimelineContextProvider, TrackContextProvider, useEditorContext, + useSegmentContext, useTimelineContext, useTrackContext, } from "./context"; @@ -459,7 +461,7 @@ export function Timeline() { return ( { @@ -470,7 +472,7 @@ export function Timeline() { }} > { const start = segment.start; @@ -531,7 +533,7 @@ export function Timeline() { }} /> { setState("timelineSelection", { type: "zoom", @@ -540,15 +542,23 @@ export function Timeline() { e.stopPropagation(); }} > -
-
- {" "} - {zoomPercentage()} -
-
+ {(() => { + const ctx = useSegmentContext(); + + return ( + 100}> +
+
+ {" "} + {zoomPercentage()} +
+
+
+ ); + })()}
{ const end = segment.end; @@ -669,34 +679,38 @@ function SegmentRoot( return (props.segment.start / duration()) * (trackBounds.width ?? 0); }); + const width = () => + ((trackBounds.width ?? 0) * (props.segment.end - props.segment.start)) / + duration(); + return ( -
+
- {props.children} +
+ {props.children} +
-
+ ); } @@ -713,7 +727,15 @@ function SegmentContent(props: ComponentProps<"div">) { } function SegmentHandle(props: ComponentProps<"div">) { + const ctx = useSegmentContext(); return ( -
+
); } diff --git a/apps/desktop/src/routes/editor/context.ts b/apps/desktop/src/routes/editor/context.ts index 58127a3e..5b70b739 100644 --- a/apps/desktop/src/routes/editor/context.ts +++ b/apps/desktop/src/routes/editor/context.ts @@ -183,3 +183,8 @@ export const [TrackContextProvider, useTrackContext] = createContextProvider( }, null! ); + +export const [SegmentContextProvider, useSegmentContext] = + createContextProvider((props: { width: Accessor }) => { + return props; + }, null!); diff --git a/crates/export/src/lib.rs b/crates/export/src/lib.rs index 383fc1cf..15bb567d 100644 --- a/crates/export/src/lib.rs +++ b/crates/export/src/lib.rs @@ -156,7 +156,7 @@ where MP4Encoder::video_format(), self.output_size.0, self.output_size.1, - 30, + FPS, ), audio_info, cap_media::encoders::Output::File(self.output_path.clone()), @@ -310,6 +310,7 @@ where tx_image_data, &self.meta, self.render_segments, + FPS, ) .then(|f| async { f.map_err(Into::into) }); @@ -489,6 +490,7 @@ where tx_image_data, &self.meta, self.render_segments, + FPS, ) .await?; diff --git a/crates/rendering/src/lib.rs b/crates/rendering/src/lib.rs index 5fd7e577..53c709f8 100644 --- a/crates/rendering/src/lib.rs +++ b/crates/rendering/src/lib.rs @@ -159,6 +159,7 @@ pub async fn render_video_to_channel( sender: mpsc::Sender, meta: &RecordingMeta, segments: Vec, + fps: u32, ) -> Result<(), RenderingError> { let constants = RenderVideoConstants::new(options, meta).await?; let recordings = ProjectRecordings::new(meta); @@ -206,7 +207,7 @@ pub async fn render_video_to_channel( } }; - let total_frames = (30_f64 * duration).ceil() as u32; + let total_frames = (fps as f64 * duration).ceil() as u32; println!( "Final export duration: {} seconds ({} frames at 30fps)", duration, total_frames @@ -356,7 +357,6 @@ impl RenderVideoConstants { depth_or_array_layers: 1, }, ); - println!("Watermark texture created and written to GPU"); let watermark_view = watermark_texture.create_view(&wgpu::TextureViewDescriptor::default()); let watermark_sampler = device.create_sampler(&wgpu::SamplerDescriptor { @@ -1091,12 +1091,12 @@ pub async fn produce_frame( is_upgraded: 0.0, }; - println!( - "Rendering watermark at position: {:?}, size: {:?}, output_size: {:?}", - watermark_uniforms.position, - watermark_uniforms.watermark_size, - watermark_uniforms.output_size - ); + // println!( + // "Rendering watermark at position: {:?}, size: {:?}, output_size: {:?}", + // watermark_uniforms.position, + // watermark_uniforms.watermark_size, + // watermark_uniforms.output_size + // ); let watermark_buffer = constants @@ -1170,7 +1170,7 @@ pub async fn produce_frame( render_pass.set_pipeline(&constants.watermark_pipeline.render_pipeline); render_pass.set_bind_group(0, &watermark_bind_group, &[]); render_pass.draw(0..6, 0..1); // Using 6 vertices for two triangles - println!("Drew watermark with 6 vertices"); + // println!("Drew watermark with 6 vertices"); } constants.queue.submit(Some(watermark_encoder.finish()));