npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hive-academy/angular-3d

v1.1.0

Published

Declarative Three.js components for Angular - Build stunning 3D experiences with familiar Angular patterns

Readme

@hive-academy/angular-3d

npm version License: MIT

🎨 Declarative Three.js components for Angular applications

A modern Angular library providing declarative, type-safe wrappers for Three.js. Build stunning 3D graphics experiences with familiar Angular patterns using signals, standalone components, and dependency injection.

✨ Features

  • 🎯 Declarative API - Configure 3D scenes via Angular inputs and signals
  • 🎬 Scene Container - Automatic WebGLRenderer, Scene, and Camera setup
  • 📦 54 Components - Primitives, lights, text, particles, effects, loaders, and more
  • 💡 5 Light Types - Ambient, Directional, Point, Spot, and preset SceneLighting
  • 🌊 Animation Directives - Float3d, Rotate3d, and waypoint-based flight animations
  • 🎮 Orbit Controls - Interactive camera controls out of the box
  • 📥 Asset Loaders - GLTF/GLB models, SVG icons, and texture loading
  • 🎬 Scene Loading & Entrance - Asset preloading with cinematic camera animations
  • 🌈 Postprocessing - Bloom, DOF, SSAO, color grading, and 8+ effects
  • 🚀 WebGPU Ready - TSL (Three.js Shading Language) node-based materials
  • 🌐 SSR Compatible - Safely handles server-side rendering
  • 🌳 Tree-Shakeable - Import only what you need
  • 🎓 TypeScript First - Full type safety and IntelliSense support

Scope: This library provides 3D graphics components. For scroll animations, see @hive-academy/angular-gsap.


📦 Installation

npm install @hive-academy/angular-3d three three-stdlib gsap maath troika-three-text

Peer Dependencies:

| Package | Version | Purpose | | ------------------- | -------- | -------------------------------------------- | | @angular/core | ~20.3.0 | Angular framework | | @angular/common | ~20.3.0 | Angular common utilities | | three | ^0.182.0 | Three.js core library | | three-stdlib | ^2.35.0 | Three.js extensions (OrbitControls, loaders) | | gsap | ^3.14.2 | Animation engine (used by Float3d, Rotate3d) | | maath | ^0.10.8 | Math utilities for 3D calculations | | troika-three-text | ^0.52.4 | 3D text rendering | | rxjs | ~7.8.0 | Reactive extensions |


🚀 Quick Start

Example 1: Basic Scene with Box

import { Component } from '@angular/core';
import { Scene3dComponent, BoxComponent } from '@hive-academy/angular-3d';

@Component({
  selector: 'app-basic-scene',
  standalone: true,
  imports: [Scene3dComponent, BoxComponent],
  template: `
    <a3d-scene-3d [cameraPosition]="[0, 0, 5]">
      <a3d-box [position]="[0, 0, 0]" [color]="'#ff6b6b'" />
    </a3d-scene-3d>
  `,
  styles: [
    `
      a3d-scene-3d {
        display: block;
        width: 100%;
        height: 400px;
      }
    `,
  ],
})
export class BasicSceneComponent {}

Example 2: Scene with Lighting

import { Component } from '@angular/core';
import { Scene3dComponent, SphereComponent, SceneLightingComponent } from '@hive-academy/angular-3d';

@Component({
  selector: 'app-lit-scene',
  standalone: true,
  imports: [Scene3dComponent, SphereComponent, SceneLightingComponent],
  template: `
    <a3d-scene-3d [cameraPosition]="[0, 2, 5]">
      <a3d-scene-lighting />
      <a3d-sphere [position]="[0, 0, 0]" [color]="'#4ecdc4'" [metalness]="0.8" [roughness]="0.2" />
    </a3d-scene-3d>
  `,
})
export class LitSceneComponent {}

Example 3: Animated Scene

import { Component } from '@angular/core';
import { Scene3dComponent, TorusComponent, Float3dDirective, Rotate3dDirective, SceneLightingComponent } from '@hive-academy/angular-3d';

@Component({
  selector: 'app-animated-scene',
  standalone: true,
  imports: [Scene3dComponent, TorusComponent, Float3dDirective, Rotate3dDirective, SceneLightingComponent],
  template: `
    <a3d-scene-3d [cameraPosition]="[0, 0, 5]">
      <a3d-scene-lighting />
      <a3d-torus [position]="[0, 0, 0]" [color]="'#9b59b6'" float3d rotate3d />
    </a3d-scene-3d>
  `,
})
export class AnimatedSceneComponent {}

📚 API Reference

Scene Container

Scene3dComponent

Root scene container automatically sets up WebGLRenderer, Scene, PerspectiveCamera, and render loop.

Selector: <a3d-scene-3d>

Inputs:

  • cameraPosition?: [number, number, number] - Camera position (default: [0, 0, 5])
  • cameraTarget?: [number, number, number] - Camera look-at target (default: [0, 0, 0])
  • backgroundColor?: string - Scene background color
  • fov?: number - Camera field of view (default: 75)
  • enableShadows?: boolean - Enable shadow rendering
  • rendererOptions?: WebGLRendererParameters - Custom renderer config

