Skip to content

EffectsSpace

Photo, Video & Motionv0.1.0-alpha.1 MIT

A C# motion-design and compositing workbench for desktop and browser

EffectsSpace is an independent motion-design and compositing application built with Uno Platform, .NET and SkiaSharp, operating on a real composition model of layers, nested compositions, keyframes, masks, mattes, effects, video frames and audio samples. The browser app is the same C# Uno workbench compiled to WebAssembly, drawing preview into Uno's existing Skia canvas. It imports Motion JPEG AVI and PCM WAVE media and exports PNG sequences, AVI with sound and high-precision WAVE mixes.

11reusable, packable libraries
17layer blend modes
11built-in effects
96 kHzFloat32 / PCM24 WAVE delivery
EffectsSpacewieslawsoltes.github.io/EffectsSpace/
EffectsSpace running in a browser
Highlights

What makes EffectsSpace special

Familiar if you know Adobe After Effects-style motion design tools — but original, local‑first and written end‑to‑end in C#.

Layered compositions

Shapes, Bezier paths, text, images, Motion JPEG video, PCM audio, nulls, guides, adjustment layers and nested pre-comps.

Keyframe animation

Stopwatches, auto-key, linear/hold/Bezier interpolation, Easy Ease and value or signed-velocity graphs.

Multi-key editing

Select, marquee, retime, copy, cut and paste keys across transform, effect and audio channels as single undoable transactions.

Masks and mattes

Independently feathered Add/Subtract/Intersect masks with direct node editing, plus alpha and luma track mattes.

Effects and blend modes

Blur, Glow, Drop Shadow, Exposure, Fractal Noise, Vignette and more, with seventeen blend modes and masked adjustment layers.

Bounded expressions

Side-effect-free scalar expressions with time, clamp, linear, ease, wiggle and loopOut; not JavaScript and no host access.

Real media and audio

Import Motion JPEG AVI and PCM WAVE, remap source time, animate gain/balance and preview on the Web Audio clock.

Precision delivery

Export transparent PNG sequences, Motion JPEG AVI with stereo sound, or PCM16/PCM24/Float32 WAVE with optional TPDF dither.

0reusable libraries
0lines of C# & XAML
0features catalogued
0.NET projects
0CI workflows
0docs
Feature tour

29 capabilities, 7 areas

Compose

  • Solids, rounded rectangles, ellipses, stars, Bezier paths and inline-edited text
  • Images, Motion JPEG video, PCM audio, nulls and guides
  • Parent chains, nested compositions and pre-compose
  • Seventeen blend modes and multi-sample composition motion blur

Viewer

  • Fit, zoom and pan
  • Move, eight scale handles, rotation and anchor compensation
  • Pen tool with symmetric Bezier handles and path node editing
  • Direct mask node and tangent editing with cancellation

Animate

  • Frame-snapped time, stopwatches and auto-key
  • Linear, Hold and Bezier interpolation with Easy Ease
  • Value and signed-velocity graph editors
  • Multi-key selection, retiming, nudging and session-local clipboard
  • Bounded scalar expressions: wiggle, loopOut, linear, ease, clamp

Composite

  • Masked adjustment layers that affect only layers below
  • Alpha, alpha inverted, luma and luma inverted track mattes
  • Add/Subtract/Intersect/None masks with opacity, feather, expansion and inversion
  • Time remap, freeze frame and continuous remap-curve reversal

Effects

  • Blur, Glow and Drop Shadow
  • Exposure, Brightness/Contrast, Hue/Saturation and Tint
  • Invert and Posterize
  • Fractal Noise fill generator and Vignette overlay

Media and audio

  • Classic Motion JPEG AVI with optional PCM audio
  • Mono/stereo integer and float WAVE, 8–192 kHz
  • Gain and balance automation with source waveform display
  • Band-limited windowed-sinc resampling with an exact same-rate path

Projects and delivery

  • Versioned, self-contained .effects projects with embedded media
  • IndexedDB (browser) and local app-data (desktop) recovery
  • Transparent PNG frames and ZIP PNG sequences with a rational manifest
  • Motion JPEG AVI with PCM16/48 kHz sound and PCM16/PCM24/Float32 WAVE mixes
