New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

posev

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

posev

Professional-grade, framework-agnostic biomechanical animation SDK for sports analytics, rehabilitation apps, and motion capture systems

latest
Source
npmnpm
Version
1.1.0
Version published
Maintainers
1
Created
Source

PoseV — Enterprise Biomechanical Animation SDK

Professional-grade, framework-agnostic biomechanical animation engine for sports analytics, rehabilitation apps, and motion capture systems.

Status Version License Bundle Size Tests

Table of Contents

  • Installation
  • Quick Start
  • Core Features
  • Framework Integration
  • API Reference
  • Plugin Guide
  • Movement JSON Standard
  • Rig System
  • Performance & Production
  • Examples
  • Contributing

Installation

Via npm

npm install posev

Via CDN (UMD)

<script src="https://cdn.jsdelivr.net/npm/posev@1.0.0/dist/posev.umd.min.js"></script>
<script>
  const { PoseVCore } = window.PoseV;
</script>

Verify Installation

npm list posev

Quick Start

Basic Animation (Vanilla JavaScript)

import { PoseVCore } from 'posev';

// 1. Create engine
const engine = new PoseVCore({
  debug: true,
  strictValidation: true,
});

// 2. Load movement data
await engine.load({
  movement: './movements/squat.json',
  rig: './rigs/standard-human.json',
});

// 3. Play animation
engine.play();

// 4. Listen to frame updates
engine.on('frameUpdate', (frame) => {
  console.log(`Progress: ${(frame.progress * 100).toFixed(1)}%`);
  console.log(`Current time: ${frame.currentTime.toFixed(2)}ms`);
  
  // Update your UI or renderer here
  renderPose(frame.pose);
});

// 5. Control playback
engine.pause();
engine.seek(0.5); // Seek to 50%
engine.setSpeed(0.5); // Slow motion
engine.play();

// Cleanup
engine.dispose();

Vue 3 Integration

<template>
  <div class="posev-container">
    <canvas ref="canvas" width="800" height="600"></canvas>
    
    <div class="controls">
      <button @click="togglePlayPause">
        {{ isPlaying ? 'Pause' : 'Play' }}
      </button>
      <input
        type="range"
        min="0"
        max="1"
        :value="progress"
        @input="seek"
      />
      <span>{{ formatTime(currentTime) }} / {{ formatTime(duration) }}</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { usePoseV } from 'posev';

const canvas = ref<HTMLCanvasElement>();
const { play, pause, seek, getState } = usePoseV({
  movement: './movements/squat.json',
  rig: './rigs/standard-human.json',
  renderer: {
    canvas: canvas.value,
    width: 800,
    height: 600,
  },
  autoplay: true,
});

const state = computed(() => getState());
const isPlaying = computed(() => state.value?.playback === 'playing');
const progress = computed(() => state.value?.progress ?? 0);
const currentTime = computed(() => state.value?.currentTime ?? 0);
const duration = computed(() => state.value?.duration ?? 0);

const togglePlayPause = () => {
  isPlaying.value ? pause() : play();
};

const formatTime = (ms: number) => {
  const seconds = (ms / 1000).toFixed(2);
  return seconds;
};
</script>

<style scoped>
.posev-container {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
</style>

React Integration

import { useEffect, useRef, useState } from 'react';
import { PoseVCore, PerformanceMonitor, ResourceManager } from 'posev';

export function PoseVPlayer({ movementUrl, rigUrl }) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const engineRef = useRef<PoseVCore | null>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [progress, setProgress] = useState(0);
  const [duration, setDuration] = useState(0);

  useEffect(() => {
    const perfMonitor = new PerformanceMonitor();
    const resourceMgr = new ResourceManager();

    const engine = new PoseVCore({
      renderer: {
        canvas: canvasRef.current!,
        type: 'canvas2d',
      },
      perfMonitor,
      resourceMgr,
    });

    engineRef.current = engine;

    engine.load({ movement: movementUrl, rig: rigUrl }).then(() => {
      setDuration(engine.getTimeline()?.duration ?? 0);
      engine.on('frameUpdate', (frame) => {
        setProgress(frame.progress);
      });
    });

    return () => {
      engine.dispose();
      resourceMgr.cleanup();
    };
  }, [movementUrl, rigUrl]);

  const togglePlayPause = () => {
    if (isPlaying) {
      engineRef.current?.pause();
    } else {
      engineRef.current?.play();
    }
    setIsPlaying(!isPlaying);
  };

  const handleSeek = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newProgress = parseFloat(e.target.value);
    engineRef.current?.seek(newProgress);
  };

  return (
    <div>
      <canvas ref={canvasRef} width={800} height={600} />
      <div>
        <button onClick={togglePlayPause}>
          {isPlaying ? 'Pause' : 'Play'}
        </button>
        <input
          type="range"
          min="0"
          max="1"
          step="0.01"
          value={progress}
          onChange={handleSeek}
        />
        <span>{(progress * 100).toFixed(1)}%</span>
      </div>
    </div>
  );
}

