@storybynumbers_/remotion-glitch-effect 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -28
- package/README.npm.md +13 -3
- package/dist/DigitalGlitchRGB.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,20 +8,59 @@ Digital glitch effect with RGB channel splitting for Remotion.
|
|
|
8
8
|
npm install @storybynumbers_/remotion-glitch-effect
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Minimal usage
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
14
|
import { DigitalGlitchRGB } from '@storybynumbers_/remotion-glitch-effect';
|
|
15
15
|
|
|
16
|
-
<DigitalGlitchRGB
|
|
17
|
-
splitAmount={5}
|
|
18
|
-
blurAmount={0.8}
|
|
19
|
-
burstSpacing={28}
|
|
20
|
-
>
|
|
16
|
+
<DigitalGlitchRGB>
|
|
21
17
|
<YourContent />
|
|
22
18
|
</DigitalGlitchRGB>
|
|
23
19
|
```
|
|
24
20
|
|
|
21
|
+
## How it’s made
|
|
22
|
+
|
|
23
|
+
This effect is intentionally “no fancy pipeline”: it’s built from SVG filters, a burst scheduler, and deterministic per-frame variation.
|
|
24
|
+
|
|
25
|
+
### 1) Bursts instead of always-on noise
|
|
26
|
+
|
|
27
|
+
Rather than wiggling every frame, the component creates short glitch windows (“bursts”) separated by calm periods:
|
|
28
|
+
|
|
29
|
+
- `generateBursts(totalFrames, burstSpacing, burstDuration, seed)` produces a list of non-overlapping bursts.
|
|
30
|
+
- Each burst has a `startFrame`, `duration`, `peakIntensity`, and its own derived `seed`.
|
|
31
|
+
- Bursts are created with Remotion’s `random()` using string keys (for deterministic randomness).
|
|
32
|
+
|
|
33
|
+
During playback, `getGlitchIntensity(frame, bursts)` returns:
|
|
34
|
+
|
|
35
|
+
- `0` outside any burst (stable).
|
|
36
|
+
- `0..1` inside a burst, using a simple envelope (fast attack, slight decay).
|
|
37
|
+
|
|
38
|
+
### 2) Per-frame variation, but still reproducible
|
|
39
|
+
|
|
40
|
+
Inside a burst, each frame uses a derived seed (`burst.seed + frame`) to vary offsets and jitter. With the same input `seed`, renders remain reproducible across machines and over time.
|
|
41
|
+
|
|
42
|
+
### 3) RGB split using SVG filters
|
|
43
|
+
|
|
44
|
+
When glitching, we render three stacked layers of the same children:
|
|
45
|
+
|
|
46
|
+
- Red layer: extract red via `feColorMatrix`, then offset with `feOffset`.
|
|
47
|
+
- Green layer: extract green and keep centered (acts as a stable reference).
|
|
48
|
+
- Blue layer: extract blue and offset (in the opposite direction).
|
|
49
|
+
|
|
50
|
+
Blur is applied only during bursts (`feGaussianBlur`) to soften harsh edges and make the split read more like “signal processing” than three crisp copies.
|
|
51
|
+
|
|
52
|
+
Finally, the layers are composited with `mixBlendMode: 'screen'` so channel separation stays bright and punchy.
|
|
53
|
+
|
|
54
|
+
### 4) Performance: no work when stable
|
|
55
|
+
|
|
56
|
+
Outside bursts, the component returns `<AbsoluteFill>{children}</AbsoluteFill>` and applies no SVG filter work at all.
|
|
57
|
+
|
|
58
|
+
### 5) Avoiding filter ID collisions
|
|
59
|
+
|
|
60
|
+
Each instance uses `useId()` to build a unique filter ID, so multiple glitches can exist on the same page without clobbering each other’s SVG definitions.
|
|
61
|
+
|
|
62
|
+
Implementation lives in `lib/DigitalGlitchRGB.tsx`.
|
|
63
|
+
|
|
25
64
|
## Props
|
|
26
65
|
|
|
27
66
|
| Prop | Type | Default | Description |
|
|
@@ -33,29 +72,10 @@ import { DigitalGlitchRGB } from '@storybynumbers_/remotion-glitch-effect';
|
|
|
33
72
|
| `burstDuration` | `[number, number]` | `[2, 5]` | Min/max burst length in frames |
|
|
34
73
|
| `seed` | `number` | `42` | Deterministic randomization seed |
|
|
35
74
|
|
|
36
|
-
##
|
|
37
|
-
|
|
38
|
-
**Subtle phone interference**
|
|
39
|
-
```tsx
|
|
40
|
-
<DigitalGlitchRGB splitAmount={3} blurAmount={0.5} burstSpacing={35}>
|
|
41
|
-
{children}
|
|
42
|
-
</DigitalGlitchRGB>
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
**Aggressive glitch**
|
|
46
|
-
```tsx
|
|
47
|
-
<DigitalGlitchRGB splitAmount={7} jitterAmount={2.5} burstSpacing={18}>
|
|
48
|
-
{children}
|
|
49
|
-
</DigitalGlitchRGB>
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## How It Works
|
|
75
|
+
## Notes
|
|
53
76
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
- Per-frame variation within bursts for organic feel
|
|
57
|
-
- Zero overhead when stable (no filters applied)
|
|
58
|
-
- Fully deterministic (reproducible renders)
|
|
77
|
+
- This package targets “digital interference”: small, sparse bursts tend to look better than constant distortion.
|
|
78
|
+
- If you want a consistent look across multiple shots, keep `seed` fixed per shot (or derive it from a stable ID).
|
|
59
79
|
|
|
60
80
|
## Requirements
|
|
61
81
|
|
package/README.npm.md
CHANGED
|
@@ -8,17 +8,27 @@ Digital glitch effect with RGB channel splitting for Remotion.
|
|
|
8
8
|
npm install @storybynumbers_/remotion-glitch-effect
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Minimal use
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
14
|
import { DigitalGlitchRGB } from '@storybynumbers_/remotion-glitch-effect';
|
|
15
15
|
|
|
16
|
-
<DigitalGlitchRGB
|
|
16
|
+
<DigitalGlitchRGB>
|
|
17
17
|
<YourContent />
|
|
18
18
|
</DigitalGlitchRGB>
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## How it’s made (overview)
|
|
22
|
+
|
|
23
|
+
- Schedules sparse “bursts” up front using Remotion’s deterministic `random()` and a `seed`.
|
|
24
|
+
- During a burst, computes a quick intensity envelope and varies offsets per-frame (still deterministic).
|
|
25
|
+
- Renders three layers (R/G/B) and uses SVG filters: `feColorMatrix` to isolate channels, `feOffset` for separation, optional `feGaussianBlur` for softness.
|
|
26
|
+
- Composites layers with `mixBlendMode: 'screen'`.
|
|
27
|
+
- Outside bursts, renders children directly (no filters applied).
|
|
28
|
+
|
|
29
|
+
Implementation: `lib/DigitalGlitchRGB.tsx`.
|
|
30
|
+
|
|
31
|
+
## Props
|
|
22
32
|
|
|
23
33
|
- `splitAmount` (number, default 4) RGB offset in pixels
|
|
24
34
|
- `blurAmount` (number, default 0.8) Blur radius
|
package/dist/DigitalGlitchRGB.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useId } from 'react';
|
|
2
|
-
import { AbsoluteFill, random, useCurrentFrame } from 'remotion';
|
|
2
|
+
import { AbsoluteFill, random, useCurrentFrame, useVideoConfig } from 'remotion';
|
|
3
3
|
/**
|
|
4
4
|
* Attempt to generate a burst at each spacing interval.
|
|
5
5
|
* Returns array of non-overlapping bursts.
|
|
@@ -52,11 +52,11 @@ function getGlitchIntensity(frame, bursts) {
|
|
|
52
52
|
}
|
|
53
53
|
export const DigitalGlitchRGB = ({ children, splitAmount = 4, blurAmount = 0.8, jitterAmount = 1.5, burstSpacing = 25, burstDuration = [2, 5], seed = 42, }) => {
|
|
54
54
|
const frame = useCurrentFrame();
|
|
55
|
+
const { durationInFrames } = useVideoConfig();
|
|
55
56
|
const reactId = useId();
|
|
56
57
|
const filterId = useMemo(() => `glitch-rgb-${reactId.replace(/:/g, '')}`, [reactId]);
|
|
57
58
|
// Pre-generate burst schedule (memoized, doesn't change during playback)
|
|
58
|
-
|
|
59
|
-
const bursts = useMemo(() => generateBursts(600, burstSpacing, burstDuration, seed), [burstSpacing, burstDuration, seed]);
|
|
59
|
+
const bursts = useMemo(() => generateBursts(durationInFrames, burstSpacing, burstDuration, seed), [durationInFrames, burstSpacing, burstDuration, seed]);
|
|
60
60
|
// Get current glitch state
|
|
61
61
|
const { intensity, burst } = getGlitchIntensity(frame, bursts);
|
|
62
62
|
const isGlitching = intensity > 0 && burst !== null;
|