Integrated playground

Run EffectsSpace right here

The browser studio opens the editable ORBITAL motion study at its hero frame, running the same C# workbench compiled to WebAssembly. Switch viewports, go fullscreen and tick off the guided tour as you explore.

https://wieslawsoltes.github.io/EffectsSpace/
EffectsSpace screenshot

Try EffectsSpace live

The browser studio opens the editable ORBITAL motion study at its hero frame, running the same C# workbench compiled to WebAssembly.

Real C# · Uno WebAssembly · runs locally in your browser
Booting .NET WebAssembly runtime…
Reusable packages

11 libraries you can embed

EffectsSpace is assembled from independently reusable libraries, each published on NuGet.org. Hover the graph to trace dependencies; click a node to jump to its package, and open a card for install and usage.

Core 321 lines Animation 254 lines Documents 170 lines Editing 679 lines Rendering 110 lines Media 970 lines Skia 715 lines Controls 314 lines Viewer 628 lines Timeline 595 lines Workbench 1,168 lines App 286 lines
Arrows point from a project to what it references. Bars show relative size. ModelEngineI/ORenderingControlsEditorWorkbench
Model 0.1.0-alpha.1

EffectsSpace.Core

Compositions, layers, paths, effects, channels and rational time

No UI depsnet10.0
321 lines18 files0 refsUsage
Engine 0.1.0-alpha.1

EffectsSpace.Animation

Curves, derivatives, easing, transforms and bounded expressions

No UI depsnet10.0
refs → Core
254 lines5 files1 refsUsage
I/O 0.1.0-alpha.1

EffectsSpace.Documents

Versioned JSON, validation, budgets and storage/audio-output contracts

No UI depsnet10.0
refs → Core
170 lines4 files1 refsUsage
Engine 0.1.0-alpha.1

EffectsSpace.Editing

Transactions, selection-aware history, keyframe clipboard and commands

No UI depsnet10.0
refs → Animation, Documents
679 lines8 files2 refsUsage
Rendering 0.1.0-alpha.1

EffectsSpace.Rendering

Indexed frame evaluation, render plans, hit testing and export schedules

No UI depsnet10.0
refs → Animation
110 lines3 files1 refsUsage
I/O 0.1.0-alpha.1

EffectsSpace.Media

RIFF/AVI/WAVE, PCM indexing, sinc resampling, audio mixing and AVI muxing

No UI depsnet10.0
refs → Animation
970 lines14 files1 refsUsage
Rendering 0.1.0-alpha.1

EffectsSpace.Skia

Compositing, filters and masks, resource caches and PNG/AVI rendering

SkiaSharpnet10.0
refs → Rendering, Media
nuget → SkiaSharp
715 lines10 files2 refsUsage
Controls 0.1.0-alpha.1

EffectsSpace.Controls

Original studio chrome, icons, choices, splitters and numeric scrubbing

Unonet10.0-browserwasmnet10.0-desktop
refs → Core
314 lines7 files1 refsUsage
Editor 0.1.0-alpha.1

EffectsSpace.Viewer

Composition viewer with camera, transforms, paths, inline text, masks and waveform

Uno + Skianet10.0-browserwasmnet10.0-desktop
refs → Controls, Editing, Skia
628 lines5 files3 refsUsage
Editor 0.1.0-alpha.1

EffectsSpace.Timeline

Row-cached timeline, clip/key editing, marquee and value/velocity graphs

Uno + Skianet10.0-browserwasmnet10.0-desktop
refs → Controls, Editing, Rendering
595 lines5 files3 refsUsage
Workbench 0.1.0-alpha.1

EffectsSpace.Workbench

Panels, media/delivery settings, transport, render queue and document workflows

Uno + Skianet10.0-browserwasmnet10.0-desktop
refs → Viewer, Timeline
1,168 lines13 files2 refsUsage
Install from NuGet

11 packages on NuGet.org