Core Features

🎬 Animation Engine

  • Keyframe-based animation with interpolation
  • Multiple easing modes (linear, cubic, ease-in, ease-out)
  • Speed control (0.1x to 3x)
  • Precise seeking and time scrubbing
  • Frame-accurate playback

🦴 Skeletal Rig System

  • Predefined humanoid rigs (standard, compact, custom)
  • Joint hierarchy validation
  • Bone length and angle constraints
  • Forward kinematics support
  • Ancestor/descendant queries

🔌 Plugin Architecture

  • Event-based plugin system
  • Plugin lifecycle (install, activate, deactivate, uninstall)
  • Access to engine internals via context
  • Error recovery and fallback support
  • Built-in plugins: gait analysis, pose detection, motion capture

📊 Biomechanical Validation

  • JSON schema validation
  • Bone length variance checking
  • Angle constraint enforcement
  • Duration and timing validation
  • Comprehensive error catalog

🎨 Rendering

  • Canvas 2D renderer (default)
  • WebGL renderer (high-performance)
  • Custom renderer support
  • Debug visualization mode
  • Performance profiling

📱 Mobile Optimized

  • <15 KB gzipped delivery
  • Conservative performance budgets
  • Battery-aware frame rate targeting
  • Memory leak prevention
  • Resource lifecycle management

Framework Integration

Vue 3 Composition API

Full Composition API support with lifecycle management:

import { usePoseV } from 'posev';
import { ref, onMounted } from 'vue';

const { play, pause, seek, getState } = usePoseV({
  movement: 'squat.json',
  rig: 'standard-human.json',
  autoplay: true,
  debug: false,
});

onMounted(() => {
  play();
});

See Vue Integration Guide for details.

React Hooks (Coming Soon)

const { play, pause, seek } = usePoseV(config);

Vanilla JavaScript

Works with any framework:

const engine = new PoseVCore(config);
await engine.load(manifest);
engine.play();

API Reference

PoseVCore

Main animation engine class.

Constructor

new PoseVCore(config?: PoseVCoreConfig)

Config Options:

interface PoseVCoreConfig {
  // Validation
  strictValidation?: boolean;        // Default: false
  
  // Rendering
  renderer?: RendererConfig;         // Canvas/WebGL settings
  
  // Production Hardening
  errorHandler?: ErrorHandler;       // Custom error handler
  perfMonitor?: PerformanceMonitor;  // Performance tracking
  resourceMgr?: ResourceManager;     // Memory management
  
  // Debugging
  debug?: boolean;                   // Enable debug mode
  logger?: Logger;                   // Custom logger
}

Methods

// Asset Management
await engine.load(manifest: MovementManifest): Promise<void>
await engine.assets.preload(assets: AssetDef[]): Promise<void>

// Playback Control
engine.play(): void
engine.pause(): void
engine.stop(): void
engine.seek(progress: 0..1): void
engine.setSpeed(multiplier: number): void

// State Query
engine.getState(): PlaybackState
engine.getTimeline(): Timeline | null
engine.getPose(time?: number): Pose | null
engine.getProgress(): number
engine.getDuration(): number

// Events
engine.on(event: 'frameUpdate' | 'stateChange' | 'error', listener): Unsubscriber
engine.off(event, listener): void
engine.emit(event, data): void

// Lifecycle
engine.dispose(): void

Events

// Frame update - fires every animation frame
engine.on('frameUpdate', (frame: FrameData) => {
  // { currentTime, progress, pose, deltaTime }
});

// Playback state changed
engine.on('stateChange', (state: PlaybackState) => {
  // { timeline, playback, speed, progress }
});

// Error occurred
engine.on('error', (error: PoseVError) => {
  // { code, category, severity, message }
});

// Complete - animation finished
engine.on('complete', (stats: PlaybackStats) => {
  // { totalTime, frameCount, avgFps }
});

Timeline

Animation timeline with keyframes.