Geometry Primitives

| Component | Selector | Description | | ----------------------- | ----------------------- | ----------------------------------------------- | | BoxComponent | <a3d-box> | Box/cube mesh with configurable size | | SphereComponent | <a3d-sphere> | Sphere mesh with radius and segments | | CylinderComponent | <a3d-cylinder> | Cylinder mesh with height and radius | | TorusComponent | <a3d-torus> | Torus (donut) mesh | | PolyhedronComponent | <a3d-polyhedron> | Platonic solids (tetrahedron, octahedron, etc.) | | FloatingSphereComponent | <a3d-floating-sphere> | Pre-animated floating sphere |

Common Inputs (all primitives):

  • position?: [number, number, number] - Position in 3D space
  • rotation?: [number, number, number] - Rotation in radians
  • scale?: [number, number, number] | number - Scale factor
  • color?: string - Material color (hex or CSS color name)
  • metalness?: number - Metalness (0-1, default: 0)
  • roughness?: number - Roughness (0-1, default: 0.5)
  • opacity?: number - Opacity (0-1, default: 1)
  • transparent?: boolean - Enable transparency

Lights

| Component | Selector | Description | | ------------------------- | ------------------------- | ------------------------------------------- | | AmbientLightComponent | <a3d-ambient-light> | Uniform ambient illumination | | DirectionalLightComponent | <a3d-directional-light> | Sun-like directional light with shadows | | PointLightComponent | <a3d-point-light> | Omnidirectional point light | | SpotLightComponent | <a3d-spot-light> | Focused cone spotlight | | SceneLightingComponent | <a3d-scene-lighting> | Preset lighting rig (ambient + directional) |

Example:

<a3d-scene-3d>
  <a3d-ambient-light [intensity]="0.5" />
  <a3d-directional-light [position]="[5, 5, 5]" [intensity]="1.0" [castShadow]="true" />
  <a3d-sphere [receiveShadow]="true" [castShadow]="true" />
</a3d-scene-3d>

Text Components

| Component | Selector | Description | | ----------------------------- | ------------------------------ | -------------------------------- | | TroikaTextComponent | <a3d-troika-text> | Basic 3D text using Troika | | ResponsiveTroikaTextComponent | <a3d-responsive-troika-text> | Responsive 3D text with maxWidth | | GlowTroikaTextComponent | <a3d-glow-troika-text> | 3D text with glow effect | | SmokeTroikaTextComponent | <a3d-smoke-troika-text> | 3D text with smoke effect | | ParticlesTextComponent | <a3d-particle-text> | Text rendered as particles | | BubbleTextComponent | <a3d-bubble-text> | Text with bubble effect | | ExtrudedText3dComponent | <a3d-extruded-text-3d> | Extruded 3D text with depth |

Example:

<a3d-troika-text [text]="'Hello 3D World'" [fontSize]="0.5" [color]="'#ffffff'" [position]="[0, 0, 0]" />

Space-Themed Components

| Component | Selector | Description | | ------------------------- | ------------------------- | ------------------------------- | | PlanetComponent | <a3d-planet> | Planet with optional atmosphere | | StarFieldComponent | <a3d-star-field> | Particle-based star background | | NebulaComponent | <a3d-nebula> | Volumetric nebula effect | | NebulaVolumetricComponent | <a3d-nebula-volumetric> | Advanced volumetric nebula | | CloudLayerComponent | <a3d-cloud-layer> | Cloud layer effect |

Example:

<a3d-scene-3d [cameraPosition]="[0, 0, 10]">
  <a3d-star-field [count]="5000" [radius]="50" />
  <a3d-planet [radius]="2" [textureUrl]="'assets/earth.jpg'" [hasAtmosphere]="true" />
  <a3d-nebula [position]="[-10, 0, -20]" [color]="'#9b59b6'" />
</a3d-scene-3d>

Particle Systems

| Component | Selector | Description | | ----------------------------- | ------------------------------ | ------------------------------- | | ParticleSystemComponent | <a3d-particle-system> | Configurable particle effects | | MarbleParticleSystemComponent | <a3d-marble-particle-system> | Marble-styled particles | | GpuParticleSphereComponent | <a3d-gpu-particle-sphere> | GPU-accelerated particle sphere | | SparkleCoronaComponent | <a3d-sparkle-corona> | Sparkle/corona effect | | ParticleCloudComponent | <a3d-particle-cloud> | Particle cloud effect |


Visual Effects

| Component | Selector | Description | | ------------------------ | ------------------------ | ---------------------------------- | | MetaballSceneComponent | <a3d-metaball-scene> | Metaball container (compositional) | | MetaballSphereComponent | <a3d-metaball-sphere> | Individual metaball sphere | | MetaballCursorComponent | <a3d-metaball-cursor> | Cursor-following metaball | | MarbleSphereComponent | <a3d-marble-sphere> | Marble material sphere | | FireSphereComponent | <a3d-fire-sphere> | Fire/flame effect sphere | | BackgroundCubesComponent | <a3d-background-cubes> | Decorative background cubes | | ThrusterFlameComponent | <a3d-thruster-flame> | Thruster/rocket flame effect |