The studio is built from eleven MIT-licensed packages that are versioned and released together; the app itself is a thin platform host. Seven packages (Core through Skia) target plain net10.0 and have no UI dependency; only EffectsSpace.Skia pulls in SkiaSharp. Controls, Viewer, Timeline and Workbench are Uno Platform libraries targeting net10.0-desktop and net10.0-browserwasm. Every package ships symbols to NuGet.org (.snupkg) with SourceLink.

11packages
0.1.0-alpha.1pre-release · Sep 29, 2026
7plain .NET — no UI framework
Newjust published
bashStart with the foundation package
dotnet add package EffectsSpace.Core --prerelease
xmlEvery package — keep only what you need
<PackageReference Include="EffectsSpace.Core" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Animation" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Documents" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Editing" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Rendering" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Media" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Skia" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Controls" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Viewer" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Timeline" Version="0.1.0-alpha.1" />
<PackageReference Include="EffectsSpace.Workbench" Version="0.1.0-alpha.1" />
xmlCentral package management
<!-- Directory.Packages.props -->
<ItemGroup>
  <PackageVersion Include="EffectsSpace.Core" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Animation" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Documents" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Editing" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Rendering" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Media" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Skia" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Controls" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Viewer" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Timeline" Version="0.1.0-alpha.1" />
  <PackageVersion Include="EffectsSpace.Workbench" Version="0.1.0-alpha.1" />
</ItemGroup>

Published with NuGet Trusted Publishing from GitHub Actions, with symbols (.snupkg) and SourceLink. Release v0.1.0-alpha.1 ↗

Dependencies (from project references):

Core ← Animation, Documents
Animation + Documents ← Editing
Animation ← Rendering, Media
Rendering + Media (+ SkiaSharp) ← Skia
Core ← Controls (Uno)
Controls + Editing + Skia ← Viewer
Controls + Editing + Rendering ← Timeline
Viewer + Timeline ← Workbench

More integration detail: Embedding and Portable media.

EffectsSpace.Core

ModelNo UI depsnet10.0v0.1.0-alpha.1

The serializable motion-design model: projects, compositions, layers (shapes, text, media, nested compositions, adjustments), animatable channels, keyframes, masks, paths, effects and markers, plus exact rational frame rates. Use it alone to generate or inspect compositions. No dependencies beyond .NET; no UI.

bashInstall
dotnet add package EffectsSpace.Core --prerelease
Depends onno other EffectsSpace packageUsed byAnimationDocumentsControls

Key types

  • MotionProject / Composition / Layer — the document tree; MotionProject.Empty() creates one composition.
  • Channel / Keyframe / Interpolation — animatable values with Linear, Hold and Bezier keys and optional expressions.
  • AnimatedTransform — position, anchor, scale, rotation and opacity channels.
  • EffectCatalog / LayerEffect / EffectKind — effect definitions and parameter channels.
  • LayerChannels — stable property paths ("X", "fx/<id>/Radius") for editors and tooling.
  • FrameRate — Frame, Seconds, Snap, Timecode.

Basic usage

csharpUsage
using EffectsSpace.Core;

var comp = new Composition { Name = "Title card", FrameRate = new(30, 1), Duration = 4, WorkEnd = 4 };
var card = new Layer { Kind = LayerKind.Rectangle, Name = "Card", Width = 640, Height = 360, OutPoint = 4 };
card.Transform.X.Value = 960; card.Transform.Y.Value = 540;
card.Transform.AnchorX.Value = 320; card.Transform.AnchorY.Value = 180;
card.Transform.Opacity.SetKey(0, 0);
card.Transform.Opacity.SetKey(1, 100, Interpolation.Linear);
card.Effects.Add(EffectCatalog.Create(EffectKind.DropShadow));
comp.Layers.Add(card);

var project = new MotionProject { Name = "Demo", ActiveCompositionId = comp.Id, Compositions = [comp] };
foreach (AnimatedProperty property in LayerChannels.Enumerate(card))
    Console.WriteLine($"{property.Path}: {property.Name}");
string tc = comp.FrameRate.Timecode(2.5);   // "00:00:02:15"

EffectsSpace.Animation

EngineNo UI depsnet10.0v0.1.0-alpha.1

Deterministic evaluation of channels: Bezier/linear/hold curves, signed velocity, layer transforms through parent chains, time remapping and a bounded, side-effect-free scalar expression language (not JavaScript). Depends on EffectsSpace.Core; no UI.