interface Timeline {
  movement: Movement;
  rig: Rig;
  keyframes: Keyframe[];
  duration: number;           // Total duration in ms
  fps: number;               // Frames per second
  interpolationMode: 'linear' | 'cubic';
  
  // Query methods
  getPoseAt(time: number): Pose;
  getKeyframeAt(time: number): Keyframe;
  getCurrentProgress(time: number): 0..1;
}

Pose

Skeletal pose data.

interface Pose {
  joints: Map<string, Vector3>;      // Joint positions
  bones?: Map<string, Vector3>;       // Bone vectors (optional)
  timestamp: number;
  
  getJoint(id: string): Vector3 | undefined;
  hasJoint(id: string): boolean;
}

Movement

Movement definition (loaded from JSON).

interface Movement {
  id: string;
  name: string;
  description?: string;
  duration: number;                  // in milliseconds
  fps: number;
  keyframes: KeyframeData[];
  
  // Validation
  validate(): ValidationResult;
  getKeyframeCount(): number;
  getDurationSeconds(): number;
}

Rig

Skeletal rig definition.

interface Rig {
  id: string;
  name: string;
  joints: JointDef[];
  bones: BoneDef[];
  
  // Query
  getJoint(id: string): JointDef | undefined;
  getParent(jointId: string): JointDef | undefined;
  getChildren(jointId: string): JointDef[];
  
  // Validation
  validate(): ValidationResult;
  validateBoneLengths(pose: Pose): BoneValidation;
  validateAngles(pose: Pose): AngleValidation;
}

interface JointDef {
  id: string;
  name: string;
  parent?: string;
  constraints?: AngleConstraint[];
}

interface BoneDef {
  id: string;
  from: string;
  to: string;
  minLength: number;
  maxLength: number;
  idealLength: number;
}

Plugin System

interface PoseVPlugin {
  // Metadata
  id: string;
  version: string;
  dependencies?: string[];
  
  // Lifecycle
  install?(context: PluginContext): Promise<void>;
  activate?(context: PluginContext): Promise<void>;
  deactivate?(): Promise<void>;
  uninstall?(): Promise<void>;
  
  // Optional hook
  onFrameUpdate?(frame: FrameData): void | Promise<void>;
  onStateChange?(state: PlaybackState): void | Promise<void>;
  onError?(error: PoseVError): boolean | Promise<boolean>; // Return true to suppress
}

interface PluginContext {
  engine: PoseVCore;
  timeline: Timeline;
  rig: Rig;
  renderer: Renderer;
  errorHandler: ErrorHandler;
  perfMonitor: PerformanceMonitor;
}

Plugin Guide

Writing a Simple Plugin

Create a gait analysis plugin:

import { PoseVPlugin, PluginContext, FrameData } from 'posev';

class GaitAnalysisPlugin implements PoseVPlugin {
  id = 'gait-analysis';
  version = '1.0.0';
  
  private context: PluginContext | null = null;
  private metrics = { stride: 0, cadence: 0, symmetry: 0 };
  
  async install(context: PluginContext) {
    this.context = context;
    console.log('GaitAnalysisPlugin installed');
  }
  
  async activate() {
    console.log('GaitAnalysisPlugin activated');
  }
  
  async deactivate() {
    console.log('GaitAnalysisPlugin deactivated');
  }
  
  onFrameUpdate(frame: FrameData) {
    // Analyze pose data
    const pose = frame.pose;
    
    // Calculate stride length
    const leftFoot = pose.getJoint('left_foot');
    const rightFoot = pose.getJoint('right_foot');
    
    if (leftFoot && rightFoot) {
      const distance = Math.hypot(
        rightFoot.x - leftFoot.x,
        rightFoot.z - leftFoot.z
      );
      this.metrics.stride = distance;
    }
    
    // Calculate cadence (steps per minute)
    this.metrics.cadence = (this.metrics.stride / frame.deltaTime) * 60;
    
    // Emit custom event or update UI
    this.context?.engine.emit('gait:metrics', this.metrics);
  }
  
  getMetrics() {
    return { ...this.metrics };
  }
}

// Usage
const plugin = new GaitAnalysisPlugin();
engine.plugins.install(plugin);

engine.on('gait:metrics', (metrics) => {
  console.log('Stride length:', metrics.stride.toFixed(2), 'cm');
  console.log('Cadence:', metrics.cadence.toFixed(1), 'steps/min');
});

Plugin with Dependencies

class AdvancedAnalysisPlugin implements PoseVPlugin {
  id = 'advanced-analysis';
  version = '1.0.0';
  dependencies = ['gait-analysis'];  // Requires GaitAnalysisPlugin
  