Note: MetaballComponent (<a3d-metaball>) is deprecated. Use the compositional API with MetaballSceneComponent, MetaballSphereComponent, and MetaballCursorComponent instead.


Backgrounds

| Component | Selector | Description | | ------------------------------------- | -------------------------------------- | ---------------------------------- | | HexagonalBackgroundInstancedComponent | <a3d-hexagonal-background-instanced> | GPU-instanced hexagonal background |


Scene Organization

| Component | Selector | Description | | ----------------------- | ----------------------- | ------------------------------- | | GroupComponent | <a3d-group> | Object3D container for grouping | | FogComponent | <a3d-fog> | Scene fog effect | | EnvironmentComponent | <a3d-environment> | Environment mapping | | BackgroundCubeComponent | <a3d-background-cube> | Skybox background | | InstancedMeshComponent | <a3d-instanced-mesh> | Instanced mesh rendering |

Example - Grouping objects:

<a3d-scene-3d>
  <a3d-group [position]="[0, 2, 0]" rotate3d>
    <a3d-box [position]="[-1, 0, 0]" />
    <a3d-sphere [position]="[1, 0, 0]" />
  </a3d-group>
</a3d-scene-3d>

Loaders

| Component | Selector | Description | | ------------------ | ------------------ | ------------------------- | | GltfModelComponent | <a3d-gltf-model> | GLTF/GLB model loader | | SvgIconComponent | <a3d-svg-icon> | SVG extruded as 3D object |

Example - Loading GLTF model:

<a3d-gltf-model [modelUrl]="'assets/models/spaceship.glb'" [scale]="0.5" [position]="[0, 0, 0]" [autoRotate]="true" />

Postprocessing Effects

| Component | Selector | Description | | ---------------------------------- | ----------------------------------- | ------------------------------ | | EffectComposerComponent | <a3d-effect-composer> | Postprocessing container | | BloomEffectComponent | <a3d-bloom-effect> | Bloom/glow effect | | SelectiveBloomEffectComponent | <a3d-selective-bloom-effect> | Selective bloom with luminance | | DofEffectComponent | <a3d-dof-effect> | Depth of field | | SsaoEffectComponent | <a3d-ssao-effect> | Screen-space ambient occlusion | | ColorGradingEffectComponent | <a3d-color-grading-effect> | LUT-based color grading | | ChromaticAberrationEffectComponent | <a3d-chromatic-aberration-effect> | Chromatic aberration | | FilmGrainEffectComponent | <a3d-film-grain-effect> | Film grain effect |

Example - Adding bloom:

<a3d-scene-3d>
  <a3d-effect-composer>
    <a3d-bloom-effect [strength]="1.5" [radius]="0.8" [threshold]="0.1" />
  </a3d-effect-composer>

  <a3d-sphere [color]="'#00ffff'" [emissiveIntensity]="1.0" />
</a3d-scene-3d>

🎮 Controls

OrbitControlsComponent

Interactive camera controls with mouse/touch support.

Selector: <a3d-orbit-controls>

Inputs:

  • enableDamping?: boolean - Enable smooth damping (default: true)
  • dampingFactor?: number - Damping inertia (default: 0.05)
  • enableZoom?: boolean - Enable zoom (default: true)
  • minDistance?: number - Minimum zoom distance
  • maxDistance?: number - Maximum zoom distance
  • target?: [number, number, number] - Orbit target point

Example:

<a3d-scene-3d>
  <a3d-orbit-controls [enableDamping]="true" [minDistance]="2" [maxDistance]="10" />
  <a3d-box />
</a3d-scene-3d>

🌊 Animation Directives

Float3dDirective

Adds smooth floating/bobbing animation.

Selector: [float3d]

Inputs:

  • floatHeight?: number - Float distance (default: 0.3)
  • floatSpeed?: number - Animation speed (default: 1.5)

Example:

<a3d-sphere float3d [floatHeight]="0.5" [floatSpeed]="2.0" />

Rotate3dDirective

Continuous rotation animation.

Selector: [rotate3d]

Inputs:

  • rotateSpeed?: [number, number, number] - Rotation speed per axis (default: [0, 1, 0])

Example:

<a3d-box rotate3d [rotateSpeed]="[0.5, 1, 0]" />

SpaceFlight3dDirective

Waypoint-based flight animation for spaceship-like movement.

Selector: [a3dSpaceFlight3d]

Inputs:

  • waypoints?: Array<{ position: [number, number, number]; rotation?: [number, number, number] }>
  • speed?: number - Flight speed
  • loop?: boolean - Loop through waypoints

CameraFlightDirective

Hold-to-fly camera navigation between predefined waypoints. Coordinates with OrbitControls to disable during flight and sync target after arrival. Uses GSAP for smooth camera animation with pause/resume capability.

