> ## Documentation Index
> Fetch the complete documentation index at: https://hyperframes.heygen.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cut the Curve

> A velocity-matched directional hard cut: the outgoing subject accelerates with power4.in, swaps at peak velocity, and the incoming subject continues in the same direction with power4.out.

export const InstallCommand = ({command}) => {
  const [copied, setCopied] = React.useState(false);
  const copy = async () => {
    try {
      if (navigator.clipboard && window.isSecureContext) {
        await navigator.clipboard.writeText(command);
      } else {
        const previous = document.activeElement;
        const scratch = document.createElement("textarea");
        scratch.value = command;
        scratch.setAttribute("readonly", "");
        scratch.style.position = "fixed";
        scratch.style.opacity = "0";
        document.body.appendChild(scratch);
        scratch.select();
        document.execCommand("copy");
        document.body.removeChild(scratch);
        previous?.focus?.();
      }
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch {}
  };
  return <div className="hf-install-command not-prose my-4 flex items-stretch overflow-hidden rounded-xl border border-zinc-200 bg-zinc-50 dark:border-zinc-800 dark:bg-zinc-900">
      <code className="flex-1 overflow-x-auto whitespace-nowrap border-r border-zinc-200 px-4 py-3 font-mono text-sm text-zinc-800 dark:border-zinc-800 dark:text-zinc-100">
        {command}
      </code>
      <button type="button" onClick={copy} data-copied={copied ? "true" : "false"} aria-label={`Copy ${command} to the clipboard`} className="hf-install-copy">
        <svg className="hf-install-copy-clipboard" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <path d="M14.25 5.25H7.25C6.14543 5.25 5.25 6.14543 5.25 7.25V14.25C5.25 15.3546 6.14543 16.25 7.25 16.25H14.25C15.3546 16.25 16.25 15.3546 16.25 14.25V7.25C16.25 6.14543 15.3546 5.25 14.25 5.25Z" />
          <path d="M2.80103 11.998L1.77203 5.07397C1.61003 3.98097 2.36403 2.96397 3.45603 2.80197L10.38 1.77297C11.313 1.63397 12.19 2.16297 12.528 3.00097" />
        </svg>
        <svg className="hf-install-copy-check" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <path d="M2.75 9.5L6.5 13.25L15.25 4.5" />
        </svg>
      </button>
      <span className="hf-install-copy-status" role="status" aria-live="polite">
        {copied ? "Copied" : ""}
      </span>
    </div>;
};

<iframe className="w-full aspect-video rounded-xl border-0 bg-zinc-100 dark:bg-zinc-800" title="cut-the-curve preview" loading="lazy" srcDoc={`<!doctype html><html><head><meta charset="utf-8"><style>html,body{margin:0;height:100%;overflow:hidden;background:transparent}hyperframes-player{display:block;width:100%;height:100%}</style><script src="https://cdn.jsdelivr.net/npm/@hyperframes/player@0.7/dist/hyperframes-player.global.js"><\/script></head><body><script>fetch("/public/catalog/components/cut-the-curve.json").then(function(r){return r.json()}).then(function(d){var p=document.createElement("hyperframes-player");p.setAttribute("srcdoc",d.html);p.setAttribute("controls","");p.setAttribute("autoplay","");p.setAttribute("loop","");p.setAttribute("muted","");p.setAttribute("poster","https://static.heygen.ai/hyperframes-oss/docs/images/catalog/components/cut-the-curve.png");document.body.appendChild(p)});<\/script></body></html>`} />

## Install

<InstallCommand command="npx hyperframes add cut-the-curve" />

That writes one file: `compositions/components/cut-the-curve.html`.

## Paste it into your composition

Open `compositions/components/cut-the-curve.html` and copy what is inside into your own composition.

A component has no size or duration of its own. It takes both from the composition
you paste it into.

## Variables

Every one of these has a default, so the piece works untouched. Set the ones you
want to change on the element:

| Variable      | Default  | Accepts                       | What it does                                                                             |
| ------------- | -------- | ----------------------------- | ---------------------------------------------------------------------------------------- |
| `subject`     | `cursor` | `cursor`, `card`, `scene`     | Visual payload used on both sides of the cut.                                            |
| `direction`   | `left`   | `left`, `right`, `up`, `down` | Shared screen direction for outgoing and incoming travel.                                |
| `cutFraction` | `0.33`   | 0 to 1, step 0.01             | Normalized point where the hard cut swaps subjects.                                      |
| `blurPx`      | `12`     | 0px to 40px, step 1px         | Blur in pixels shared by both subjects at the cut seam.                                  |
| `exit`        | `none`   | `none`, `fade`, `up`          | Optional departure of the incoming subject. Default none: it rests until the frame cuts. |

Set them with `data-variable-values` on the element that mounts it. These are the
defaults, so this behaves exactly like the preview above until you change one:

```html wrap theme={null}
<div
  data-composition-id="cut-the-curve"
  data-composition-src="compositions/components/cut-the-curve.html"
  data-variable-values='{"subject":"cursor","direction":"left","cutFraction":0.33,"blurPx":12,"exit":"none"}'
></div>
```

## Source

<Accordion title={`cut-the-curve.html`}>
  ```html theme={null}
  <!doctype html>
  <!--
    cut-the-curve -- HyperFrames video primitive (transitions / bridge)

    Concept: a velocity-matched directional hard cut. The outgoing subject
    accelerates along one straight screen vector with power4.in. At peak
    velocity, the timeline swaps identities. The incoming subject starts on
    the far side of the same vector and decelerates to rest with power4.out.
    Matched blur and opacity at the cut conceal the seam.

    Compiled from the launch write-up for this piece.
    The source identifies the production signature as a single power4 whip,
    with an approximately 1:2 outgoing-to-incoming distance and duration split.

    Use when: bridging attention and momentum between shots, UI states, cards,
    cursor beats, or scene blocks without requiring object identity to persist.

    Variables (declared in data-composition-variables below):
      - subject ("cursor" | "card" | "scene", default "cursor") selects the
        simple visual payload used for both sides of the cut.
      - direction ("left" | "right" | "up" | "down", default "left") owns
        both the motion axis and the shared screen direction.
      - cutFraction (number, 0-1, default 0.33) sets the hard-cut point. The
        incoming distance is derived from this fraction so seam velocity stays
        matched. At 0 or 1, the corresponding zero-duration half collapses.
      - blurPx (number, default 12) sets blur at the cut seam.
      - exit ("none" | "fade" | "up", default "none") optionally departs the
        incoming subject at the end. Enabling it reserves a short tail window
        (min(0.35s, 25% of D)) after the incoming subject lands.

    Envelope (transition profile, no elastic HOLD; T = D minus the exit tail,
    which is 0 when exit is none):
      OUT = T * cutFraction, power4.in
      IN  = T * (1 - cutFraction), power4.out
      The default 0.33 split is approximately 1:2 in time. Incoming distance is
      derived from OUT distance and the duration ratio, preserving the same
      approximately 1:2 spatial split and matching velocity at the cut.

    Sync point: CUT_AT = T * cutFraction, the fixed boundary between OUT and
    IN. It never lands in a HOLD because this profile has no HOLD phase.

    Sound cue: a short whip cut fires at CUT_AT. The primitive never plays
    audio. It dispatches an `hf:sfx` CustomEvent with
    { id: "whip-cut", t: CUT_AT } for the scene mix stage to route.

    EDIT ZONE: change only the subject geometry custom properties in the style
    block when adapting the payload drawings. The vector ratios and the paired
    power4 eases are the mechanic and must remain together.

    INVARIANTS: outgoing and incoming always share one vector; the identity swap
    happens only at CUT_AT; their blur and opacity values match at that seam;
    exactly one paused timeline registers under the literal id "cut-the-curve".

    RETIME RANGE: 0.3s to 3s. Retiming changes D only. Never timeScale the GSAP
    timeline and never split the two halves into independently tuned velocities.

    Mount contract: this is a template-wrapped sub-composition. Everything the
    mount needs, including styles, markup, GSAP, and timeline registration,
    lives inside <template>. #root fills the host box with position:absolute,
    inset:0, and container-type:size. It has no data-width or data-height.
  -->
  <html
    lang="en"
    data-composition-variables='[
      { "id": "subject", "type": "enum", "role": "content", "label": "Subject", "description": "Visual payload used on both sides of the cut.", "default": "cursor", "options": [{ "value": "cursor", "label": "Cursor" }, { "value": "card", "label": "Card" }, { "value": "scene", "label": "Scene" }] },
      { "id": "direction", "type": "enum", "role": "motion", "label": "Direction", "description": "Shared screen direction for outgoing and incoming travel.", "default": "left", "options": [{ "value": "left", "label": "Left" }, { "value": "right", "label": "Right" }, { "value": "up", "label": "Up" }, { "value": "down", "label": "Down" }] },
      { "id": "cutFraction", "type": "number", "role": "timing", "label": "Cut fraction", "description": "Normalized point where the hard cut swaps subjects.", "default": 0.33, "min": 0, "max": 1, "step": 0.01 },
      { "id": "blurPx", "type": "number", "role": "style", "label": "Cut blur", "description": "Blur in pixels shared by both subjects at the cut seam.", "default": 12, "min": 0, "max": 40, "step": 1, "unit": "px" },
      { "id": "exit", "type": "enum", "role": "timing", "label": "Exit", "description": "Optional departure of the incoming subject. Default none: it rests until the frame cuts.", "default": "none", "options": [{ "value": "none", "label": "None" }, { "value": "fade", "label": "Fade" }, { "value": "up", "label": "Up" }] }
    ]'
  >
    <head>
      <meta charset="UTF-8" />
      <title>Cut the Curve</title>
    </head>
    <body>
      <template>
        <div id="root" data-composition-id="cut-the-curve" data-duration="1" data-fps="30">
          <style>
            *,
            *::before,
            *::after {
              box-sizing: border-box;
            }

            #root {
              position: absolute;
              inset: 0;
              container-type: size;
              isolation: isolate;
              overflow: hidden;
              color: var(--fg, #f8fafc);
              font-family: var(--font-body, Inter, system-ui, sans-serif);
            }

            .ctc-clip,
            .ctc-backdrop,
            .ctc-subject {
              position: absolute;
              inset: 0;
            }

            .ctc-clip {
              overflow: hidden;
            }

            .ctc-backdrop {
              background:
                radial-gradient(
                  circle at var(--ctc-glow-x, 24%) var(--ctc-glow-y, 28%),
                  color-mix(
                    in srgb,
                    var(--fg, #f8fafc) var(--ctc-glow-strength, 18%),
                    var(--transparent, transparent)
                  ),
                  var(--transparent, transparent) var(--ctc-glow-radius, 42%)
                ),
                var(--bg, #0b1120);
            }

            .ctc-subject {
              display: grid;
              place-items: center;
              opacity: 0;
              will-change: transform, filter, opacity;
            }

            .ctc-subject.is-outgoing {
              opacity: 1;
              --ctc-primary: color-mix(in srgb, var(--fg, #f8fafc) 45%, transparent);
              --ctc-secondary: color-mix(in srgb, var(--fg, #f8fafc) 18%, transparent);
            }

            .ctc-subject.is-incoming {
              --ctc-primary: color-mix(in srgb, var(--fg, #f8fafc) 72%, transparent);
              --ctc-secondary: color-mix(in srgb, var(--fg, #f8fafc) 45%, transparent);
            }

            .ctc-art {
              display: none;
            }

            #root[data-subject="cursor"] .ctc-cursor,
            #root[data-subject="card"] .ctc-card,
            #root[data-subject="scene"] .ctc-scene {
              display: block;
            }

            .ctc-cursor {
              position: relative;
              width: var(--ctc-cursor-width, 15cqw);
              height: var(--ctc-cursor-height, 24cqh);
            }

            .ctc-cursor svg {
              width: var(--ctc-cursor-svg-width, 100%);
              height: var(--ctc-cursor-svg-height, 100%);
              overflow: visible;
              filter: drop-shadow(
                var(--ctc-shadow-x, 0cqw) var(--ctc-shadow-y, 1cqh) var(--ctc-shadow-blur, 1.6cqw)
                  color-mix(
                    in srgb,
                    var(--bg, #0b1120) var(--ctc-shadow-strength, 65%),
                    var(--transparent, transparent)
                  )
              );
            }

            .ctc-cursor-shape {
              fill: var(--ctc-primary, var(--fg, #f8fafc));
              stroke: var(--fg, #f8fafc);
              stroke-width: var(--ctc-cursor-stroke, 1.8);
              stroke-linejoin: round;
            }

            .ctc-cursor-pulse {
              position: absolute;
              left: var(--ctc-pulse-left, -5cqw);
              top: var(--ctc-pulse-top, -5cqh);
              width: var(--ctc-pulse-size, 11cqw);
              aspect-ratio: var(--ctc-pulse-ratio, 1);
              border: var(--ctc-pulse-border, 0.25cqw) solid
                color-mix(
                  in srgb,
                  var(--ctc-secondary, var(--fg, #f8fafc)) var(--ctc-pulse-strength, 58%),
                  var(--transparent, transparent)
                );
              border-radius: var(--ctc-round, 50%);
            }

            .ctc-card {
              width: var(--ctc-card-width, 42cqw);
              min-height: var(--ctc-card-height, 34cqh);
              padding: var(--ctc-card-padding-y, var(--space-3, 4.5cqh))
                var(--ctc-card-padding-x, var(--space-3, 4cqw));
              border: var(--ctc-border-width, 0.22cqw) solid var(--border, #334155);
              border-radius: var(--radius, 2cqw);
              background: var(--surface, #1e293b);
              box-shadow: var(--ctc-shadow-x, 0cqw) var(--ctc-card-shadow-y, 2.4cqh)
                var(--ctc-card-shadow-blur, 5cqw)
                color-mix(
                  in srgb,
                  var(--bg, #0b1120) var(--ctc-card-shadow-strength, 55%),
                  var(--transparent, transparent)
                );
            }

            .ctc-card-chip {
              width: var(--ctc-chip-width, 9cqw);
              height: var(--ctc-chip-height, 2.2cqh);
              border-radius: var(--ctc-pill-radius, 99cqw);
              background: var(--ctc-primary, var(--fg, #f8fafc));
              margin-bottom: var(--ctc-card-gap, var(--space-3, 3.2cqh));
            }

            .ctc-card-line,
            .ctc-scene-line {
              height: var(--ctc-line-height, 1.8cqh);
              border-radius: var(--ctc-pill-radius, 99cqw);
              background: var(--fg, #f8fafc);
            }

            .ctc-card-line + .ctc-card-line {
              margin-top: var(--ctc-line-gap, var(--space-2, 2.2cqh));
            }

            .ctc-card-line:first-of-type {
              width: var(--ctc-line-long, 88%);
            }

            .ctc-card-line:last-of-type {
              width: var(--ctc-line-short, 58%);
              opacity: var(--ctc-muted-opacity, 0.42);
            }

            .ctc-scene {
              width: var(--ctc-scene-width, 68cqw);
              height: var(--ctc-scene-height, 58cqh);
              overflow: hidden;
              border: var(--ctc-border-width, 0.22cqw) solid var(--border, #334155);
              border-radius: var(--radius, 2cqw);
              background: var(--surface, #1e293b);
              box-shadow: var(--ctc-shadow-x, 0cqw) var(--ctc-card-shadow-y, 2.4cqh)
                var(--ctc-card-shadow-blur, 5cqw)
                color-mix(
                  in srgb,
                  var(--bg, #0b1120) var(--ctc-card-shadow-strength, 55%),
                  var(--transparent, transparent)
                );
            }

            .ctc-scene-bar {
              display: flex;
              align-items: center;
              gap: var(--ctc-dot-gap, var(--space-1, 1cqw));
              height: var(--ctc-scene-bar-height, 8cqh);
              padding-inline: var(--ctc-scene-pad, var(--space-2, 2cqw));
              border-bottom: var(--ctc-border-width, 0.22cqw) solid var(--border, #334155);
            }

            .ctc-scene-dot {
              width: var(--ctc-dot-size, 1.4cqw);
              aspect-ratio: var(--ctc-pulse-ratio, 1);
              border-radius: var(--ctc-round, 50%);
              background: var(--ctc-primary, var(--fg, #f8fafc));
            }

            .ctc-scene-body {
              display: grid;
              grid-template-columns: var(--ctc-scene-columns, 1fr 2fr);
              gap: var(--ctc-scene-gap, var(--space-3, 3cqw));
              padding: var(--ctc-scene-body-pad, var(--space-3, 5cqh))
                var(--ctc-scene-pad, var(--space-3, 3cqw));
            }

            .ctc-scene-panel {
              min-height: var(--ctc-panel-height, 34cqh);
              border-radius: var(--ctc-panel-radius, var(--radius, 1.2cqw));
              background: color-mix(
                in srgb,
                var(--ctc-primary, var(--fg, #f8fafc)) var(--ctc-panel-strength, 24%),
                var(--surface, #1e293b)
              );
            }

            .ctc-scene-copy {
              padding-top: var(--ctc-copy-top, var(--space-2, 2cqh));
            }

            .ctc-scene-line + .ctc-scene-line {
              margin-top: var(--ctc-scene-line-gap, var(--space-3, 3cqh));
            }

            .ctc-scene-line:nth-child(1) {
              width: var(--ctc-scene-line-one, 92%);
            }

            .ctc-scene-line:nth-child(2) {
              width: var(--ctc-scene-line-two, 68%);
              opacity: var(--ctc-muted-opacity, 0.42);
            }

            .ctc-scene-line:nth-child(3) {
              width: var(--ctc-scene-line-three, 78%);
              background: var(--ctc-secondary, var(--fg, #f8fafc));
            }
          </style>

          <div
            id="cut-the-curve-clip"
            class="ctc-clip clip"
            data-start="0"
            data-duration="1"
            data-track-index="0"
          >
            <div class="ctc-backdrop"></div>

            <div class="ctc-subject is-outgoing" aria-hidden="true">
              <div class="ctc-art ctc-cursor">
                <span class="ctc-cursor-pulse"></span>
                <svg viewBox="0 0 64 88" aria-hidden="true">
                  <path
                    class="ctc-cursor-shape"
                    d="M8 5 L54 43 L34 47 L45 75 L30 82 L19 53 L8 68 Z"
                  />
                </svg>
              </div>
              <div class="ctc-art ctc-card">
                <div class="ctc-card-chip"></div>
                <div class="ctc-card-line"></div>
                <div class="ctc-card-line"></div>
              </div>
              <div class="ctc-art ctc-scene">
                <div class="ctc-scene-bar">
                  <span class="ctc-scene-dot"></span><span class="ctc-scene-dot"></span
                  ><span class="ctc-scene-dot"></span>
                </div>
                <div class="ctc-scene-body">
                  <div class="ctc-scene-panel"></div>
                  <div class="ctc-scene-copy">
                    <div class="ctc-scene-line"></div>
                    <div class="ctc-scene-line"></div>
                    <div class="ctc-scene-line"></div>
                  </div>
                </div>
              </div>
            </div>

            <div class="ctc-subject is-incoming" aria-hidden="true">
              <div class="ctc-art ctc-cursor">
                <span class="ctc-cursor-pulse"></span>
                <svg viewBox="0 0 64 88" aria-hidden="true">
                  <path
                    class="ctc-cursor-shape"
                    d="M8 5 L54 43 L34 47 L45 75 L30 82 L19 53 L8 68 Z"
                  />
                </svg>
              </div>
              <div class="ctc-art ctc-card">
                <div class="ctc-card-chip"></div>
                <div class="ctc-card-line"></div>
                <div class="ctc-card-line"></div>
              </div>
              <div class="ctc-art ctc-scene">
                <div class="ctc-scene-bar">
                  <span class="ctc-scene-dot"></span><span class="ctc-scene-dot"></span
                  ><span class="ctc-scene-dot"></span>
                </div>
                <div class="ctc-scene-body">
                  <div class="ctc-scene-panel"></div>
                  <div class="ctc-scene-copy">
                    <div class="ctc-scene-line"></div>
                    <div class="ctc-scene-line"></div>
                    <div class="ctc-scene-line"></div>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
          <script>
            (function () {
              "use strict";

              var root = document.getElementById("root");
              var outgoing = root.querySelector(".is-outgoing");
              var incoming = root.querySelector(".is-incoming");
              var vars =
                window.__hyperframes && window.__hyperframes.getVariables
                  ? window.__hyperframes.getVariables()
                  : {};

              var subject =
                vars.subject === "card" || vars.subject === "scene" ? vars.subject : "cursor";
              var direction =
                vars.direction === "right" || vars.direction === "up" || vars.direction === "down"
                  ? vars.direction
                  : "left";
              var rawCut = Number(vars.cutFraction);
              var cutFraction = Number.isFinite(rawCut) ? Math.max(0, Math.min(1, rawCut)) : 0.33;
              var rawBlur = Number(vars.blurPx);
              var blurPx = Number.isFinite(rawBlur) ? Math.max(0, rawBlur) : 12;
              var exit = vars.exit === "fade" || vars.exit === "up" ? vars.exit : "none";

              root.dataset.subject = subject;

              // Direction is the single owner of axis, sign, unit, and base travel.
              var vectors = {
                left: { axis: "x", sign: -1, unit: "cqw", distance: 34 },
                right: { axis: "x", sign: 1, unit: "cqw", distance: 34 },
                up: { axis: "y", sign: -1, unit: "cqh", distance: 26 },
                down: { axis: "y", sign: 1, unit: "cqh", distance: 26 },
              };
              var vector = vectors[direction];
              var duration = Math.max(0.001, parseFloat(root.dataset.duration || "1"));
              // Exit none keeps the whole duration for the cut profile. An
              // enabled exit reserves a short tail after the incoming lands.
              var EXIT = exit === "none" ? 0 : Math.min(0.35, duration * 0.25);
              var TRAVEL = Math.max(0.001, duration - EXIT);
              var CUT_AT = TRAVEL * cutFraction;
              var ENTRY_DURATION = TRAVEL - CUT_AT;
              var entryDistance =
                CUT_AT > 0 ? vector.distance * (ENTRY_DURATION / CUT_AT) : vector.distance * 2;
              var seamBlur = "blur(" + blurPx + "px)";
              var clearBlur = "blur(0px)";
              var seamOpacity = 0.72;

              var outgoingEnd = { opacity: seamOpacity, filter: seamBlur };
              outgoingEnd[vector.axis] = vector.sign * vector.distance + vector.unit;

              var incomingStart = { x: 0, y: 0, opacity: 0, filter: seamBlur };
              incomingStart[vector.axis] = -vector.sign * entryDistance + vector.unit;

              var incomingEnd = { opacity: 1, filter: clearBlur };
              incomingEnd[vector.axis] = 0;

              gsap.set(outgoing, { x: 0, y: 0, opacity: 1, filter: clearBlur });
              gsap.set(incoming, incomingStart);

              var tl = gsap.timeline({ paused: true });

              if (CUT_AT > 0) {
                tl.to(
                  outgoing,
                  Object.assign({}, outgoingEnd, { duration: CUT_AT, ease: "power4.in" }),
                  0,
                );
              }

              // CUT: one visibility owner, matched blur and opacity on both sides.
              tl.set(outgoing, { opacity: 0 }, CUT_AT);
              tl.set(incoming, { opacity: seamOpacity }, CUT_AT);
              tl.call(
                function () {
                  root.dispatchEvent(
                    new CustomEvent("hf:sfx", {
                      detail: { id: "whip-cut", t: CUT_AT },
                      bubbles: true,
                    }),
                  );
                },
                [],
                CUT_AT,
              );

              if (ENTRY_DURATION > 0) {
                tl.to(
                  incoming,
                  Object.assign({}, incomingEnd, {
                    duration: ENTRY_DURATION,
                    ease: "power4.out",
                  }),
                  CUT_AT,
                );
              } else {
                tl.set(incoming, incomingEnd, CUT_AT);
              }

              // Optional departure; exit none rests until the frame cuts.
              if (exit === "fade") {
                tl.to(incoming, { opacity: 0, duration: EXIT, ease: "power2.in" }, TRAVEL);
              } else if (exit === "up") {
                tl.to(
                  incoming,
                  { opacity: 0, y: "-6cqh", duration: EXIT, ease: "power2.in" },
                  TRAVEL,
                );
              }

              tl.seek(0);

              window.__timelines = window.__timelines || {};
              window.__timelines["cut-the-curve"] = tl;
            })();
          </script>
        </div>
      </template>
    </body>
  </html>
  ```
</Accordion>

Tagged `transition` `directional-cut` `velocity-match` `whip` `bridge` `demonstrate`.

## Related topics

* [Browse the complete Catalog](/catalog)
* [Add assets and Catalog items in Studio](/studio/assets-and-blocks)
* [Build a richer composition](/go-further)


## Related topics

- [Whip Pan Cut](/catalog/components/whip-pan-cut.md)
- [Match Cut](/catalog/components/match-cut.md)
- [Spring Stack Shuffle](/catalog/components/spring-stack-shuffle.md)