  async install(context: PluginContext) {
    // Install will fail if dependency not available
  }
}

Error Recovery in Plugins

class RobustPlugin implements PoseVPlugin {
  id = 'robust';
  version = '1.0.0';
  
  onFrameUpdate(frame: FrameData) {
    try {
      // Process frame
    } catch (error) {
      // Log but don't crash
      console.error('Plugin error:', error);
    }
  }
  
  // Return true to suppress error propagation
  onError(error: PoseVError) {
    if (error.code === 'P_5004') {
      // Handle specific error
      return true; // Suppress
    }
    return false; // Propagate
  }
}

Movement JSON Standard

Format Specification (v1.0.0)

{
  "version": "1.0.0",
  "metadata": {
    "id": "squat",
    "name": "Bodyweight Squat",
    "description": "Standard squat movement",
    "author": "Motion Capture Studio",
    "captureDate": "2024-11-23",
    "fps": 60,
    "duration": 2000,
    "units": "centimeters"
  },
  "rig": {
    "id": "standard-human",
    "version": "1.0.0"
  },
  "keyframes": [
    {
      "time": 0,
      "joints": {
        "root": { "x": 0, "y": 0, "z": 0 },
        "left_hip": { "x": -8, "y": 95, "z": 0 },
        "left_knee": { "x": -8, "y": 52, "z": 0 },
        "left_ankle": { "x": -8, "y": 2, "z": 0 },
        "right_hip": { "x": 8, "y": 95, "z": 0 },
        "right_knee": { "x": 8, "y": 52, "z": 0 },
        "right_ankle": { "x": 8, "y": 2, "z": 0 }
      }
    },
    {
      "time": 1000,
      "joints": {
        "root": { "x": 0, "y": 0, "z": 0 },
        "left_hip": { "x": -8, "y": 60, "z": 0 },
        "left_knee": { "x": -8, "y": 20, "z": 0 },
        "left_ankle": { "x": -8, "y": 2, "z": 0 },
        "right_hip": { "x": 8, "y": 60, "z": 0 },
        "right_knee": { "x": 8, "y": 20, "z": 0 },
        "right_ankle": { "x": 8, "y": 2, "z": 0 }
      }
    },
    {
      "time": 2000,
      "joints": {
        "root": { "x": 0, "y": 0, "z": 0 },
        "left_hip": { "x": -8, "y": 95, "z": 0 },
        "left_knee": { "x": -8, "y": 52, "z": 0 },
        "left_ankle": { "x": -8, "y": 2, "z": 0 },
        "right_hip": { "x": 8, "y": 95, "z": 0 },
        "right_knee": { "x": 8, "y": 52, "z": 0 },
        "right_ankle": { "x": 8, "y": 2, "z": 0 }
      }
    }
  ],
  "interpolation": "cubic",
  "loops": true,
  "tags": ["lower-body", "squat", "strength"]
}

Schema Requirements

interface MovementJSON {
  // Version and metadata
  version: '1.0.0';
  metadata: {
    id: string;                    // Unique identifier
    name: string;                  // Human-readable name
    description?: string;
    author?: string;
    captureDate?: string;
    
    fps: number;                   // Frame rate (30-120)
    duration: number;              // Total duration in ms
    units?: 'centimeters' | 'meters' | 'inches';
  };
  
  // Rig reference
  rig: {
    id: string;
    version: string;
  };
  
  // Keyframes (minimum 2)
  keyframes: Array<{
    time: number;                  // Time in ms (0 to duration)
    joints: {
      [jointId: string]: {         // One entry per joint in rig
        x: number;
        y: number;
        z: number;
      };
    };
  }>;
  
  // Animation settings
  interpolation?: 'linear' | 'cubic';  // Default: 'linear'
  loops?: boolean;                     // Default: true
  tags?: string[];                     // Categorization
}

Validation Rules

  • Time Values

    • First keyframe must be at time 0
    • Last keyframe must be at duration
    • Times must be monotonically increasing
    • No duplicate times
  • Joint Coverage

    • Every keyframe must have all rig joints
    • Extra joints are ignored
    • Missing joints cause validation error
  • Coordinate Ranges

    • Values typically -500 to +500 (units)
    • No NaN, Infinity, or undefined
    • Positive Z is forward, Y is up
  • Duration

    • Minimum: 100ms
    • Maximum: 300,000ms (5 minutes)
    • Recommended: 500ms - 30,000ms