Selector: [a3dCameraFlight]

Inputs:

| Input | Type | Default | Description | | --------------------- | ------------------ | ---------- | ------------------------------------------------- | | waypoints | CameraWaypoint[] | (required) | Array of waypoints defining the flight path | | enabled | boolean | true | Enable/disable flight controls | | holdButton | number | 0 | Mouse button for forward flight (0=left, 2=right) | | backwardKey | string | 'KeyQ' | Key code for backward navigation | | startIndex | number | 0 | Starting waypoint index | | controlsEnableDelay | number | 300 | Delay (ms) before re-enabling OrbitControls |

Outputs:

| Output | Type | Description | | ----------------------- | ------------------------- | ------------------------------------------- | | flightStart | void | Emitted when flight begins | | flightEnd | void | Emitted when flight ends (waypoint reached) | | waypointReached | WaypointReachedEvent | Emitted when camera arrives at a waypoint | | progressChange | FlightProgressEvent | Emitted during flight with progress (0-1) | | navigationStateChange | WaypointNavigationState | Emitted when navigation state changes |

CameraWaypoint Interface:

interface CameraWaypoint {
  id: string; // Unique identifier
  position: [number, number, number]; // Camera position [x, y, z]
  lookAt: [number, number, number]; // Camera look-at target [x, y, z]
  duration?: number; // Flight duration in seconds (default: 2)
  ease?: string; // GSAP easing function (default: 'power2.inOut')
  fov?: number; // Optional FOV override for zoom effects
}

Example - Basic camera flight:

@Component({
  template: `
    <a3d-scene-3d>
      <a3d-orbit-controls a3dCameraFlight [waypoints]="waypoints" (controlsReady)="onControlsReady($event)" (waypointReached)="onWaypointReached($event)" (flightStart)="isFlying.set(true)" (flightEnd)="isFlying.set(false)" />
    </a3d-scene-3d>
  `,
})
export class HeroComponent {
  @ViewChild(CameraFlightDirective) flightDirective!: CameraFlightDirective;

  waypoints: CameraWaypoint[] = [
    { id: 'start', position: [0, 0, 16], lookAt: [0, 0, 0] },
    { id: 'destination', position: [-15, 3, 8], lookAt: [-20, 2, -5], duration: 2.5 },
  ];

  isFlying = signal(false);

  onControlsReady(controls: OrbitControls): void {
    this.flightDirective.setOrbitControls(controls);
  }

  onWaypointReached(event: WaypointReachedEvent): void {
    console.log(`Arrived at: ${event.waypoint.id}`);
  }
}

Features:

  • Hold-to-fly forward navigation (configurable mouse button)
  • Key-press backward navigation (Q key by default)
  • Pause/resume flight on mouse release/hold
  • Quaternion-based camera rotation (prevents gimbal lock flipping)
  • OrbitControls coordination (disable during flight, sync target after)
  • Progress events for driving visual effects (warp lines, speed effects)
  • Reduced motion support (instant jumps instead of animated flight)

ObjectFlightDirective

Waypoint-based object animation for 3D objects. Mirrors the CameraFlightDirective API for consistency, but animates Object3D instances instead of the camera.

Selector: [a3dObjectFlight]

Inputs:

| Input | Type | Default | Description | | ----------------- | ------------------ | ---------------- | ------------------------------------------- | | waypoints | ObjectWaypoint[] | (required) | Array of waypoints defining the flight path | | enabled | boolean | true | Enable/disable flight controls | | startIndex | number | 0 | Starting waypoint index | | defaultDuration | number | 1.5 | Default duration for waypoints | | defaultEase | string | 'power2.inOut' | Default easing function | | autoPlay | boolean | false | Auto-play through all waypoints on init | | loop | boolean | false | Loop back to start after last waypoint |

Outputs:

| Output | Type | Description | | ----------------------- | ---------------------------- | ----------------------------------------- | | flightStart | void | Emitted when flight begins | | flightEnd | void | Emitted when flight ends | | waypointReached | ObjectWaypointReachedEvent | Emitted when object arrives at a waypoint | | progressChange | ObjectFlightProgressEvent | Emitted during flight with progress (0-1) | | navigationStateChange | ObjectFlightState | Emitted when navigation state changes |

ObjectWaypoint Interface:

interface ObjectWaypoint {
  id: string; // Unique identifier
  position: [number, number, number]; // Object position [x, y, z]
  rotation?: [number, number, number]; // Optional rotation [x, y, z] in radians
  scale?: [number, number, number] | number; // Optional scale
  duration?: number; // Flight duration in seconds
  ease?: string; // GSAP easing function
}

Example - Animated object with waypoints:

@Component({
  template: `
    <a3d-scene-3d>
      <a3d-sphere #sphere a3dObjectFlight [waypoints]="objectWaypoints" [defaultDuration]="1.5" (waypointReached)="onObjectWaypointReached($event)" (progressChange)="onProgressChange($event)" />
    </a3d-scene-3d>
  `,
})
export class AnimatedObjectComponent {
  @ViewChild('sphere', { read: ObjectFlightDirective })
  objectFlight!: ObjectFlightDirective;

