Lens Zoom

A hard cut disguised as a lens punch-in — barrel distortion, zoom blur, chromatic split and camera shake around the splice

Installation
$ pnpm dlx shadcn@latest add @remocn/lens-zoom

Usage

lensZoom() is a Remotion transition presentation. The transition is a hard cut, not a dissolve: the outgoing half owns progress 0–0.5 and the incoming half owns 0.5–1, so the splice lands exactly halfway through the transition. Use LENS_ZOOM_DURATION_IN_FRAMES (28) with linearTiming for the tutorial's pacing — two equal 14-frame ramps either side of the cut.

tsx
import { TransitionSeries, linearTiming } from "@remotion/transitions";
import {
  lensZoom,
  LENS_ZOOM_DURATION_IN_FRAMES,
} from "@/components/remocn/lens-zoom";
 
export const MyVideo = () => (
  <TransitionSeries>
    <TransitionSeries.Sequence durationInFrames={70}>
      <SceneA />
    </TransitionSeries.Sequence>
    <TransitionSeries.Transition
      timing={linearTiming({ durationInFrames: LENS_ZOOM_DURATION_IN_FRAMES })}
      presentation={lensZoom()}
    />
    <TransitionSeries.Sequence durationInFrames={70}>
      <SceneB />
    </TransitionSeries.Sequence>
  </TransitionSeries>
);

Performance scales with blurSamples × (lensSteps + 1) painted copies of each scene per frame, tripled when the three channel scales differ. Setting redScale, greenScale and blueScale equal skips the chromatic split entirely — the single biggest thing to turn off while dialling the transition in.

Props

lensZoom(props) accepts:

PropTypeDefault
inScaleFrom / inScaleTo
number100 / 150

Scale ramp of the outgoing half, in percent

inFovFrom / inFovTo
number0 / 160

Lens distortion FOV ramp of the outgoing half, in degrees

inBlurFrom / inBlurTo
number0 / 60

Zoom blur amount ramp of the outgoing half

inRotationFrom / inRotationTo
number0 / -15

Rotation ramp of the outgoing half, in degrees

outScaleFrom / outScaleTo
number135 / 100

Scale ramp of the incoming half — starts below the outgoing peak so the energy steps down at the cut

outFovFrom / outFovTo
number135 / 0

Lens distortion FOV ramp of the incoming half

outBlurFrom / outBlurTo
number45 / 0

Zoom blur amount ramp of the incoming half

outRotationFrom / outRotationTo
number345 / 360

Rotation ramp of the incoming half — unwinds the outgoing twist

anticipateScale
number100

Scale the outgoing scene squeezes down to before the punch — the wind-up before the jump. The lens, blur and rotation ramps hold until the squeeze ends. Disabled by default (scaling the full frame below 100 reveals the backdrop behind it) — prefer squeezing the subject inside the scene; set below `inScaleFrom` to enable the frame squeeze

anticipatePortion
number0.35

Portion of the outgoing half spent on the squeeze. 0 disables it

lensSteps
number9

Concentric rings approximating the barrel warp. Nearly free — the rings are disjoint

blurSamples
number7

Scaled copies approximating the zoom blur. The expensive knob — higher is smoother

blurScaleGain
number1

Scale span one unit of blur amount buys

blurFade
number1.5

Higher keeps the sharp copy dominant over the smear

shakeAmount
number50

Peak of the shake envelope around the cut. 0 disables the shake

shakeFrequency
number1.4

Shake noise frequency

shakeCyclesPerUnit
number8

Noise cycles per second one unit of frequency is worth

shakeTranslatePx
number73

Peak shake translation in pixels

shakeRotateDeg
number1.1

Peak shake rotation in degrees

redScale / greenScale / blueScale
number1.01 / 1.0 / 0.99

Per-channel scales for the chromatic aberration. Set all three equal to skip the split

letterboxAspect
number0

Cinematic bars aspect ratio (e.g. 2.39). 0 disables them

width / height
numbercomposition size

Stage size in pixels

distortionCenterX / distortionCenterY
numberstage center

Center of the lens distortion, blur and shake

  • inScaleFrom / inScaleTonumber

    Scale ramp of the outgoing half, in percent

    Default100 / 150

  • inFovFrom / inFovTonumber

    Lens distortion FOV ramp of the outgoing half, in degrees

    Default0 / 160

  • inBlurFrom / inBlurTonumber

    Zoom blur amount ramp of the outgoing half

    Default0 / 60

  • inRotationFrom / inRotationTonumber

    Rotation ramp of the outgoing half, in degrees

    Default0 / -15

  • outScaleFrom / outScaleTonumber

    Scale ramp of the incoming half — starts below the outgoing peak so the energy steps down at the cut

    Default135 / 100

  • outFovFrom / outFovTonumber

    Lens distortion FOV ramp of the incoming half

    Default135 / 0

  • outBlurFrom / outBlurTonumber

    Zoom blur amount ramp of the incoming half

    Default45 / 0

  • outRotationFrom / outRotationTonumber

    Rotation ramp of the incoming half — unwinds the outgoing twist

    Default345 / 360

  • anticipateScalenumber

    Scale the outgoing scene squeezes down to before the punch — the wind-up before the jump. The lens, blur and rotation ramps hold until the squeeze ends. Disabled by default (scaling the full frame below 100 reveals the backdrop behind it) — prefer squeezing the subject inside the scene; set below `inScaleFrom` to enable the frame squeeze

    Default100

  • anticipatePortionnumber

    Portion of the outgoing half spent on the squeeze. 0 disables it

    Default0.35

  • lensStepsnumber

    Concentric rings approximating the barrel warp. Nearly free — the rings are disjoint

    Default9

  • blurSamplesnumber

    Scaled copies approximating the zoom blur. The expensive knob — higher is smoother

    Default7

  • blurScaleGainnumber

    Scale span one unit of blur amount buys

    Default1

  • blurFadenumber

    Higher keeps the sharp copy dominant over the smear

    Default1.5

  • shakeAmountnumber

    Peak of the shake envelope around the cut. 0 disables the shake

    Default50

  • shakeFrequencynumber

    Shake noise frequency

    Default1.4

  • shakeCyclesPerUnitnumber

    Noise cycles per second one unit of frequency is worth

    Default8

  • shakeTranslatePxnumber

    Peak shake translation in pixels

    Default73

  • shakeRotateDegnumber

    Peak shake rotation in degrees

    Default1.1

  • redScale / greenScale / blueScalenumber

    Per-channel scales for the chromatic aberration. Set all three equal to skip the split

    Default1.01 / 1.0 / 0.99

  • letterboxAspectnumber

    Cinematic bars aspect ratio (e.g. 2.39). 0 disables them

    Default0

  • width / heightnumber

    Stage size in pixels

    Defaultcomposition size

  • distortionCenterX / distortionCenterYnumber

    Center of the lens distortion, blur and shake

    Defaultstage center

Inspired by After Effects: Lens Zoom Transition Tutorial by Creative Dojo.