UI/Components/Card elements/Floating Card

Floating Card

A Remotion video component that animates a card floating up and down with a spring-based entry.

Floating Card!
0:00 / 0:06

Installation

CLI

npx shadcn@latest add "https://clippkit.com/r/floating-card"

Manual

Create a new file, for example, at src/components/clippkit/floating-card.tsx (or your preferred location) and paste the following code into it.

/**
 * Free Remotion Template Component
 * ---------------------------------
 * This template is free to use in your projects!
 * Credit appreciated but not required.
 *
 * Created by the team at https://www.reactvideoeditor.com
 *
 * Happy coding and building amazing videos! 🎉
 */
 
"use client";
 
import { spring, useCurrentFrame, useVideoConfig } from "remotion";
 
interface FloatingCardProps {
  text?: string;
  textColor?: string;
  backgroundColor?: string;
  fontSize?: string;
  width?: string;
  height?: string;
  borderRadius?: string;
  borderColor?: string;
  borderWidth?: string;
  borderStyle?: "solid" | "dashed" | "dotted";
  durationInFrames?: number; // Duration of the entry animation
  damping?: number;
  mass?: number;
  stiffness?: number;
  boxShadow?: string;
  floatAmplitude?: number; // How much the card floats up and down
  floatSpeed?: number; // Speed of the floating animation
}
 
export function FloatingCard({
  text = "Floating Card",
  textColor = "var(--card-foreground)",
  backgroundColor = "var(--card)",
  fontSize = "1.25rem",
  width = "200px",
  height = "280px",
  borderRadius = "15px",
  borderColor = "var(--ring)",
  borderWidth = "1px",
  borderStyle = "solid",
  durationInFrames = 30, // Shorter for entry animation
  damping = 12,
  mass = 0.5,
  stiffness = 100,
  boxShadow = `0 1px 3px var(--border), 0 6px 12px oklch(from var(--border) calc(l - 0.1) c h / 30%)`,
  floatAmplitude = 10, // Pixels
  floatSpeed = 30, // Divisor for frame, smaller is faster
}: FloatingCardProps) {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
 
  // Entry animation for scale
  const scale = spring({
    frame,
    fps,
    from: 0,
    to: 1,
    durationInFrames,
    config: {
      damping,
      mass,
      stiffness,
    },
  });
 
  // Floating animation for position
  const floatOffset = Math.sin(frame / floatSpeed) * floatAmplitude;
 
  const cardStyle: React.CSSProperties = {
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: `translate(-50%, -50%) translateY(${floatOffset}px) scale(${scale})`,
    width,
    height,
    background: backgroundColor,
    borderRadius,
    borderColor,
    borderWidth,
    borderStyle,
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    fontSize,
    fontWeight: "bold",
    color: textColor,
    padding: "10px", // Added padding similar to CardFlip face
    boxSizing: "border-box", // Added for consistent padding behavior
    boxShadow,
    overflow: "hidden", // Ensures border radius is respected with box shadow
  };
 
  return <div style={cardStyle}>{text}</div>;
}
Update the import paths in your Remotion compositions if you placed the file in a different location than shown in the usage examples.

Usage

Once the FloatingCard component is added to your project (either via CLI or Manually), you can integrate it into your Remotion project by importing it and defining a Composition.

Prerequisite

Ensure you have a Remotion project set up. If not, please refer to the Remotion documentation to get started.

Project Structure Example

Here’s an example folder layout showing where to place the component and how it fits into a typical Remotion project

app/main.tsx
import { Player } from "@remotion/player";
 
import FloatingCard from "../components/floating-card"; // Adjusted path
 
export function FloatingCardDemo() {
  const floatingCardProps = {
    text: "Floating Card!",
    textColor: "var(--foreground)",
    backgroundColor: "var(--card)",
    fontSize: "1.5rem",
    width: "250px",
    height: "180px",
    borderRadius: "20px",
    borderColor: "var(--primary)",
    borderWidth: "1px",
    borderStyle: "solid" as const,
    durationInFrames: 40, // Entry animation duration
    damping: 15,
    mass: 0.7,
    stiffness: 110,
    boxShadow: "0 10px 25px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.1)",
    floatAmplitude: 15, // Amplitude of the float
    floatSpeed: 40, // Speed of the float
  };
 
  return (
    <Player
      component={FloatingCard}
      inputProps={floatingCardProps}
      durationInFrames={180} // Total duration of the player timeline, longer to see float
      compositionWidth={480}
      compositionHeight={400}
      fps={30}
      style={{
        width: "100%",
        height: "100%",
        backgroundColor: "var(--background)",
      }}
      autoPlay
      controls
      loop
    />
  );
}

Define a Composition

In your Remotion project's entry file (commonly src/Root.tsx, src/index.tsx, app/main.tsx), import FloatingCard and define a Composition.

app/main.tsx (or equivalent)
import { Player } from "@remotion/player";

import FloatingCard from "@/components/clippkit/floating-card"; // Assuming you placed it in src/components/clippkit

export default function FloatingCardScene() {
  const floatingCardProps = {
    text: "Hello From Remotion!",
    textColor: "#FFF",
    backgroundColor: "linear-gradient(45deg, #7e22ce, #a21caf)",
    fontSize: "1.8rem",
    width: "300px",
    height: "200px",
    borderRadius: "25px",
    borderColor: "#FFF",
    borderWidth: "2px",
    borderStyle: "solid" as const,
    durationInFrames: 45, // Duration of entry animation
    damping: 18,
    mass: 0.6,
    stiffness: 90,
    boxShadow: "0 8px 16px rgba(0,0,0,0.25)",
    floatAmplitude: 20,
    floatSpeed: 35,
  };

  return (
    <Player
      component={FloatingCard}
      inputProps={floatingCardProps}
      durationInFrames={180} // Total duration of the player timeline
      compositionWidth={500}
      compositionHeight={500} // Square aspect ratio to see the card nicely
      fps={30}
      style={{
        width: "100%",
        height: "100%",
      }}
      autoPlay
      controls
      loop
    />
  );
}

API Reference

The component exported as FloatingCard (e.g., from apps/docs/registry/default/ui/floating-card.tsx or your project's component path) accepts the following props to customize its animation and appearance:

PropTypeDefault ValueDescription
textstring"Floating Card"The text content to display on the card.
textColorstring"var(--card-foreground)"The color of the text on the card. Accepts any valid CSS color value.
backgroundColorstring"var(--card)"The background of the card. Accepts any valid CSS background value.
fontSizestring"1.25rem"The font size of the text on the card. Accepts any valid CSS font-size value.
widthstring"200px"The width of the card. Accepts any valid CSS width value.
heightstring"280px"The height of the card. Accepts any valid CSS height value.
borderRadiusstring"15px"The border radius of the card. Accepts any valid CSS border-radius value.
borderColorstring"var(--ring)"The border color of the card. Accepts any valid CSS color value.
borderWidthstring"1px"The border width of the card. Accepts any valid CSS border-width value.
borderStylestring"solid"The border style of the card. Can be "solid", "dashed", or "dotted".
durationInFramesnumber30The duration of the entry spring animation in frames.
dampingnumber12The damping amount for the entry spring animation. Controls how quickly oscillations die down.
massnumber0.5The mass for the entry spring animation.
stiffnessnumber100The stiffness for the entry spring animation.
boxShadowstring"0 1px 3px var(--border), ..."The box shadow for the card. Accepts any valid CSS box-shadow value.
floatAmplitudenumber10The amplitude (in pixels) of the vertical floating motion.
floatSpeednumber30A divisor for the frame in the sine wave calculation; smaller values mean faster floating.

On this page