  objectWaypoints: ObjectWaypoint[] = [
    { id: 'start', position: [0, 0, 0] },
    { id: 'center', position: [5, 2, 0], duration: 2, scale: 1.5 },
    { id: 'end', position: [10, 0, 0], duration: 1.5, ease: 'power3.out' },
  ];

  flyToNext(): void {
    this.objectFlight.flyNext();
  }

  flyToPrevious(): void {
    this.objectFlight.flyPrevious();
  }
}

Public Methods:

| Method | Description | | ---------------------- | ------------------------------------------- | | flyNext() | Fly to next waypoint | | flyPrevious() | Fly to previous waypoint | | flyToWaypoint(idx) | Fly to a specific waypoint index | | jumpToWaypoint(idx) | Instantly jump to a waypoint (no animation) | | pauseFlight() | Pause the current flight animation | | resumeFlight() | Resume a paused flight animation | | getNavigationState() | Get current navigation state snapshot |

Features:

  • Sequential waypoint navigation with forward/backward support
  • Position, rotation, and scale animation per waypoint
  • Configurable duration and easing per waypoint
  • Progress events for driving visual effects
  • Auto-play and loop modes
  • Reduced motion support

CameraShakeDirective

Configurable camera shake effects for impacts, transitions, and dynamic scenes. Provides organic, multi-layered shake with configurable intensity, frequency, and decay.

Selector: [a3dCameraShake]

Inputs:

| Input | Type | Default | Description | | ---------------- | --------- | ------- | ---------------------------------------------- | | shakeEnabled | boolean | false | Enable/disable shake via input binding | | shakeIntensity | number | 0.05 | Shake intensity in scene units | | shakeFrequency | number | 10 | Oscillation frequency (higher = faster) | | shakeDecay | number | 0 | Decay rate per second (0 = no decay) | | shakeMaxX | number | - | Max offset in X axis (default: intensity) | | shakeMaxY | number | - | Max offset in Y axis (default: intensity*0.8) | | shakeMaxZ | number | 0 | Max offset in Z axis |

Outputs:

| Output | Type | Description | | ------------- | ------------------ | -------------------------------- | | shakeChange | CameraShakeEvent | Emitted when shake state changes |

CameraShakeEvent Interface:

interface CameraShakeEvent {
  isShaking: boolean; // Whether shake is active
  currentIntensity: number; // Current intensity (may decay)
  elapsedTime: number; // Seconds since shake started
}

Example - Input-controlled shake:

<div a3dCameraShake [shakeEnabled]="isFlying()" [shakeIntensity]="0.08" [shakeFrequency]="12" />

Example - Programmatic control:

@Component({
  template: `
    <a3d-scene-3d>
      <div #shaker a3dCameraShake />
      <!-- Scene content -->
    </a3d-scene-3d>
  `,
})
export class ImpactSceneComponent {
  @ViewChild('shaker', { read: CameraShakeDirective })
  cameraShake!: CameraShakeDirective;

  // One-shot impact shake
  onImpact(): void {
    this.cameraShake.triggerShake({
      duration: 0.3,
      intensity: 0.12,
      fadeOut: true,
    });
  }

  // Continuous shake
  startRumble(): void {
    this.cameraShake.startShake({ intensity: 0.05, frequency: 8 });
  }

  stopRumble(): void {
    this.cameraShake.stopShake();
  }
}

Public Methods:

| Method | Description | | ----------------------- | --------------------------------------------- | | startShake(config?) | Start continuous shake with optional config | | stopShake() | Stop shake and restore camera position | | triggerShake(options) | One-shot shake that auto-stops after duration | | getIsShaking() | Get current shake state |

ShakeTriggerOptions:

interface ShakeTriggerOptions {
  duration: number; // Shake duration in seconds (required)
  intensity?: number; // Override intensity
  frequency?: number; // Override frequency
  fadeOut?: boolean; // Fade to zero over duration (default: true)
}

Features:

  • Multi-layered sine wave shake for organic feel
  • One-shot triggers with automatic fadeout
  • Continuous shake with manual control
  • Per-axis intensity control (X, Y, Z)
  • Automatic camera position restoration
  • Integrates with demand-based rendering

🎯 Interaction Directives

MouseTracking3dDirective

Makes objects follow mouse movement.

Selector: [mouseTracking3d]

Inputs:

  • trackingSpeed?: number - Response speed (default: 0.1)
  • trackingRange?: number - Movement range (default: 1.0)

Example:

<a3d-sphere mouseTracking3d [trackingSpeed]="0.2" />

🎬 Scene Loading & Entrance Animations

Orchestrate professional scene loading experiences with asset preloading and cinematic camera entrances.

Overview

