fadeInDuration = 1.5
delay = (index - 1) * 0.2
t = time - (thisLayer.startTime + delay)
progress = clamp(t / fadeInDuration, 0, 1)
easeT = ease(progress, 0, 1)
// Opacity
opacity = easeT
// Scale
startScale = 85
endScale = 100
scale = linear(easeT, startScale, endScale)
// Position
startY = 0.3 + index * 0.05
endY = 0.0
y = linear(easeT, startY, endY)
z = -0.1 * index // Depth
// Subtle drift
driftT = max(0, t - fadeInDuration)
driftAmt = clamp(driftT / 8.0, 0, 1)
y += driftAmt * -0.02
x = driftAmt * 0.015
[scale, scale] // for Scale
[opacity] // for Opacity
[x, y, z] // for Position
💡 Bonus Tips • Use Gaussian blur at 100% → 0% on entrance for “focus pull” feel • Try letter tracking keyframes in sync with position ease (subtle spacing that tightens) • Don’t animate all text at once — use layer index to stagger
In NodeVideo, the feature we're using is typically called Expressions or the Expression Editor—this lets you write MiniScript code to control almost any property (position, opacity, scale, blur, etc.) dynamically, like in After Effects but with their own flavor of scripting. You can use expressions to animate text overlays (or anything else) without manual keyframes.
⸻
Here’s how you can recreate that smooth, cinematic overlay look using NodeVideo’s expression system:
⸻
• Layer 1: Main text (white, bold, centered)
• Layer 2: Duplicate of main text, placed under main text
• Apply a Gaussian Blur or Glow (adjust for softness)
• Lower opacity if needed
Group them if you want to animate together.
⸻
// Fade in over 0.5s
fadeDuration = 0.5
t = clamp((time - thisLayer.startTime)/fadeDuration, 0, 1)
ease(t, 0, 1)
• This fades the text from 0 to 100% opacity over half a second.
// Scale from 110% to 100% for a gentle pop
scaleDuration = 0.7
t = clamp((time - thisLayer.startTime)/scaleDuration, 0, 1)
s = ease(t, 1.1, 1.0)
[s, s]
• Gives a subtle zoom-in as it appears, matching modern YT shorts style.
• Copy the same expression as main text opacity to sync fade-in.
• You can add a longer duration for a soft linger:
fadeDuration = 0.7
t = clamp((time - thisLayer.startTime)/fadeDuration, 0, 1)
ease(t, 0, 0.6) // Max out at 60% opacity for subtlety
⸻
fadeInDuration = 0.5
fadeOutDuration = 0.5
startFadeOut = thisLayer.outPoint - fadeOutDuration
if (time < thisLayer.startTime) then
0
else if (time < thisLayer.startTime + fadeInDuration) then
t = (time - thisLayer.startTime) / fadeInDuration
ease(t, 0, 1)
else if (time > startFadeOut) then
t = (time - startFadeOut) / fadeOutDuration
ease(1-t, 0, 1)
else
1
end if
• Fades in, stays, then fades out at the end.
⸻
If your text should match the camera pullback, use the same t or easeT as your FOV expression, so it animates in sync with camera movement.
⸻
• Expressions in NodeVideo = mini scripts for animation control (powerful, reusable, no keyframes).
• Animate opacity and scale for elegant, modern text.
• Use duplicate blurred text as a glow, also animated with expressions.
• Sync with your FOV or other video motion for pro results.
⸻
Want a full template example with all code blocks? Or do you want suggestions for even more stylized cinematic text reveals (like tracking, letter spacing, etc.)?