Context
Exports always keep the source's aspect ratio. ExportSettings.renderSize(for:) fits the screen into a resolution box, and FrameComposer letterboxes the screen onto that canvas. For LinkedIn, Instagram, TikTok and Shorts, people want 1:1 and 9:16 videos.
Where to look
Sources/SnapcapCore/Model/Project.swift: ExportResolution, ExportSettings, and renderSize(for:), which never upscales, keeps dimensions even, and applies H.264 limits of 4096×2304 and 2304×4096.
Sources/SnapcapCore/Render/CompositionBuilder.swift: vc.renderSize = project.export.renderSize(for: screenSize).
Sources/SnapcapCore/Render/FrameComposer.swift: fit(_:into:) aspect-fits the screen on black.
Sources/SnapcapCore/Layout/OverlayLayout.swift: the bubble's position and size are relative to the canvas (size uses the shorter side), so it adapts automatically. Check how it looks.
Sources/Snapcap/Views/EditorView.swift: PlayerStage sizes the stage from project.source.pixelSize. The preview must use the export canvas's aspect ratio and place the screen the same way the export does. The export pickers are in EditorInspector, and the setup window has matching pickers in Sources/Snapcap/Views/RecorderView.swift.
Tests/SnapcapCoreTests/LayoutTests.swift: renderSizeNeverUpscalesAndStaysEven.
Proposal
- Add
ExportSettings.aspect: original, square or portrait9x16. Decode it leniently with original as the default; the fingerprint picks it up automatically.
- Canvas size: for 1:1, use the resolution box's short side (1080p → 1080×1080); for 9:16, 1080p → 1080×1920. For
original resolution, derive the size from the source's shorter side. Keep dimensions even and respect the H.264 limits.
- Screen placement:
fit (letterbox on a background color) or fill (crop), with a horizontal focus slider (focusX, 0…1) for fill.
- Consider a bottom-center default bubble position for 9:16. The existing normalized x/y still works.
Acceptance criteria
Context
Exports always keep the source's aspect ratio.
ExportSettings.renderSize(for:)fits the screen into a resolution box, andFrameComposerletterboxes the screen onto that canvas. For LinkedIn, Instagram, TikTok and Shorts, people want 1:1 and 9:16 videos.Where to look
Sources/SnapcapCore/Model/Project.swift:ExportResolution,ExportSettings, andrenderSize(for:), which never upscales, keeps dimensions even, and applies H.264 limits of 4096×2304 and 2304×4096.Sources/SnapcapCore/Render/CompositionBuilder.swift:vc.renderSize = project.export.renderSize(for: screenSize).Sources/SnapcapCore/Render/FrameComposer.swift:fit(_:into:)aspect-fits the screen on black.Sources/SnapcapCore/Layout/OverlayLayout.swift: the bubble's position and size are relative to the canvas (size uses the shorter side), so it adapts automatically. Check how it looks.Sources/Snapcap/Views/EditorView.swift:PlayerStagesizes the stage fromproject.source.pixelSize. The preview must use the export canvas's aspect ratio and place the screen the same way the export does. The export pickers are inEditorInspector, and the setup window has matching pickers inSources/Snapcap/Views/RecorderView.swift.Tests/SnapcapCoreTests/LayoutTests.swift:renderSizeNeverUpscalesAndStaysEven.Proposal
ExportSettings.aspect:original,squareorportrait9x16. Decode it leniently withoriginalas the default; the fingerprint picks it up automatically.originalresolution, derive the size from the source's shorter side. Keep dimensions even and respect the H.264 limits.fit(letterbox on a background color) orfill(crop), with a horizontal focus slider (focusX, 0…1) for fill.Acceptance criteria
renderSize.ExportTestsstay green.OverlayLayoutsays it should.