Creating Movement Data

import { MovementValidator } from 'posev';

const movementData = {
  version: '1.0.0',
  metadata: {
    id: 'jump',
    name: 'Standing Jump',
    fps: 60,
    duration: 1200,
  },
  rig: { id: 'standard-human', version: '1.0.0' },
  keyframes: [
    { time: 0, joints: { /* ... */ } },
    { time: 600, joints: { /* ... */ } },
    { time: 1200, joints: { /* ... */ } },
  ],
};

// Validate before use
const validator = new MovementValidator();
const result = validator.validate(movementData);

if (result.valid) {
  console.log('✅ Movement data is valid');
} else {
  console.error('❌ Validation errors:', result.errors);
}

Rig System

Overview

A rig defines the skeletal structure and constraints for animations. PoseV ships with predefined humanoid rigs and supports custom rigs.

Standard Humanoid Rig (v1.0.0)

The default rig with 17 joints and 16 bones:

Root (pelvis)
├── Spine
│   └── Chest
│       ├── Left Shoulder
│       │   └── Left Arm
│       │       └── Left Forearm
│       │           └── Left Hand
│       └── Right Shoulder
│           └── Right Arm
│               └── Right Forearm
│                   └── Right Hand
├── Left Hip
│   └── Left Knee
│       └── Left Ankle
│           └── Left Foot
└── Right Hip
    └── Right Knee
        └── Right Ankle
            └── Right Foot

Joint IDs:

root, spine, chest,
left_shoulder, left_arm, left_forearm, left_hand,
right_shoulder, right_arm, right_forearm, right_hand,
left_hip, left_knee, left_ankle, left_foot,
right_hip, right_knee, right_ankle, right_foot

Using Built-in Rigs

import { StandardHumanRig, CompactHumanRig } from 'posev';

// Standard rig (17 joints, full detail)
const rig = new StandardHumanRig();

// Compact rig (11 joints, optimized)
const compactRig = new CompactHumanRig();

// Access rig data
const joints = rig.joints;
const bones = rig.bones;

// Query hierarchy
const parent = rig.getParent('left_knee'); // 'left_hip'
const children = rig.getChildren('spine');  // ['chest']

// Validation
const validation = rig.validate();
if (!validation.valid) {
  console.error(validation.errors);
}

Rig JSON Format

{
  "version": "1.0.0",
  "metadata": {
    "id": "standard-human",
    "name": "Standard Human Rig",
    "description": "Biomechanically accurate humanoid rig",
    "jointCount": 17
  },
  "joints": [
    {
      "id": "root",
      "name": "Root/Pelvis",
      "parent": null,
      "constraints": [
        {
          "axis": "x",
          "min": -30,
          "max": 30,
          "unit": "degrees"
        }
      ]
    },
    {
      "id": "left_knee",
      "name": "Left Knee",
      "parent": "left_hip",
      "constraints": [
        {
          "axis": "z",
          "min": 0,
          "max": 140,
          "unit": "degrees"
        }
      ]
    }
  ],
  "bones": [
    {
      "id": "left_femur",
      "from": "left_hip",
      "to": "left_knee",
      "minLength": 35,
      "maxLength": 55,
      "idealLength": 45,
      "unit": "centimeters"
    }
  ]
}

Creating a Custom Rig

import { Rig, JointDef, BoneDef } from 'posev';

const customRig = new Rig({
  id: 'quadruped',
  name: 'Four-Legged Animal',
  joints: [
    { id: 'root', name: 'Root', parent: null },
    { id: 'front_left_leg', name: 'Front Left Leg', parent: 'root' },
    { id: 'front_left_knee', name: 'Front Left Knee', parent: 'front_left_leg' },
    { id: 'front_left_foot', name: 'Front Left Foot', parent: 'front_left_knee' },
    // ... more joints
  ],
  bones: [
    {
      id: 'front_left_femur',
      from: 'front_left_leg',
      to: 'front_left_knee',
      minLength: 10,
      maxLength: 25,
      idealLength: 17,
    },
    // ... more bones
  ],
});

// Use with movement data
const movement = await engine.load({
  movement: './movements/walk.json',
  rig: customRig,
});

Rig Validation

const validation = rig.validate();

if (!validation.valid) {
  console.error('Rig errors:');
  validation.errors.forEach(error => {
    console.error(`  - ${error.joint}: ${error.message}`);
  });
}