bashInstall
dotnet add package EffectsSpace.Animation --prerelease
Depends onCoreUsed byEditingRenderingMedia

Key types

  • CurveEvaluator — Evaluate(channel, time) including expressions; EvaluateKeys, Bezier.
  • CurveVelocity.TryEvaluate — signed derivative for graphs and motion blur.
  • TransformEvaluator — Local, World, ToWorld, ToLocal matrices/points.
  • ScalarExpression.TryEvaluate — bounded expressions with authoring diagnostics.
  • LayerTime.Evaluate — source time from offsets, stretch or time remap.

Basic usage

csharpUsage
using EffectsSpace.Animation;
using EffectsSpace.Core;

var opacity = new Channel(100);
opacity.SetKey(0, 0, Interpolation.Bezier);
opacity.SetKey(1, 100);
double halfway = CurveEvaluator.Evaluate(opacity, 0.5);
bool moving = CurveVelocity.TryEvaluate(opacity, 0.5, out double perSecond);

var rotation = new Channel(0) { Expression = "value + time * 45" };
double angle = CurveEvaluator.Evaluate(rotation, 2);   // 90

if (!ScalarExpression.TryEvaluate("sin(time) * 100", time: 1, value: 0, index: 1, out double result, out string? error))
    Console.WriteLine(error);

EffectsSpace.Documents

I/ONo UI depsnet10.0v0.1.0-alpha.1

Persistence and host contracts: versioned .effects JSON with validation of schema, references, budgets and embedded media, plus UI-free interfaces that platform hosts implement for recovery, file picking/saving and audio output. Depends on EffectsSpace.Core; no UI.

bashInstall
dotnet add package EffectsSpace.Documents --prerelease
Depends onCoreUsed byEditing

Key types

  • ProjectJson — Save, Load (validating), Clone, CloneLayer, shared Options.
  • ProjectValidator.Validate — throws on invalid or over-budget documents.
  • IWorkspaceStorage / ImportedFile — recovery, import and export boundary used by the workbench.
  • IAudioPreview — optional platform audio output and playback clock.

Basic usage

csharpUsage
using EffectsSpace.Core;
using EffectsSpace.Documents;

string json = ProjectJson.Save(MotionProject.Empty());
MotionProject project = ProjectJson.Load(json);   // validates on load

sealed class FolderStorage(string root) : IWorkspaceStorage
{
    string Recovery => Path.Combine(root, "recovery.effects");
    public async Task<string?> ReadRecoveryAsync() => File.Exists(Recovery) ? await File.ReadAllTextAsync(Recovery) : null;
    public Task WriteRecoveryAsync(string json) => File.WriteAllTextAsync(Recovery, json);
    public Task<IReadOnlyList<ImportedFile>> PickFilesAsync(bool projectOnly = false) => Task.FromResult<IReadOnlyList<ImportedFile>>([]);
    public Task SaveFileAsync(string name, string mimeType, byte[] data) => File.WriteAllBytesAsync(Path.Combine(root, name), data);
}

EffectsSpace.Editing

EngineNo UI depsnet10.0v0.1.0-alpha.1

The editing model behind the studio: EditorSession owns selection, current time, auto-key and snapshot-based undo/redo; extension methods implement layer, keyframe, masking, precompose and time-remap commands. Also contains the original ORBITAL SampleProject. Depends on Animation and Documents; no UI.

bashInstall
dotnet add package EffectsSpace.Editing --prerelease

Key types

  • EditorSession — Edit, BeginEdit/PreviewChanged/CommitEdit/CancelEdit, Undo/Redo, SetTime, Select, Changed.
  • EditorCommands — AddLayer, SetProperty, AddKey, AddEffect, AddMask, Precompose, SplitSelection, …
  • KeyframeCommands — multi-key copy/cut/paste, ease, interpolate, nudge.
  • CompositingCommands — EnableTimeRemap, FreezeFrame, ReverseTime, ToggleGuide.
  • SampleProject.Create() — the editable ORBITAL study.

Basic usage

