Hex Orbit
cellforge/cell-lattice-1FreeComponent
A 3-4-5-4-3 hexagonal dot field with two soft perimeter heads chasing around the shell while the center stays quietly lit.
Install it
npx shadcn@latest add https://cellforge.dev/r/cell-lattice-1.jsonSource
1"use client";23import type { CSSProperties } from "react";45import { cx } from "@/components/ui/cellforge-core";6import { resolveDmxColorTokens } from "@/components/ui/cellforge-core";7import { styleOpacity, stylePx } from "@/components/ui/cellforge-core";8import { remapOpacityToTriplet } from "@/components/ui/cellforge-core";9import { dmxBloomRootActive, dmxDotBloomParts } from "@/components/ui/cellforge-core";10import { getPatternIndexes } from "@/components/ui/cellforge-core";11import { useCellForgePhases } from "@/components/ui/cellforge-hooks";12import { useCyclePhase } from "@/components/ui/cellforge-hooks";13import { usePrefersReducedMotion } from "@/components/ui/cellforge-hooks";14import type { CellForgeCommonProps } from "@/components/ui/cellforge-core";1516export type CellLattice1Props = CellForgeCommonProps;1718const ROW_COUNTS = [3, 4, 5, 4, 3] as const;19const BASE_OPACITY = 0.1;20const MID_OPACITY = 0.2;21const HIGH_OPACITY = 0.96;22const CENTER_OPACITY = 0.1;23const TRAIL_SPAN = 5;24const HEX_ROW_PITCH_RATIO = Math.sqrt(3) / 2;2526function hexPatternIndex(row: number, rowCount: number, col: number): number {27 return row * ROW_COUNTS[2] + Math.floor((ROW_COUNTS[2] - rowCount) / 2) + col;28}2930const PERIMETER_PATH = [31 "0,0",32 "0,1",33 "0,2",34 "1,3",35 "2,4",36 "3,3",37 "4,2",38 "4,1",39 "4,0",40 "3,0",41 "2,0",42 "1,0"43] as const;4445const PATH_LEN = PERIMETER_PATH.length;46const HALF_PATH = PATH_LEN / 2;4748function clamp01(n: number | undefined) {49 if (n == null || !Number.isFinite(n)) {50 return;51 }52 return Math.min(1, Math.max(0, n));53}5455function modF(n: number, m: number): number {56 return ((n % m) + m) % m;57}5859function smoothstep01(edge0: number, edge1: number, x: number): number {60 if (edge1 <= edge0) {61 return x >= edge1 ? 1 : 0;62 }63 const t = Math.max(0, Math.min(1, (x - edge0) / (edge1 - edge0)));64 return t * t * (3 - 2 * t);65}6667function glowAlongPath(head: number, pathIndex: number | null): number {68 if (pathIndex === null) {69 return BASE_OPACITY;70 }7172 const distance = modF(head - pathIndex, PATH_LEN);73 const glow = 1 - smoothstep01(0, TRAIL_SPAN, distance);74 return BASE_OPACITY + glow * (HIGH_OPACITY - BASE_OPACITY);75}7677function opacityForCell(id: string, phase: number): number {78 if (id === "2,2") {79 return CENTER_OPACITY;80 }8182 const pathIndex = PERIMETER_PATH.indexOf(id as (typeof PERIMETER_PATH)[number]);83 const normalizedPathIndex = pathIndex === -1 ? null : pathIndex;84 const headA = phase * PATH_LEN;85// … truncated
More from @cellforge
All 71 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| All CellForge Loadersall | @cellforge | Components | Free | no deps | |
| Core Spokescell-angle-1 | @cellforge | Components | Free | no deps | |
| Column Rakecell-angle-10 | @cellforge | Components | Free | no deps | |
| Shelf Descentcell-angle-11 | @cellforge | Components | Free | no deps | |
| Skew Driftcell-angle-12 | @cellforge | Components | Free | no deps | |
| Serpent Zipcell-angle-13 | @cellforge | Components | Free | no deps | |
| Pillar Sweepcell-angle-14 | @cellforge | Components | Free | no deps | |
| Tripod Handoffcell-angle-15 | @cellforge | Components | Free | no deps |