The Scene Loading & Entrance Animation System provides:

  • Asset Preloading - Load GLTF models and textures with unified progress tracking
  • Cinematic Camera Entrances - 4 preset camera animations (dolly-in, orbit-drift, crane-up, fade-drift)
  • Object Reveal Animations - 3 reveal effects (fade-in, scale-pop, rise-up)
  • Stagger Group Coordination - Cascade reveal effects across multiple objects

Quick Start

import { Component, inject } from '@angular/core';
import { Scene3dComponent, OrbitControlsComponent, BoxComponent, SphereComponent, AssetPreloaderService, StaggerGroupService, CinematicEntranceDirective, SceneRevealDirective, type CinematicEntranceConfig } from '@hive-academy/angular-3d';

@Component({
  selector: 'app-hero-scene',
  standalone: true,
  imports: [Scene3dComponent, OrbitControlsComponent, BoxComponent, SphereComponent, CinematicEntranceDirective, SceneRevealDirective],
  template: `
    <a3d-scene-3d [cameraPosition]="[0, 2, 8]">
      <a3d-orbit-controls a3dCinematicEntrance [entranceConfig]="entranceConfig" (entranceComplete)="onEntranceComplete()" />

      <a3d-box a3dSceneReveal [revealConfig]="{ animation: 'scale-pop', staggerGroup: 'items', staggerIndex: 0 }" [position]="[-2, 0, 0]" [color]="'#ff6b6b'" />

      <a3d-sphere a3dSceneReveal [revealConfig]="{ animation: 'scale-pop', staggerGroup: 'items', staggerIndex: 1 }" [position]="[2, 0, 0]" [color]="'#4ecdc4'" />
    </a3d-scene-3d>

    @if (!preloadState.isReady()) {
    <div class="loading">Loading: {{ preloadState.progress() }}%</div>
    }
  `,
})
export class HeroSceneComponent {
  private preloader = inject(AssetPreloaderService);
  private stagger = inject(StaggerGroupService);

  // Preload assets (optional - for heavy scenes)
  preloadState = this.preloader.preload([
    { url: '/assets/model.glb', type: 'gltf', weight: 3 },
    { url: '/assets/texture.jpg', type: 'texture' },
  ]);

  entranceConfig: CinematicEntranceConfig = {
    preset: 'dolly-in',
    duration: 2.5,
    preloadState: this.preloadState,
  };

  async onEntranceComplete(): Promise<void> {
    await this.stagger.revealGroup('items', 150);
  }
}

AssetPreloaderService

Coordinates loading of multiple assets with unified progress tracking.

Methods:

| Method | Description | | --------------------------- | -------------------------------------------- | | preload(assets) | Load multiple assets, returns PreloadState | | getActiveOperationCount() | Get number of active preload operations |

AssetDefinition:

| Property | Type | Description | | ---------- | ----------- | ---------------------------------------------------- | | url | string | URL of the asset to load | | type | AssetType | 'gltf', 'texture', or 'hdri' | | weight? | number | Weight for progress calculation (default: 1) | | options? | object | Loader options (e.g., { useDraco: true } for GLTF) |

PreloadState (reactive signals):

| Signal | Type | Description | | ------------- | ----------------- | ----------------------------------- | | progress | Signal<number> | Combined progress (0-100) | | isReady | Signal<boolean> | True when all assets loaded | | errors | Signal<Error[]> | Array of loading errors | | loadedCount | Signal<number> | Count of successfully loaded assets | | totalCount | Signal<number> | Total number of assets | | cancel | () => void | Cancel loading operation |


CinematicEntranceDirective

Applies cinematic camera entrance animations with preset patterns.

Selector: [a3dCinematicEntrance]

Inputs:

| Input | Type | Description | | ---------------- | ------------------------- | ----------------------- | | entranceConfig | CinematicEntranceConfig | Animation configuration |

Outputs:

| Output | Type | Description | | ------------------ | ------ | -------------------------------- | | entranceStart | void | Emitted when animation starts | | entranceComplete | void | Emitted when animation completes |

CinematicEntranceConfig:

| Property | Type | Default | Description | | ---------------- | ---------------- | ---------------- | ------------------------------- | | preset? | EntrancePreset | subtle dolly-in | Animation preset | | duration? | number | 2.5 | Duration in seconds | | startPosition? | [x, y, z] | (from preset) | Override start camera position | | endPosition? | [x, y, z] | (current camera) | Override end camera position | | startLookAt? | [x, y, z] | (from preset) | Override start look-at target | | endLookAt? | [x, y, z] | [0, 0, 0] | Override end look-at target | | easing? | string | 'power2.inOut' | GSAP easing function | | delay? | number | 0 | Delay before animation starts | | autoStart? | boolean | true | Auto-start when ready | | preloadState? | PreloadState | - | Wait for assets before starting |

Available Presets (EntrancePreset):

| Preset | Description | | --------------- | ------------------------------------------------ | | 'dolly-in' | Camera moves forward along Z-axis toward scene | | 'orbit-drift' | Camera drifts from offset position (right/above) | | 'crane-up' | Camera rises from below, like a crane shot | | 'fade-drift' | Gentle horizontal drift from the left |