// Validate specific pose
const poseValidation = rig.validateBoneLengths(pose);
if (!poseValidation.valid) {
  poseValidation.violations.forEach(v => {
    console.warn(`Bone ${v.bone} length ${v.actual}cm exceeds max ${v.max}cm`);
  });
}

// Validate angles
const angleValidation = rig.validateAngles(pose);
angleValidation.violations.forEach(v => {
  console.warn(`Joint ${v.joint} angle ${v.actual}° exceeds max ${v.max}°`);
});

Rig Hierarchy Queries

// Get all ancestors
const ancestors = rig.getAncestors('left_foot');
// → ['left_ankle', 'left_knee', 'left_hip', 'root']

// Get all descendants
const descendants = rig.getDescendants('root');
// → [all joints in tree]

// Check relationship
const isDescendant = rig.isDescendant('left_foot', 'root');
// → true

// Get bone connecting two joints
const bone = rig.getBone('left_hip', 'left_knee');
// → { id: 'left_femur', ... }

Performance & Production

Bundle Optimization

PoseV uses aggressive tree-shaking and minification:

ESM: 24.2 KB gzipped (79.6% compression)
UMD Min: 13.7 KB gzipped (73% compression)

Performance Budgets

Mobile-first conservative targets:

MetricTargetStatus
Frame Time<16.67ms (60 FPS)
Memory<50 MB
Load Time<5 seconds
Max Keyframes10,000

Error Handling

23 predefined error codes across 6 categories:

import { ERROR_CATALOG, ErrorHandler } from 'posev';

const handler = new ErrorHandler();

try {
  await engine.load(manifest);
} catch (error) {
  handler.handle(error);
  
  if (error.retryable) {
    // Implement exponential backoff retry
    setTimeout(() => engine.load(manifest), 1000);
  }
  
  console.log(handler.getReport());
}

Monitoring

Real-time performance monitoring:

import { PerformanceMonitor } from 'posev';

const monitor = new PerformanceMonitor();

engine.on('frameUpdate', (frame) => {
  monitor.recordMetric({
    fps: 60,
    frameTime: 16.7,
    memoryUsage: 42,
    cpuTime: 14.5,
    renderTime: 2.2,
  });
});

// Check for violations
const status = monitor.getBudgetStatus();
if (!status.compliant) {
  console.warn('Performance degradation:', status.violations);
}

// Generate report
console.log(monitor.getReport());

Examples

See examples/rehab-app/ for a complete application with:

  • Patient movement recording
  • AI-powered form analysis
  • Progress tracking
  • Export to PT software

Motion Capture Integration

See examples/mocap-integration/ for mocap workflow:

  • Real-time pose streaming
  • Calibration tools
  • File export (BVH, FBX, JSON)

Sports Analytics Dashboard

See examples/sports-dashboard/ for analytics:

  • Gait analysis metrics
  • Performance comparison
  • Video overlay with annotations
  • Team performance trending

Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

Development Setup

# Install dependencies
npm install

# Run dev server
npm run dev

# Run tests
npm test

# Run tests in watch mode
npm test -- --watch

# Build for production
npm run build

# Run linter
npm run lint

# Type check
npm run type-check

Creating Issues

Before opening an issue, please check:

  • ✅ Existing issues and discussions
  • ✅ Documentation and guides
  • ✅ Troubleshooting section

Pull Requests

  • Fork the repository
  • Create a feature branch (git checkout -b feature/amazing-feature)
  • Write tests for your changes
  • Ensure all tests pass (npm test)
  • Commit changes (git commit -m 'Add amazing feature')
  • Push to branch (git push origin feature/amazing-feature)
  • Open a Pull Request

Support

Documentation

Community

  • 💬 GitHub Discussions
  • 🐛 Bug Reports: GitHub Issues
  • 💡 Feature Requests: GitHub Discussions
  • 📧 Email: support@posev.ai

Enterprise Support

Priority bug fixes, custom integration, and SLA support available. Contact: enterprise@posev.ai

License

MIT © 2024 PoseV Contributors

Changelog

v1.0.0 (2024-11-23)

  • ✅ Core animation engine
  • ✅ Skeletal rig system
  • ✅ Movement JSON standard
  • ✅ Plugin architecture
  • ✅ Vue 3 integration
  • ✅ Canvas 2D rendering
  • ✅ Production hardening (error handling, performance monitoring, memory management)
  • ✅ Comprehensive test suite (86 tests, 100% passing)

Acknowledgments

Built with ❤️ for sports tech, rehabilitation, and motion analysis professionals.

Keywords

biomechanical

FAQs

Package last updated on 23 Nov 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts