Componentmedia0.73 KB gzipZero dependencies

Damage Vignette

Edge flash overlay that pulses on every hit.

Preview

Live Preview
ARENA VIEW · HITS 0
No damage

Installation

Tokens guide →

Add to your project via CLI (zero dependencies, code you own):

npx bigbullui add damage-vignette

Or install the full npm package:

npm install bigbullui
import { DamageVignette } from "@/components/ui/damage-vignette";

<DamageVignette hitKey={hits}>Arena view</DamageVignette>

Usage guidance

Use Damage Vignette when a ticket stub surface needs Edge flash overlay that pulses on every hit. Keep props minimal and prefer composition with sibling stubs.

Avoid Damage Vignette for long form flows or dense data grids where a dedicated layout block fits better.

Source code

damage-vignette.tsx

Zero dependencies (only React + utils). Copy and paste directly into your project:

"use client";

import * as React from "react";
import { cn } from "./lib/utils";

export interface DamageVignetteProps extends React.HTMLAttributes<HTMLDivElement> {
  hitKey: number;
  intensity?: number;
}

/** Damage vignette: edge flash that pulses on every hitKey change, silent under motion-reduce. */
export function DamageVignette({ hitKey, intensity = 0.55, className, children, ...props }: DamageVignetteProps) {
  const [flash, setFlash] = React.useState(0);
  React.useEffect(() => {
    if (hitKey <= 0) return;
    setFlash((f) => f + 1);
    const t = setTimeout(() => setFlash((f) => Math.max(0, f - 1)), 450);
    return () => clearTimeout(t);
  }, [hitKey]);

  return (
    <div className={cn("relative overflow-hidden", className)} {...props}>
      <style>{`@keyframes dmgFlash { 0% { opacity: 0; } 25% { opacity: 1; } 100% { opacity: 0; } }`}</style>
      {children}
      {flash > 0 && (
        <div
          key={flash}
          aria-hidden="true"
          className="pointer-events-none absolute inset-0 animate-[dmgFlash_0.45s_ease-out] motion-reduce:animate-none"
          style={{
            opacity: intensity,
            background: "radial-gradient(ellipse at center, transparent 45%, var(--destructive) 100%)",
          }}
        />
      )}
      <span className="sr-only" role="status">
        {hitKey > 0 ? `Took damage ${hitKey} times` : "No damage"}
      </span>
    </div>
  );
}

Props

PropTypeDescription
hitKeynumberIncrement to flash the edge vignette (required).
intensitynumberFlash opacity (default 0.55).