cutship.ai
Component · Text/Hooks · 9:16
Chrome Logo Spin
by CutshipVerified
Your logo as a solid chrome badge turning slowly in 3D: real thickness from stacked layers, a polished sky-and-horizon reflection, a sheen that sweeps the face and a soft floor shadow. Loops seamlessly. Drop in a transparent PNG, or type a name.
0 taken · 3 views
Included with Pro
Sign up free to Make this
Sign up free to unlock the spec, agent prompt and Make this.
components/remotion/chrome-logo-spin/component.tsx
import React from "react";
import { AbsoluteFill, Img, staticFile, useCurrentFrame, useVideoConfig } from "remotion";
import { loadFont } from "@remotion/google-fonts/Unbounded";
import type { ChromeLogoSpinProps } from "./schema";
const { fontFamily } = loadFont("normal", { weights: ["800"], subsets: ["latin"] });
const resolve = (src: string) => (/^(https?:|data:|\/)/.test(src) ? src : staticFile(src));
const FINISH: Record<ChromeLogoSpinProps["finish"], { face: string; side: (i: number) => string }> = {
chrome: {
face: "linear-gradient(180deg, #93a9c6 0%, #cfdcee 16%, #f6f9fd 32%, #b9c4d3 45%, #1b2028 49.5%, #3a2f27 53%, #8b7865 61%, #dacdbb 73%, #fcf7ef 85%, #a3937f 100%)",
side: (i) => `hsl(220 9% ${44 - i * 1.3}%)`,
},
gold: {
face: "linear-gradient(180deg, #fff3c4 0%, #f7d77a 18%, #fff8e1 32%, #d9a441 45%, #4a2e0b 49.5%, #6b4512 53%, #b98532 62%, #f3d27f 74%, #fff6d6 86%, #b88a3a 100%)",
side: (i) => `hsl(38 55% ${36 - i * 1.1}%)`,
},
"black chrome": {
face: "linear-gradient(180deg, #5d6470 0%, #9aa3b1 16%, #d7dde6 30%, #59606b 44%, #050608 49.5%, #121418 54%, #3c424b 64%, #8c95a3 76%, #c4ccd7 86%, #3a3f47 100%)",
side: (i) => `hsl(220 8% ${20 - i * 0.5}%)`,
},
};
export const ChromeLogoSpin: React.FC<ChromeLogoSpinProps> = ({
logo,
text,
tagline,
background,
spotlight,
finish,
depth,
turns,
tilt,
size,
brandKit,
}) => {
const frame = useCurrentFrame();
const { durationInFrames, width } = useVideoConfig();
const image = brandKit?.logo || logo;
const bg = brandKit?.colors?.[1] ?? background;
const metal = FINISH[finish];
const angle = (frame / durationInFrames) * 360 * turns;
// The sheen crosses the face once per turn, while it faces the camera.
const facing = ((angle % 360) + 360) % 360;
const sheenPos = facing < 70 ? 130 - (facing / 70) * 160 : facing > 300 ? 130 : -30;
// The shadow narrows when the badge is edge-on.
const edgeOn = Math.abs(Math.cos((angle * Math.PI) / 180));
const w = width * size;
const layerStep = (w / 500) * 1.6;
const shape: React.CSSProperties = image
? {
position: "absolute",
inset: 0,
WebkitMaskImage: `url("${resolve(image)}")`,
maskImage: `url("${resolve(image)}")`,
WebkitMaskSize: "contain",
maskSize: "contain",
WebkitMaskRepeat: "no-repeat",
maskRepeat: "no-repeat",
WebkitMaskPosition: "center",
maskPosition: "center",
}
: { position: "absolute", inset: 0, display: "grid", placeItems: "center" };
// A plain function (not a component), so layers update in place each frame instead of remounting.
const layer = ({ key, fill, z, rotate = 0, sheen = false, solid = false }: { key: string; fill: string; z: number; rotate?: number; sheen?: boolean; solid?: boolean }) =>
image ? (
<div key={key} style={{ ...shape, backfaceVisibility: solid ? "visible" : "hidden", background: fill, transform: `translateZ(${z}px) rotateY(${rotate}deg)`, backgroundSize: sheen ? "300% 100%" : undefined, backgroundPosition: sheen ? `${sheenPos}% 0` : undefined }} />
) : (
<div key={key} style={{ ...shape, backfaceVisibility: solid ? "visible" : "hidden", transform: `translateZ(${z}px) rotateY(${rotate}deg)` }}>
<span
style={{
fontFamily: brandKit?.fonts?.[0] ?? fontFamily,
fontWeight: 800,
fontSize: w / Math.max(3.4, text.length * 0.82),
lineHeight: 1,
whiteSpace: "nowrap",
background: fill,
backgroundSize: sheen ? "300% 100%" : undefined,
backgroundPosition: sheen ? `${sheenPos}% 0` : undefined,
WebkitBackgroundClip: "text",
backgroundClip: "text",
color: "transparent",
}}
>
{text}
</span>
</div>
);
return (
<AbsoluteFill style={{ background: bg, alignItems: "center", justifyContent: "center" }}>
<AbsoluteFill style={{ background: `radial-gradient(ellipse 60% 38% at 50% 48%, rgba(255,255,255,${0.16 * spotlight}), transparent 70%)` }} />
{/* Loads the logo before the first frame renders (the mask itself doesn't wait). */}
{image ? <Img src={resolve(image)} style={{ position: "absolute", width: 1, height: 1, opacity: 0 }} /> : null}
<div style={{ perspective: w * 3.2 }}>
<div style={{ position: "relative", width: w, height: image ? w * 0.55 : w * 0.4, transformStyle: "preserve-3d", transform: `rotateX(${tilt}deg) rotateY(${angle}deg)` }}>
{Array.from({ length: depth }, (_, i) => (
layer({ key: `side-${i}`, fill: metal.side(i), z: -(i + 1) * layerStep, solid: true })
))}
{layer({ key: "face", fill: metal.face, z: 0.5 })}
{layer({ key: "sheen", fill: "linear-gradient(100deg, transparent 35%, rgba(255,255,255,0.85) 46%, rgba(200,222,255,0.55) 50%, transparent 62%)", z: 1, sheen: true })}
{layer({ key: "back", fill: metal.face, z: -(depth + 1) * layerStep, rotate: 180 })}
</div>
</div>
<div
style={{
position: "absolute",
top: `calc(50% + ${w * 0.36}px)`,
width: w * 0.85 * (0.4 + 0.6 * edgeOn),
height: w * 0.05,
borderRadius: "50%",
background: "radial-gradient(closest-side, rgba(0,0,0,0.55), transparent)",
filter: `blur(${w * 0.012}px)`,
}}
/>
{tagline ? (
<div
style={{
position: "absolute",
top: `calc(50% + ${w * 0.48}px)`,
fontFamily: brandKit?.fonts?.[1] ?? fontFamily,
fontSize: w * 0.045,
letterSpacing: "0.22em",
textTransform: "uppercase",
color: "rgba(255,255,255,0.7)",
}}
>
{tagline}
</div>
) : null}
</AbsoluteFill>
);
};
Remotion code you can paste anywhere, or install it: npx cutship add chrome-logo-spin
MIT License: use it in any video, personal or commercial. License
More from Cutship
Creator page →