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

@evitcastudio/lens

v4.4.1

Published

A modular camera system for 2D games with specialized camera types (Follow, Spectate, Pan, Influence, Transition) and rich effects including shake, zoom, and seamless transitions.

Readme


Features

  • Specialized Camera Types:
    • FollowCamera: Smooth target tracking with customizable 3D offsets (x, y, z height) and deadzones.
    • SpectateCamera: Cinematic target spectating with instant snap or smooth easing.
    • PanCamera: Directed camera pans to positions or entities with configurable hold duration and auto pan-back.
    • InfluenceCamera: Multi-target weighted focus camera dynamically interpolating between multiple entities.
    • TransitionCamera: Seamless camera-to-camera or point-to-point blending with zero visual pop and live dynamic target tracking.
  • Screen Shake System: 29 built-in professionally calibrated shake presets plus fully customizable amplitude, frequency, decay curves, and multi-axis parameters.
  • Smooth Zoom & Easing: Independent X/Y zoom animations with 30+ easing equations (linear, easeOutCubic, easeInOutQuad, etc.).
  • Time Scale Awareness: Seamless integration with bullet-time / slow-motion mechanics, with flags to allow effects to ignore global game speed.
  • Debug Gizmos & Guides: Built-in PIXI debug visualization and crosshair alignment guides.
  • Autonomous or Manual Lifecycle: Run via internal requestAnimationFrame loop or step manually inside your game's render loop (cameraManager.update(elapsedMs)).

Installation

# Using bun
bun add @evitcastudio/lens

# Using npm
npm install @evitcastudio/lens

# Using yarn / pnpm
yarn add @evitcastudio/lens
pnpm add @evitcastudio/lens


Choosing Your Setup: Standalone vs. Kit

Lens is designed for games built with the Vylocity Game Engine:

  • Using the @evitcastudio/kit framework (>= 3.4.0)? You do not need to install @evitcastudio/lens directly! Lens is already bundled and prepackaged directly inside Kit as a built-in Camera plugin. You can access it immediately via Kit:

    import { Kit, Camera } from '@evitcastudio/kit';
    
    // Camera is already prepackaged in Kit (>= 3.4.0)
    const camera = Kit.getPlugin<Camera>('Camera');
    camera.shakePreset('explosion-large');
  • Standalone Vylocity (without Kit)? Install @evitcastudio/lens and instantiate CameraManager directly:

    import { CameraManager } from '@evitcastudio/lens';
    
    const cameraManager = new CameraManager();

Quickstart (Standalone CameraManager)

import { CameraManager } from '@evitcastudio/lens';

// Auto-starts internal RAF loop by default
const cameraManager = new CameraManager();

// Or for manual control in your own game loop:
// const cameraManager = new CameraManager({ autoStart: false });
// In your tick/render loop: cameraManager.update(elapsedMs);

1. Follow Camera (Main Player Tracking)

// Create and bind to player
const followCam = cameraManager.createFollowCamera();
cameraManager.setMainFollowCamera(followCam, player, { x: 0, y: 0, z: 0 }, true);

// Set smooth tracking transition settings
followCam.setSettings({
  duration: 400,
  ease: 'easeOutCubic'
});

2. Seamless Camera Transitions

Switch smoothly between cameras or targets with dynamic Hermite spline interpolation and spring-damping (zero visual pop):

// Seamlessly blend from current camera to a boss camera
await cameraManager.switchTo(bossCamera, {
  duration: 800,
  smoothing: 'smoothDamp', // or 'cubicSpline'
  springTension: 170,
  springFriction: 26
});

3. Screen Shake

// Trigger any of the 29 built-in presets
cameraManager.shakePreset('explosion-large');
cameraManager.shakePreset('gunshot');
cameraManager.shakePreset('handheld-soft', undefined, true); // infinite handheld camera

// Stop shaking
cameraManager.stopShake();

// Or define a custom shake
cameraManager.shake({
  strength: { x: 6, y: 6 },
  duration: { x: 350, y: 350 },
  vibrato: 15,
  curve: 0.5
});