csharpUsage
using EffectsSpace.Core;
using EffectsSpace.Documents;
using EffectsSpace.Editing;

var session = new EditorSession(MotionProject.Empty());
Layer layer = session.AddLayer(LayerKind.Rectangle);   // added and selected
session.AutoKey = true;
session.SetProperty("X", 250);
session.SetTime(1);
session.SetProperty("X", 700);
session.AddEffect(EffectKind.GaussianBlur);

session.BeginEdit("Drag");                             // interactive gesture
layer.Transform.Y.Value += 40; session.PreviewChanged();
session.CommitEdit();                                  // one undo step; CancelEdit on Escape

session.Undo();
string json = ProjectJson.Save(session.Project);

EffectsSpace.Rendering

RenderingNo UI depsnet10.0v0.1.0-alpha.1

Renderer-neutral evaluation: resolves which layers are visible at a time, their world matrices, opacity and source time, with shared parent transforms evaluated once. Also provides hit testing, render budgets and deterministic export frame schedules. Depends on EffectsSpace.Animation; no UI or graphics library.

bashInstall
dotnet add package EffectsSpace.Rendering --prerelease
Depends onAnimationUsed bySkiaTimeline

Key types

  • CompositionFrame — evaluation snapshot for one composition/time; Layers, Find(id).
  • RenderLayer / RenderPlan — layer + World matrix, Opacity, SourceTime, stacking Index.
  • RenderPlanner — Build, HitTest, ExportTimes.
  • RenderBudget — dimension, pixel and nesting limits.

Basic usage

csharpUsage
using EffectsSpace.Core;
using EffectsSpace.Editing;
using EffectsSpace.Rendering;

Composition comp = SampleProject.Create().Compositions[0];

var frame = new CompositionFrame(comp, time: 2.4);
foreach (RenderLayer item in frame.Layers)
    Console.WriteLine($"{item.Layer.Name}: opacity {item.Opacity:0.00}, world {item.World}");

Layer? hit = RenderPlanner.HitTest(comp, 2.4, new Vec2(960, 540));
double[] times = RenderPlanner.ExportTimes(comp).ToArray();   // work-area frame times
RenderBudget.Default.Check(3840, 2160);                         // throws when over budget

EffectsSpace.Media

I/ONo UI depsnet10.0v0.1.0-alpha.1

Portable, bounded media without native codecs: RIFF/WAVE and classic Motion JPEG AVI readers, zero-copy PCM indexing, band-limited sinc resampling, a nested-composition audio mixer and AVI/WAVE writers. Runs identically on desktop and WebAssembly. Depends on EffectsSpace.Animation; no Uno or Skia.

bashInstall
dotnet add package EffectsSpace.Media --prerelease
Depends onAnimationUsed bySkia

Key types

  • AviSource — Read, FrameAt, FrameData (JPEG slices), optional Audio.
  • WaveFile / PcmSource — WAVE parsing and sample access; WaveFile.Encode for quick output.
  • AudioMixer — prepared composition mix; Mix, WaveAsync.
  • WaveRenderer / WavePcmWriter — PCM16/PCM24/Float32 delivery with optional TPDF dither.
  • MjpegAviWriter — forward-only AVI muxing of JPEG frames and PCM16.
  • MediaCatalog — cached metadata/indexes keyed by asset payload.

Basic usage

csharpUsage
using EffectsSpace.Media;

AviSource video = AviSource.Read(aviBytes);                  // MJPEG AVI, optional PCM
ReadOnlyMemory<byte> jpeg = video.FrameData(video.FrameAt(0.5));
PcmSource audio = WaveFile.Read(wavBytes);
float left = audio.Sample(0.25, channel: 0);

var mixer = new AudioMixer(project, composition, quality: AudioResamplingQuality.BandLimited);
var stereo = new float[4096 * 2];
mixer.Mix(startTime: 0, firstFrame: 0, stereo, sampleRate: 48000);
byte[] wave = await WaveRenderer.RenderAsync(mixer, 0, 2, WaveEncoding.Pcm24,
    dither: true, cancellationToken: cancellationToken);

EffectsSpace.Skia

RenderingSkiaSharpnet10.0v0.1.0-alpha.1

