TimeSlice Dual
Two clips in one frame of venetian blinds
- images_a
- images_b
- mask
- images
- mask
- num_frames
- slice_edges
The pitch: everything TimeSlice Effect does, but the slices pull from two different clips. Clip A fills some bands, clip B fills the rest, and the two interleave like venetian blinds - except each strip is also sampled from a different moment in time.
Why you'd reach for it: this is the transition and mashup node. A/B dissolves in ComfyUI are usually opacity ramps, and the seams show. Dual lets you art-direct a handover instead: the whole frame belongs to A, then bands flip to B one by one, each carrying its own time smear. That covers glitch transitions, split-reality looks (two takes occupying one frame), and side-by-side comparisons without a visible seam.
How it works. It runs the same shared slicing engine as the rest of the pack, then assigns each slice a source with pattern. offset_a and offset_b are independent cascade steps for A's and B's slices, so the two clips don't have to smear at the same speed. Handy detail: input B is automatically resized to match A if their dimensions differ, so you don't have to pre-align clips yourself.
The inputs that matter:
- images_a / images_b - the two clips. They'll be cut to the shorter one's length, so match your frame counts.
- pattern - how slices are assigned to sources:
alternate(ABAB),pairs(AABB repeating),aba,aabb,abba. This sets the texture of the interleave. - mix - the balance.
0.5keeps the pattern as designed; push toward0or1and slices get reassigned (seeded) so one source dominates. It's your crossfade, minus the mush. - offset_a / offset_b - per-source time smear, so one clip can streak while the other stays crisp.
- num_slices, angle, spacing, direction, loop_mode, blend_width, seed - pack-standard shared controls.
- mask (optional) - restrict the whole two-source mess to the white area; outside stays original A.
The optional block - cascade_curve, slice_jitter, and the animate controls (num_slices_end, offset_a_end, offset_b_end, angle_end, temporal_curve, frame_count) - is where Dual earns its keep. animate interpolates the offsets from start to end over the clip, so the balance between A and B shifts mid-take instead of sitting frozen.
Outputs. The same four sockets as the whole pack: images, mask, num_frames, slice_edges. Output length is the shorter of the two inputs - shorter still under trim, so read num_frames rather than assuming.
Install
Pack-wide, nothing special: ComfyUI Manager → search "TimeSlice Nodes" → Install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/systms-ai/TimeSlice-Nodes.git
Restart, and it shows under Systms → effects. Only dependency is numpy; no model files to download.
Gotchas
Both clips should be the same frame rate and roughly the same length - the node cuts to min(B_a, B_b) and won't warn you about the mismatch. Pre-trim wildly different clips before you feed them in. And the usual pack rule: single images in, nothing meaningful out - these are clip nodes. Also worth remembering: two hi-res clips in, two clips in memory, so RAM scales accordingly.
Recipe to start: alternate pattern, mix 0.5, offset_a 1, offset_b 6, num_slices 40 - a subtle two-speed weave. For a transition, animate offset_a from 1→6 and offset_b from 6→1 over the clip, and the two takes trade places as they smear.
Inputs (23)
| Name | Type | Default | Description |
|---|---|---|---|
| images_a | IMAGE | First source clip (A). | |
| images_b | IMAGE | Second source clip (B). Resized to match A if their dimensions differ. | |
| num_slices | INT | 201–2000 | Number of slices to divide the frame into |
| offset_a | INT | 1-120–120 | Frame offset step for A-source slices |
| offset_b | INT | 1-120–120 | Frame offset step for B-source slices |
| angle | FLOAT | 0-180–180 | Slice angle in degrees. 0 = vertical, 90 = horizontal. |
| spacing | COMBO | How slice widths are distributed across the frame: even (linear), eased toward one side, or random. | |
| direction | COMBO | Which slices carry the most time offset: building from one edge (forward/reverse), from the centre, or from both edges. | |
| pattern | COMBO | How slices are assigned to the A and B clips across the frame. | |
| loop_mode | COMBO | How out-of-range frame indices are handled: wrap around (loop), bounce back (ping_pong), or shorten the clip (trim). | |
| blend_width | INT | 00–400 | Soft blend width (px) across boundaries. 0 = hard edges. |
| mix | FLOAT | 0.500–1 | Balance between A and B. 0.5 = equal. |
| seed | INT | 00–4294967295 | Seed for 'random' spacing, slice jitter and mix balancing |
| cascade_curveopt | COMBO | How the per-slice offset grows across slices. | |
| slice_jitteropt | INT | 00–60 | Random +/- frames added per slice (seeded). Adds glitchy irregularity. |
| animateopt | BOOLEAN | false | Animate slices/offsets/angle from start -> end over the clip. |
| num_slices_endopt | INT | 601–2000 | Target slice count reached at the end of the animation. |
| offset_a_endopt | INT | 6-120–120 | Target A-source offset at the end of the animation. |
| offset_b_endopt | INT | 6-120–120 | Target B-source offset at the end of the animation. |
| angle_endopt | FLOAT | 0-180–180 | Target slice angle (degrees) at the end of the animation. |
| temporal_curveopt | COMBO | Easing applied to the start -> end animation over time. | |
| frame_countopt | INT | 00–100000 | Frames over which the animation completes. 0 = use clip length. |
| maskopt | MASK | Optional mask. Slicing is applied only inside the white area; outside keeps the original A frame. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| mask | MASK | — |
| num_frames | INT | — |
| slice_edges | MASK | — |