Example - Custom positions:

<a3d-orbit-controls
  a3dCinematicEntrance
  [entranceConfig]="{
    startPosition: [10, 5, 15],
    endPosition: [0, 2, 8],
    startLookAt: [0, -2, 0],
    endLookAt: [0, 0, 0],
    duration: 3,
    easing: 'power3.out'
  }"
/>

SceneRevealDirective

Adds reveal animations to 3D objects with stagger group coordination.

Selector: [a3dSceneReveal]

Inputs:

| Input | Type | Description | | -------------- | ------------------- | ----------------------- | | revealConfig | SceneRevealConfig | Animation configuration |

Outputs:

| Output | Type | Description | | ---------------- | ------ | ----------------------------- | | revealStart | void | Emitted when reveal starts | | revealComplete | void | Emitted when reveal completes |

SceneRevealConfig:

| Property | Type | Default | Description | | --------------- | ----------------- | -------------- | ------------------------------------- | | animation? | RevealAnimation | 'fade-in' | Animation type | | duration? | number | 0.8 | Duration in seconds | | delay? | number | 0 | Delay before animation | | easing? | string | 'power2.out' | GSAP easing (scale-pop uses back.out) | | staggerGroup? | string | - | Group name for stagger coordination | | staggerIndex? | number | 0 | Index within stagger group | | autoReveal? | boolean | false | Auto-reveal on init |

Available Animations (RevealAnimation):

| Animation | Description | | ------------- | -------------------------------------------- | | 'fade-in' | Material opacity animates from 0 to original | | 'scale-pop' | Scale from near-zero with overshoot effect | | 'rise-up' | Position animates upward from below |

Example - Mixed animations:

<a3d-box a3dSceneReveal [revealConfig]="{ animation: 'fade-in', staggerGroup: 'items', staggerIndex: 0 }" />

<a3d-sphere a3dSceneReveal [revealConfig]="{ animation: 'scale-pop', staggerGroup: 'items', staggerIndex: 1 }" />

<a3d-torus a3dSceneReveal [revealConfig]="{ animation: 'rise-up', staggerGroup: 'items', staggerIndex: 2 }" />

StaggerGroupService

Coordinates reveal animations across multiple SceneRevealDirective instances.

Methods:

| Method | Description | | --------------------------- | -------------------------------------------- | | revealGroup(name, delay?) | Reveal all items in group with stagger delay | | hideGroup(name) | Hide all items in group simultaneously | | hasGroup(name) | Check if group exists and has items | | getGroupSize(name) | Get number of items in group | | getGroupNames() | Get array of all group names | | clearGroup(name) | Clear all items from a group | | clearAllGroups() | Clear all groups |

Example - Programmatic control:

private stagger = inject(StaggerGroupService);

// Reveal with 150ms stagger delay (default)
await this.stagger.revealGroup('hero-items');

// Reveal with custom 200ms stagger
await this.stagger.revealGroup('hero-items', 200);

// Reveal all at once (no stagger)
await this.stagger.revealGroup('hero-items', 0);

// Hide all items for re-reveal
await this.stagger.hideGroup('hero-items');

LoadingOverlayComponent

Pre-styled loading overlay that displays during scene initialization and asset loading.

Selector: <a3d-loading-overlay>

Inputs:

| Input | Type | Description | | ---------- | ---------------------- | -------------------------------------- | | progress | Signal<number> | Loading progress signal (0-100) | | isReady | Signal<boolean> | Ready state signal (triggers fade-out) | | config? | LoadingOverlayConfig | Optional visual customization |

LoadingOverlayConfig:

| Property | Type | Default | Description | | ----------------- | --------- | ----------- | ---------------------------- | | fadeOutDuration | number | 800 | Fade-out duration in ms | | fadeOutDelay | number | 200 | Delay before fade-out starts | | showProgress | boolean | true | Show progress percentage | | showSpinner | boolean | true | Show animated spinner | | spinnerColor | string | '#ff6600' | Spinner accent color | | backgroundColor | string | '#0a0a0f' | Overlay background color | | zIndex | number | 9999 | CSS z-index |

Example - Basic usage with preload state:

<a3d-scene-3d [cameraPosition]="[0, 2, 8]">
  <!-- 3D content -->
</a3d-scene-3d>

<a3d-loading-overlay [progress]="preloadState.progress" [isReady]="preloadState.isReady" />

Example - Custom styling:

<a3d-loading-overlay
  [progress]="preloadState.progress"
  [isReady]="preloadState.isReady"
  [config]="{
    spinnerColor: '#00ff88',
    backgroundColor: '#1a1a2e',
    fadeOutDuration: 500
  }"
/>

Features:

  • Animated spinner with pulsing glow effect
  • Smooth progress text updates
  • Respects prefers-reduced-motion media query
  • Automatic fade-out when isReady becomes true
  • Removes itself from DOM after fade-out completes

ScrollZoomCoordinatorDirective

Coordinates camera zoom with page scroll.