The compositor: draws a composition at a time into any SKCanvas with blend modes, mattes, masks, effects, motion blur, nested compositions and decoded video frames, using bounded geometry/filter/image caches. Exporters produce PNG frames, PNG sequences and Motion JPEG AVI with sound. Depends on Rendering, Media and SkiaSharp; no UI framework (headless hosts need Skia native assets and a typeface for text).

bashInstall
dotnet add package EffectsSpace.Skia --prerelease
Depends onRenderingMediaUsed byViewer

Key types

  • SkiaCompositor — Render(canvas, project, composition, time), Typeface, Budget, Metrics; IDisposable.
  • FrameExporter — Png, PngSequenceAsync.
  • AviExporter — ExportAsync to Motion JPEG AVI with mixed PCM audio.
  • EffectPipeline, PathGeometry — Skia filters and paths for layers.
  • MediaStudy.Create — the CLOCKWORK media sample.

Basic usage

csharpUsage
using EffectsSpace.Editing;
using EffectsSpace.Skia;
using SkiaSharp;

var project = SampleProject.Create();
var composition = project.Compositions[0];

using var compositor = new SkiaCompositor { Typeface = SKTypeface.Default };
byte[] png = new FrameExporter(compositor).Png(project, composition, time: 2.4, width: 960);
byte[] avi = await new AviExporter(compositor).ExportAsync(project, composition, width: 960);

using var surface = SKSurface.Create(new SKImageInfo(composition.Width, composition.Height));
compositor.Render(surface.Canvas, project, composition, time: 2.4, includeGuides: false);

EffectsSpace.Controls

ControlsUnonet10.0-browserwasmnet10.0-desktopv0.1.0-alpha.1

Original compact studio chrome for Uno: vector icons, buttons, drop-down choices, tabbed panels, splitters and scrub-to-edit numeric fields with begin/preview/commit/cancel events. Depends on EffectsSpace.Core; requires Uno Platform (Skia renderer).

bashInstall
dotnet add package EffectsSpace.Controls --prerelease
Depends onCoreUsed byViewerTimeline

Key types

  • NumericField — scrub/type numeric input; EditStarted, ValueChanging, EditCompleted, EditCancelled.
  • StudioButton / StudioIcon / IconKind — icon buttons and standalone vector icons.
  • StudioPanel — tabbed panel; AddTab, Select, TabChanged.
  • StudioChoice, StudioSplitter — compact choice list and draggable splitter.
  • Studio — palette constants, Brush, Text, Input, Row helpers.

Basic usage

csharpUsage
using EffectsSpace.Controls;

var opacity = new NumericField("Opacity", 100) { Minimum = 0, Maximum = 100 };
opacity.ValueChanging += value => Preview(value);
opacity.EditCompleted += Commit;

var panel = new StudioPanel();
panel.AddTab("Properties", Studio.Row(Studio.Text("Opacity"), opacity));
panel.AddTab("Actions", new StudioButton("Render", () => Render(), IconKind.Render));
window.Content = panel;   // your Uno Window

EffectsSpace.Viewer

EditorUno + Skianet10.0-browserwasmnet10.0-desktopv0.1.0-alpha.1

The interactive composition viewer: draws through SkiaCompositor into Uno's Skia canvas and supports pan/zoom, selection, direct transform/anchor/rotation manipulation, pen paths, inline text, mask editing and an audio waveform view. Depends on Controls, Editing and Skia; requires Uno Platform (Skia renderer).

bashInstall
dotnet add package EffectsSpace.Viewer --prerelease

Key types

  • CompositionView(EditorSession) — Tool, Fit, SetZoom, ShowGrid, ShowGuides, ShowTransparency, Renderer; IDisposable.
  • ViewerTool — Select, Hand, Zoom, Rotate, Anchor, shapes, Pen, Text.
  • MaskEditView(CompositionView) — transactional mask node/tangent editing overlay.
  • AudioWaveformView — SetSource(PcmSource), Playhead.

Basic usage

csharpUsage
using EffectsSpace.Editing;
using EffectsSpace.Viewer;