4. Smooth Zoom

// Zoom in 2x over 500ms with easeOutCubic
cameraManager.zoom(2, 500, 'easeOutCubic');

// Different zoom per axis
cameraManager.zoom({ x: 1.5, y: 1.5 }, 300);

// Reset zoom
cameraManager.zoom(1, 400, 'easeInOutQuad');

5. Panning & Spectating

// Pan to a point of interest, pause for 1 second, then pan back to player
await cameraManager.panTo({ x: 1200, y: 800 }, {
  duration: 800,
  pauseDuration: 1000,
  panBack: true,
  ease: 'easeInOutCubic'
});

// Spectate another entity
await cameraManager.spectateTarget(bossEntity, {
  duration: 600,
  ease: 'easeOutQuad'
});

Camera Event System

The camera system emits lifecycle events across its lifecycle. When used with @evitcastudio/kit, all events are automatically dispatched through Kit's global event bus (Kit.on), allowing audio, gamepad rumble, or UI systems to decouple from the camera:

// Listen globally via Kit
Kit.on('Camera', 'shake-start', (event) => {
  console.log('Camera started shaking:', event.data.preset);
  // Example: trigger gamepad vibration
});

Kit.on('Camera', 'shake-end', () => {
  // Example: stop gamepad vibration
});

Kit.on('Camera', 'transition-start', (event) => {
  // Example: animate letterbox cinematic bars
});

Kit.on('Camera', 'transition-end', () => {
  // Example: restore gameplay HUD
});

Standalone users can also subscribe directly on CameraManager (or CameraPlugin):

const unsubscribe = cameraManager.on('view-eye-changed', ({ camera, previousCamera }) => {
  console.log('Active camera changed to:', camera.id);
});

// Later, unsubscribe:
unsubscribe();

Available Events

| Event | Trigger | Payload | | :--- | :--- | :--- | | shake-start | Shake effect begins | { preset, strength, duration, infinite, rotation } | | shake-end | Shake effect ends / stopped | { preset } | | zoom-start | Zoom animation begins | { destination, duration, ease } | | zoom-end | Zoom animation finishes | { zoom } | | transition-start | switchTo transition begins | { fromCamera, toCamera, duration } | | transition-end | switchTo transition finishes | { activeCamera } | | pan-start | Directed pan begins | { target, duration, panBack } | | pan-end | Directed pan completes | { target } | | spectate-start | Spectating starts | { target, duration } | | spectate-end | Spectating ends | { target } | | view-eye-changed | Active view eye changes | { previousCamera, camera, cameraType } |


Native Debug Overlay & Gizmos

Lens includes a built-in, lightweight 2D canvas overlay for debugging cameras and viewing spatial relationships with zero WebGL scene graph overhead.

// Enable debug overlay with full feature set
cameraManager.setDebugMode({
  enabled: true,
  canvas: '#gizmo-canvas', // or omit to auto-create an overlay
  showCameraMarkers: true,
  showTargetLines: true,
  showBounds: true,
  showCenterCrosshair: true,
  bounds: { minX: 50, maxX: 1230, minY: 50, maxY: 670 },
  // Optional custom render hook for game-specific badges, reticles, or nameplates
  onCustomRender: (ctx, worldToScreen, width, height) => {
    // Custom game rendering here
  }
});

// Or dynamically adjust options:
cameraManager.setDebugOptions({ showTargetLines: false });

Shake Presets

| Category | Presets | | :--- | :--- | | Combat & Explosions | gunshot, recoil, explosion-small, explosion-large, impact, impact-light, impact-heavy, crash | | Environmental | earthquake-soft, earthquake-hard, rumble, tremor, thunder, wind, wave | | Atmospheric & Camera | handheld-soft, handheld-hard, breathing, heartbeat, pulse, sway, dizzy, nervous, jitter, vibration | | Movement & Actions | footstep, landing, door-slam, bounce |


License

MIT © Evitca Studio & doubleactii