Map Steam
terrae/steamFreeComponent
Rising steam effect with wispy particle animation.
Install it
npx shadcn@latest add https://www.terrae.dev/steam.jsonSource
1"use client"23import { useEffect, useId, useRef, useState, useCallback } from "react"4import { useMap } from "./hooks"5import type { MapCoordinates } from "./types"67type SteamParticle = {8 x: number9 y: number10 velocityX: number11 velocityY: number12 radius: number13 life: number14 maxLife: number15 opacity: number16}1718type MapSteamProps = {19 id?: string20 coordinates: MapCoordinates21 size?: number22 intensity?: number23 particleCount?: number24 color?: string25 drift?: number26 riseSpeed?: number27 autoStart?: boolean28}2930type SteamRenderer = {31 width: number32 height: number33 data: Uint8ClampedArray34 context?: CanvasRenderingContext2D35 particles: SteamParticle[]36 isActive: boolean37 currentIntensity: number38 onAdd: () => void39 render: () => boolean40 start: () => void41 stop: () => void42 setIntensity: (intensity: number) => void43}4445type RgbColor = {46 red: number47 green: number48 blue: number49}5051type SteamControl = {52 start: () => void53 stop: () => void54 setIntensity: (intensity: number) => void55 isActive: boolean56}5758const DEFAULT_SIZE = 10059const DEFAULT_INTENSITY = 160const DEFAULT_PARTICLE_COUNT = 4061const DEFAULT_COLOR = "#ffffff"62const DEFAULT_DRIFT = 0.463const DEFAULT_RISE_SPEED = 164const CONTROL_UPDATE_INTERVAL = 1006566const hexToRgb = (hex: string): RgbColor => {67 const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)6869 if (!result) {70 return { red: 255, green: 255, blue: 255 }71 }7273 return {74 red: parseInt(result[1], 16),75 green: parseInt(result[2], 16),76 blue: parseInt(result[3], 16),77 }78}7980const createParticle = (81 centerX: number,82 baseY: number,83 intensity: number,84 drift: number,85 riseSpeed: number86): SteamParticle => {87 const spreadX = 20 * intensity8889 return {90 x: centerX + (Math.random() - 0.5) * spreadX,91 y: baseY + Math.random() * 10,92 velocityX: (Math.random() - 0.5) * drift,93 velocityY: -riseSpeed * (0.8 + Math.random() * 0.4),94 radius: 6 + Math.random() * 10 * intensity,95 life: 0,96 maxLife: 60 + Math.random() * 40,97 opacity: 0.3 + Math.random() * 0.4,98 }99}100101const fadeCanvasEdges = (context: CanvasRenderingContext2D, width: number, height: number) => {102 const edgeSize = Math.max(4, Math.floor(width * 0.06))103 context.globalCompositeOperation = "destination-out"104105 const topGradient = context.createLinearGradient(0, 0, 0, edgeSize)106 topGradient.addColorStop(0, "rgba(0, 0, 0, 1)")107 topGradient.addColorStop(1, "rgba(0, 0, 0, 0)")108// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from terrae
All 40 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Map Animated Circleanimated-circle | terrae | Components | Free | 1 dep | |
| Map Animated Footprintanimated-footprint | terrae | Components | Free | 2 deps | |
| Map Animated Polygonanimated-polygon | terrae | Components | Free | 1 dep | |
| Map Animated Pulseanimated-pulse | terrae | Components | Free | 1 dep | |
| Map Arc Animatedarc-animated | terrae | Components | Free | 1 dep | |
| Map Blur Areablur-area | terrae | Components | Free | 1 dep | |
| Map Camera Followcamera-follow | terrae | Components | Free | 1 dep | |
| Map Choroplethchoropleth | terrae | Components | Free | 1 dep |