var session = new EditorSession(SampleProject.Create());
var viewer = new CompositionView(session) { Tool = ViewerTool.Select, ShowGrid = true };
viewer.Error += message => Console.Error.WriteLine(message);
window.Content = viewer;                     // your Uno Window
viewer.Loaded += (_, _) => viewer.Fit();
window.Closed += (_, _) => viewer.Dispose();

EffectsSpace.Timeline

EditorUno + Skianet10.0-browserwasmnet10.0-desktopv0.1.0-alpha.1

The composition timeline: row-cached layer bars, trimming, keyframe selection/marquee/drag, property filtering and value/velocity graph editing with Bezier handles, all bound to an EditorSession. Depends on Controls, Editing and Rendering; requires Uno Platform (Skia renderer).

bashInstall
dotnet add package EffectsSpace.Timeline --prerelease

Key types

  • TimelineView(EditorSession) — Fit, ZoomBy, GraphMode, GraphKind, ShowProperties, RevealProperty; IDisposable.
  • GraphKind — Value or Velocity.
  • TimelineRow — the laid-out layer/property rows.

Basic usage

csharpUsage
using EffectsSpace.Editing;
using EffectsSpace.Timeline;

var session = new EditorSession(SampleProject.Create());
var timeline = new TimelineView(session);
timeline.Error += message => Console.Error.WriteLine(message);
window.Content = timeline;                   // your Uno Window
timeline.Loaded += (_, _) => timeline.Fit();

timeline.RevealProperty("Opacity");           // expand and scroll to a property
timeline.GraphMode = true;                    // curve editor
timeline.GraphKind = GraphKind.Velocity;

CompositionView and TimelineView can share one session and do not require the full workbench.

EffectsSpace.Workbench

WorkbenchUno + Skianet10.0-browserwasmnet10.0-desktopv0.1.0-alpha.1

The complete studio as one UserControl: project bin, viewer, timeline and graph, inspectors, effect/mask panels, media and audio-delivery settings, transport with audio clock, render queue and open/save/import/export workflows. The host supplies an IWorkspaceStorage (and optionally IAudioPreview). Depends on Viewer and Timeline; requires Uno Platform (Skia renderer).

bashInstall
dotnet add package EffectsSpace.Workbench --prerelease
Depends onViewerTimeline

Key types

  • StudioWorkbench(EditorSession, IWorkspaceStorage) — the studio control; IDisposable.
  • Session, Viewer, Timeline, MaskEditor — access to the embedded parts.
  • SaveAsync, OpenAsync, ImportAsync, ExportFrameAsync, ExportAviAsync, ExportAudioAsync, TogglePlayback, ShowStatus.

Basic usage

csharpUsage
using EffectsSpace.Controls;
using EffectsSpace.Documents;
using EffectsSpace.Editing;
using EffectsSpace.Workbench;

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    var window = new Window { Title = "EffectsSpace" };
    IWorkspaceStorage storage = new MyWorkspaceStorage();   // your platform implementation
    var workbench = new StudioWorkbench(new EditorSession(SampleProject.Create()), storage);
    workbench.Viewer.Renderer.Typeface = Studio.Typeface;
    window.Content = workbench;
    window.Closed += (_, _) => workbench.Dispose();
    window.Activate();
}

src/EffectsSpace.App contains complete desktop (DesktopWorkspaceStorage) and browser (BrowserWorkspaceStorage) implementations.

Architecture

From engine to workbench

Layers build bottom‑up: each one depends only on those beneath it.

L1Model and documents

Uno- and Skia-free compositions, layers and rational time, plus validated versioned documents and storage contracts.

EffectsSpace.CoreEffectsSpace.Documents
L2Animation and editing

Curves, easing and bounded expressions with atomic transactions, selection-aware history and keyframe clipboard.

EffectsSpace.AnimationEffectsSpace.Editing
L3Rendering and media

Renderer-neutral frame plans and portable AVI/WAVE media, composited through SkiaSharp.

EffectsSpace.RenderingEffectsSpace.MediaEffectsSpace.Skia
L4Studio controls

Original Uno controls plus Skia-painted viewer and timeline surfaces drawn into SKCanvasElement.

EffectsSpace.ControlsEffectsSpace.ViewerEffectsSpace.Timeline
L5Workbench

