Retro Grid

Display an animated scrolling grid of retro squares.

Credits

Shout out to Magic UI for the inspiration. I actually discovered this package while browsing their website.

Getting Started

Add Animation

You will need to add this to your tailwind.css file.

--animate-grid: grid 15s linear infinite;

@keyframes grid {
  0% {
    transform: translateY(-50%);
  }
  100% {
    transform: translateY(0);
  }
}

Create Component

Create the component RetroGrid.vue in the components directory.

<template>
  <Primitive
    :as
    :as-child
    :class="styles({ class: props.class })"
    :style="{
      '--grid-angle': `${angle}deg`,
      '--cell-size': `${cellSize}px`,
      '--opacity': opacity,
      '--light-line': lightLineColor,
      '--dark-line': darkLineColor,
    }"
  >
    <div class="absolute inset-0 [transform:rotateX(var(--grid-angle))]">
      <div
        class="[inset:0%_0px] [margin-left:-200%] [height:300vh] [width:600vw] [transform-origin:100%_0_0] animate-grid [background-image:linear-gradient(to_right,var(--light-line)_1px,transparent_0),linear-gradient(to_bottom,var(--light-line)_1px,transparent_0)] [background-size:var(--cell-size)_var(--cell-size)] [background-repeat:repeat] dark:[background-image:linear-gradient(to_right,var(--dark-line)_1px,transparent_0),linear-gradient(to_bottom,var(--dark-line)_1px,transparent_0)]"
      />
    </div>

    <div
      class="absolute inset-0 bg-gradient-to-t from-white to-transparent to-90% dark:from-black"
    />
  </Primitive>
</template>

<script lang="ts">
  import { Primitive } from "reka-ui";
  import type { PrimitiveProps } from "reka-ui";
  import type { HTMLAttributes } from "vue";

  export type RetroGridProps = PrimitiveProps & {
    /**
     * Additional CSS classes to apply to the grid container
     */
    class?: HTMLAttributes["class"];
    /**
     * Rotation angle of the grid in degrees
     * @default 65
     */
    angle?: number;
    /**
     * Grid cell size in pixels
     * @default 60
     */
    cellSize?: number;
    /**
     * Grid opacity value between 0 and 1
     * @default 0.5
     */
    opacity?: number;
    /**
     * Grid line color in light mode
     * @default "gray"
     */
    lightLineColor?: string;
    /**
     * Grid line color in dark mode
     * @default "gray"
     */
    darkLineColor?: string;
  };
</script>

<script lang="ts" setup>
  const props = withDefaults(defineProps<RetroGridProps>(), {
    angle: 65,
    cellSize: 60,
    opacity: 0.5,
    lightLineColor: "gray",
    darkLineColor: "gray",
  });
  const styles = tv({
    base: [
      "pointer-events-none absolute size-full overflow-hidden [perspective:200px]",
      "opacity-[var(--opacity)]",
    ],
  });
</script>

Usage

Basic

Retro Grid