Install
That writes one file:compositions/yt-logo-intro.html.
Add it to your video
It runs for 6 seconds at 1920×1080. Paste this into your composition:index.html
<div
data-composition-id="yt-logo-intro"
data-composition-src="compositions/yt-logo-intro.html"
data-start="0"
data-duration="6"
data-track-index="1"
data-width="1920"
data-height="1080"
></div>
data-start. Put it on a different timeline row with
data-track-index. See data attributes for the rest.
Source
yt-logo-intro.html
yt-logo-intro.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<style>
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: transparent;
overflow: hidden;
}
#yt-li-root {
/* ---- yt tokens ---- */
--yt-font: "Inter", -apple-system, sans-serif;
--yt-paper: #e9e9e6;
--yt-paper-dark: #1c1c1e;
--yt-ink: #1d1d1f;
--yt-ink-dark: #e8e8e4;
--yt-red: #e62e2e;
--yt-line-alpha: 0.1;
position: relative;
width: 1920px;
height: 1080px;
overflow: hidden;
background: var(--yt-paper);
font-family: var(--yt-font);
}
#yt-li-root.yt-dark {
background: var(--yt-paper-dark);
}
#yt-li-lines {
position: absolute;
inset: 0;
}
.yt-li-line {
position: absolute;
left: -40px;
right: -40px;
height: 2px;
background: rgba(0, 0, 0, var(--yt-line-alpha));
}
.yt-dark .yt-li-line {
background: rgba(255, 255, 255, var(--yt-line-alpha));
}
#yt-li-center {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 42px;
}
#yt-li-logo {
width: 220px;
height: 220px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: var(--yt-ink);
color: #ffffff;
font-weight: 700;
font-size: 92px;
letter-spacing: -0.03em;
overflow: hidden;
}
.yt-dark #yt-li-logo {
background: var(--yt-ink-dark);
color: var(--yt-paper-dark);
}
#yt-li-logo img {
width: 100%;
height: 100%;
object-fit: contain;
}
.yt-li-shadow #yt-li-logo,
.yt-li-shadow #yt-li-text {
filter: drop-shadow(0 14px 30px rgba(0, 0, 0, 0.22));
}
#yt-li-textrow {
display: flex;
align-items: center;
gap: 26px;
min-height: 96px;
}
#yt-li-text {
font-weight: 700;
font-size: 74px;
letter-spacing: -0.015em;
color: var(--yt-ink);
white-space: nowrap;
}
.yt-dark #yt-li-text {
color: var(--yt-ink-dark);
}
#yt-li-arrow {
display: inline-flex;
align-items: center;
justify-content: center;
width: 84px;
height: 64px;
border-radius: 16px;
background: var(--yt-red);
opacity: 0;
}
#yt-li-arrow svg {
width: 38px;
stroke: #ffffff;
stroke-width: 3.2;
stroke-linecap: round;
stroke-linejoin: round;
fill: none;
}
</style>
</head>
<body>
<div
id="yt-li-root"
data-composition-id="yt-logo-intro"
data-start="0"
data-duration="6"
data-width="1920"
data-height="1080"
>
<div id="yt-li-lines"></div>
<div id="yt-li-center">
<div id="yt-li-logo"></div>
<div id="yt-li-textrow">
<div id="yt-li-text"></div>
<div id="yt-li-arrow">
<svg viewBox="0 0 24 24"><path d="M4 12h15M13 5l7 7-7 7" /></svg>
</div>
</div>
</div>
<div
id="yt-li-drv"
class="clip"
data-start="0"
data-duration="6"
data-track-index="0"
style="position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none"
></div>
</div>
<script>
(function () {
window.__timelines = window.__timelines || {};
/* ---- published parameters ----
A logo intro: logo drops in, a kicker line, then the title
with an accent-red arrow. Background lines with frequency +
distortion (seeded offsets — no randomness). */
var CONFIG = {
scheme: "light", // "light" | "dark"
logoType: "text", // "text" | "image"
logoText: "YT",
logoSrc: null,
kicker: "LET'S DIVE IN",
title: "yt-logo-intro",
arrow: { enabled: true },
lines: { enabled: true, count: 12, distort: 10 },
dropShadow: true,
animationIn: true,
animationOut: true,
};
var DUR = 6;
function clamp(v, lo, hi) {
return Math.min(hi, Math.max(lo, v));
}
var IN = clamp(DUR * 0.08, 0.3, 0.8);
var OUT = clamp(DUR * 0.06, 0.25, 0.6);
var root = document.getElementById("yt-li-root");
var lines = document.getElementById("yt-li-lines");
var logo = document.getElementById("yt-li-logo");
var text = document.getElementById("yt-li-text");
var arrow = document.getElementById("yt-li-arrow");
if (CONFIG.scheme === "dark") root.classList.add("yt-dark");
if (CONFIG.dropShadow) root.classList.add("yt-li-shadow");
/* background lines: even spacing + seeded sine distortion */
if (CONFIG.lines.enabled) {
var gap = 1080 / (CONFIG.lines.count + 1);
for (var i = 1; i <= CONFIG.lines.count; i++) {
var l = document.createElement("div");
l.className = "yt-li-line";
var wobble = Math.sin(i * 2.399) * CONFIG.lines.distort;
l.style.top = Math.round(i * gap + wobble) + "px";
l.style.transform = "rotate(" + (Math.sin(i * 1.7) * 0.35).toFixed(2) + "deg)";
lines.appendChild(l);
}
}
if (CONFIG.logoType === "image" && CONFIG.logoSrc) {
var img = document.createElement("img");
img.src = CONFIG.logoSrc;
logo.appendChild(img);
} else {
logo.textContent = CONFIG.logoText;
}
if (!CONFIG.arrow.enabled) arrow.style.display = "none";
var tl = gsap.timeline({ paused: true });
if (CONFIG.animationIn) tl.from(root, { opacity: 0, duration: IN, ease: "power2.out" }, 0);
/* logo pops */
gsap.set(logo, { opacity: 0, scale: 0.55, y: 24 });
tl.to(
logo,
{ opacity: 1, scale: 1, y: 0, duration: 0.55, ease: "back.out(1.5)" },
IN * 0.6,
);
/* kicker -> swap -> title + arrow */
gsap.set(text, { opacity: 0, y: 14 });
tl.set(text, { textContent: CONFIG.kicker, letterSpacing: "0.22em", fontSize: "40px" }, 0);
tl.to(text, { opacity: 1, y: 0, duration: 0.45, ease: "power2.out" }, IN * 0.6 + 0.45);
tl.to(text, { opacity: 0, y: -12, duration: 0.3, ease: "power2.in" }, 2.3);
tl.set(
text,
{ textContent: CONFIG.title, letterSpacing: "-0.015em", fontSize: "74px", y: 14 },
2.62,
);
tl.to(text, { opacity: 1, y: 0, duration: 0.5, ease: "power3.out" }, 2.66);
gsap.set(arrow, { scale: 0.5, x: -14 });
tl.to(arrow, { opacity: 1, scale: 1, x: 0, duration: 0.45, ease: "back.out(1.6)" }, 2.9);
/* ambient: lines breathe */
tl.to(lines, { y: 8, duration: 2.2, ease: "sine.inOut", yoyo: true, repeat: 1 }, 0.8);
/* exit + hard kill */
if (CONFIG.animationOut) {
tl.to(root, { opacity: 0, duration: OUT, ease: "power2.in" }, DUR - OUT - 0.05);
}
tl.set(root, { visibility: "hidden" }, DUR - 0.02);
window.__timelines["yt-logo-intro"] = tl;
})();
</script>
</body>
</html>
logo intro creator.