Command Palette

Search for a command to run...

Docs
Breeze Footer

Breeze Footer

A footer component that uses an SVG mask to display an animated video background, because your footer deserves a cinematic ending.

Scroll down ↓

Installation

Install the following dependencies:

npm install clsx tailwind-merge

Add the utils.ts file to the @/lib folder

utils.ts

import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
 
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

Create a breeze-footer.tsx file and copy the below code.

breeze-footer.tsx

"use client";
import React, { useEffect, useRef } from "react";
 
type BreezeFooterProps = {
  svgMask: string; // either raw <svg> code or path like "/logoMask.svg"
  videoSrc: string;
  speed?: number;
  invert?: number; // 0 = normal colors, 1 = fully inverted
  maskSize?: string;
  maskPosition?: string;
};
 
const BreezeFooter: React.FC<BreezeFooterProps> = ({
  svgMask,
  videoSrc,
  speed = 1,
  maskSize = "contain",
  maskPosition = "center",
  invert = 0,
}) => {
  const videoRef = useRef<HTMLVideoElement>(null);
 
  // If svgMask starts with "<svg", treat it as SVG markup
  const maskUrl = svgMask.trim().startsWith("<svg")
    ? `data:image/svg+xml;utf8,${encodeURIComponent(svgMask)}`
    : svgMask; // direct file path
 
  useEffect(() => {
    if (videoRef.current) {
      videoRef.current.playbackRate = speed;
    }
  }, [speed]);
 
  return (
    <div className="pointer-events-none relative aspect-[64/9] w-full overflow-hidden">
      <div
        style={{
          width: "100%",
          height: "100%",
          WebkitMaskImage: `url("${maskUrl}")`,
          WebkitMaskRepeat: "no-repeat",
          maskRepeat: "no-repeat",
          WebkitMaskPosition: maskPosition,
          maskPosition,
          WebkitMaskSize: maskSize,
          maskSize,
          position: "relative",
        }}
      >
        <video
          ref={videoRef}
          src={videoSrc}
          autoPlay
          muted
          loop
          playsInline
          style={{
            width: "100%",
            height: "100%",
            objectFit: "cover",
            filter: `invert(${invert})`,
          }}
        ></video>
      </div>
    </div>
  );
};
 
export default BreezeFooter;

Update the import paths to match your project setup.

Usage

import BreezeFooter from "@/components/breezeblocks/breeze-footer";
// you can either use:
 
// Inline SVG
<BreezeFooter
  svgMask={`<svg>...</svg>`}
  videoSrc="/video.mp4"
  speed={0.5}
  invert={1}
/>
 
// Or from SVG file
<BreezeFooter
  svgMask="/mask.svg"
  videoSrc="/video.mp4"
  speed={0.5}
/>

Props

PropTypeDescriptionDefault
svgMaskstringThe mask source. Can be inline SVG code (<svg>…</svg>) or .svg file pathrequired
videoSrcstringPath/URL to the video filerequired
speednumberSpeed multiplier for the video1
invertnumberInverts video colors. 0 = normal, 1 = fully inverted0
maskSizestringCSS mask-size value"contain"
maskPositionstringCSS mask-position value"center"