Selector: [a3dScrollZoomCoordinator]

Inputs:

  • zoomRange?: [number, number] - Min/max zoom distance
  • scrollSensitivity?: number - Scroll response sensitivity

Performance3dDirective

Automatic LOD (Level of Detail) and performance optimization.

Selector: [a3dPerformance3d]

Inputs:

  • targetFps?: number - Target frame rate (default: 60)
  • enableLod?: boolean - Enable LOD switching

📋 Directives Reference

Core Directives

| Directive | Selector | Description | | ------------------ | ---------------- | ------------------------------- | | MeshDirective | [a3dMesh] | Creates a Three.js Mesh | | GroupDirective | [a3dGroup] | Creates a Three.js Group | | TransformDirective | [a3dTransform] | Applies position/rotation/scale |

Geometry Directives

| Directive | Selector | Description | | --------------------------- | ------------------------- | -------------------------- | | BoxGeometryDirective | [a3dBoxGeometry] | Creates BoxGeometry | | SphereGeometryDirective | [a3dSphereGeometry] | Creates SphereGeometry | | CylinderGeometryDirective | [a3dCylinderGeometry] | Creates CylinderGeometry | | TorusGeometryDirective | [a3dTorusGeometry] | Creates TorusGeometry | | PolyhedronGeometryDirective | [a3dPolyhedronGeometry] | Creates PolyhedronGeometry |

Material Directives

| Directive | Selector | Description | | ------------------------- | ----------------------- | --------------------------------- | | StandardMaterialDirective | [a3dStandardMaterial] | Creates MeshStandardMaterial | | PhysicalMaterialDirective | [a3dPhysicalMaterial] | Creates MeshPhysicalMaterial | | NodeMaterialDirective | [a3dNodeMaterial] | Creates TSL NodeMaterial (WebGPU) |

Light Directives

| Directive | Selector | Description | | ------------------------- | ----------------------- | ---------------------- | | LightDirective | [a3dLight] | Base light directive | | AmbientLightDirective | [a3dAmbientLight] | Adds ambient light | | PointLightDirective | [a3dPointLight] | Adds point light | | DirectionalLightDirective | [a3dDirectionalLight] | Adds directional light | | SpotLightDirective | [a3dSpotLight] | Adds spot light |

Effect Directives

| Directive | Selector | Description | | --------------- | ------------- | ------------------------ | | Glow3dDirective | [a3dGlow3d] | Adds glow effect to mesh |

Positioning Directives

| Directive | Selector | Description | | ------------------------- | -------------------- | ---------------------------------------- | | ViewportPositionDirective | [viewportPosition] | Positions 3D object relative to viewport |


🔧 Services Reference

| Service | Description | | ----------------------------------- | --------------------------------------- | | SceneService | Access to scene, camera, renderer | | RenderLoopService | Frame loop management and callbacks | | AnimationService | Flight waypoints, pulse animations | | GltfLoaderService | GLTF/GLB model loading with caching | | TextureLoaderService | Texture loading with caching | | AssetPreloaderService | Multi-asset loading with progress | | StaggerGroupService | Coordinated reveal animations | | EffectComposerService | Postprocessing effect chain management | | ViewportPositioningService | Viewport-relative positioning utilities | | ComponentRegistryService | Component registration and lookup | | Angular3dStateStore | Signal-based application state | | SceneGraphStore | Scene graph node registry | | AdvancedPerformanceOptimizerService | Performance monitoring and optimization | | RenderCallbackRegistryService | Render callback management | | VisibilityObserverService | Intersection observer utilities | | FontPreloadService | Font preloading for text components |

Injectable Functions

| Function | Description | | --------------------- | ------------------------------------ | | injectGltfLoader() | Modern DI pattern for GLTF loader | | injectTextureLoader() | Modern DI pattern for texture loader |


⚙️ Configuration

Material Options

All mesh components support standard material properties:

<a3d-sphere [color]="'#ff6b6b'" [metalness]="0.8" [roughness]="0.2" [opacity]="0.9" [transparent]="true" [emissive]="'#ff0000'" [emissiveIntensity]="0.5" />

Custom Materials with TSL

Use NodeMaterialDirective for advanced node-based materials:

import { tslFresnel, tslIridescence } from '@hive-academy/angular-3d';

🌐 SSR Compatibility

The library automatically handles server-side rendering:

  • Three.js initializes only in browser environment
  • No hydration mismatches
  • Safe component lifecycle management
// ✅ Safe - library handles SSR internally
<a3d-scene-3d>
  <a3d-box />
</a3d-scene-3d>

// ✅ No additional guards needed
constructor() {
  // Library uses isPlatformBrowser() internally
}

🎬 Live Demo

https://hive-academy.github.io/angular-3d/


📖 Resources


🤝 Contributing

Contributions are welcome! Please read our Contributing Guide and follow the conventional commit format for all commits.

See CODE_OF_CONDUCT.md for community guidelines.


📄 License

MIT © Hive Academy

See LICENSE for details.


🔗 Related Packages