Panels, transport, render queue and document workflows hosted by a thin desktop/WebAssembly app.

EffectsSpace.Workbench
Use it in code

Embed, script, extend

shRun on desktop and publish for the browser
# Fetch checksum-verified open typography and retain its license
python3 scripts/fetch-assets.py

# Native desktop: Windows, macOS or Linux
dotnet run --project src/EffectsSpace.App -f net10.0-desktop \
  -p:EffectsSpaceDesktopOnly=true

# Real Uno WebAssembly application
dotnet workload install wasm-tools
dotnet publish src/EffectsSpace.App -f net10.0-browserwasm -c Release \
  -o artifacts/publish -p:WasmShellWebAppBasePath=/EffectsSpace/
python3 scripts/collect-site.py artifacts/publish artifacts/site
python3 scripts/serve-site.py --directory artifacts/site --port 4173
shRun the engine and media test suites
# Engine and media regression executables
dotnet run --project tests/EffectsSpace.Tests -c Release
dotnet run --project tests/EffectsSpace.Animation.Tests -c Release
dotnet run --project tests/EffectsSpace.Skia.Tests -c Release
dotnet run --project tests/EffectsSpace.Compositing.Tests -c Release
dotnet run --project tests/EffectsSpace.Media.Tests -c Release
dotnet run --project tests/EffectsSpace.Media.Skia.Tests -c Release
dotnet run --project tests/EffectsSpace.Audio.Tests -c Release

# Independent media validation: requires test-only FFmpeg/ffprobe
python3 scripts/verify-media.py
python3 scripts/verify-audio.py

# Real keyboard, pointer, file-picker and download interactions
npm ci --ignore-scripts
npx playwright install chromium
npm run test:browser

File formats

.effects (versioned JSON with embedded media)read/write
Motion JPEG AVI (optional PCM audio)import
WAVE (mono/stereo integer and float PCM)import
PNG / JPEG / WebPimport
PNG frame and ZIP PNG sequenceexport
Motion JPEG AVI with PCM16/48 kHz audioexport
WAVE (PCM16 / PCM24 / Float32)export

Keyboard essentials

Save / Open / ImportCtrl S / Ctrl O / Ctrl I
Undo / RedoCtrl Z / Ctrl Shift Z
Duplicate / Split / Pre-composeCtrl D / Ctrl Shift D / Ctrl Shift C
Key copy / cut / pasteCtrl C / Ctrl X / Ctrl V
Play / previous frame / next frameSpace / Page Up / Page Down
Work area start / endB / N
Transform / effect propertiesP, S, R, T, A / E
Animated properties / Easy EaseU / F9
Graph / value–velocity switchShift F3 / Shift F4
Composite / Render stats / MediaShift F5 / Shift F6 / Shift F7
New adjustment / Time remap / FreezeCtrl Alt Y / Ctrl Alt T / Ctrl Alt F
CLOCKWORK sample / AVI / WAVE exportCtrl Alt L / Ctrl Alt M / Ctrl Alt W
Build & CI

Continuously verified

Each push runs through GitHub Actions. The public browser build is deployed only from successful pipelines.

Toolchain

.NET SDK10.0.401
Uno SDK6.7.30
Target frameworksnet10.0 · net10.0-browserwasm · net10.0-desktop

Third‑party NuGet packages

SkiaSharp3.119.2
bashClone & run the browser build locally
git clone https://github.com/wieslawsoltes/EffectsSpace.git
cd EffectsSpace
dotnet workload install wasm-tools
dotnet run --project src/EffectsSpace.App -f net10.0-browserwasm
Honest boundaries

What it doesn’t claim

The project documents its limits as carefully as its features.

  • Development alpha of 2D editing, not complete Adobe After Effects parity
  • No MP4/H.264/WebM, 3D, tracking, Adobe formats/plugins or dedicated WebGPU renderer
  • Native timeline preview is silent; browser audible preview is limited to 60 seconds
  • 8-bit sRGB workflow: no HDR, linear-light or color management; AVI export has no alpha
  • Embedded media limited to 32 MiB per asset and 64 MiB total; exports capped at 3600 frames