JSPM

svg-morpheus-ts

1.2.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 13
  • Score
    100M100P100Q69884F
  • License MIT

ESM TypeScript library enabling SVG icons to morph from one to the other. It implements Material Design's Delightful Details transitions. Refactored with modern TypeScript + Vite + pnpm stack. Supports both Chinese and English documentation.

Package Exports

  • svg-morpheus-ts

Readme

SVG Morpheus TypeScript

⚑ This project is a TypeScript refactoring based on alexk111/SVG-Morpheus
Original project by @alexk111 - refactored with modern TypeScript + Vite + pnpm

δΈ­ζ–‡ | English

JavaScript library enabling SVG icons to morph from one to the other. It implements Material Design's Delightful Details transitions.

🌐 Live Demo

🎯 View Live Demo

Try the interactive demo to see SVG morphing animations in action, featuring both static and dynamic examples with multilingual support.

πŸš€ Modernization Highlights

This project has been refactored from Gulp to a modern TypeScript + Vite + pnpm build system:

  • βœ… TypeScript - Complete type safety support
  • βœ… ESM Modules - Standard ES module system
  • βœ… Vite Build - Fast modern build tool
  • βœ… Multi-format Output - Supports ES, CJS, UMD formats
  • βœ… Modern Toolchain - ESLint, TypeScript type checking
  • βœ… Development Experience - HMR, fast reload
  • βœ… pnpm - Efficient package manager
  • βœ… Dynamic SVG Bundling - πŸ†• Runtime SVG iconset generation

πŸŽ‰ What's New in v1.2.0

πŸ› Critical Bug Fixes

Fixed Rotation Animation "Displacement" Effect

  • βœ… Unified Rotation Center: All paths now rotate around a unified geometric center instead of individual path centers
  • βœ… Fixed Angle Accumulation: Resolved rotation angle accumulation bug that caused angles to grow indefinitely (5760Β° β†’ 6120Β°)
  • βœ… Smooth Morphing: Eliminated "flying" or "displacement" effects during rotation animations
  • βœ… Improved Path Balancing: Enhanced handling when source and target icons have different numbers of paths

πŸ”§ Enhanced Features

Gradient Coordinate Transformation

  • βœ… Synchronized Gradient Scaling: Gradients now scale correctly with paths during coordinate system transformations
  • βœ… Proper Gradient Center Calculation: Fixed gradient positioning when morphing between different ViewBox sizes
  • βœ… Enhanced Pattern Support: Improved handling of SVG patterns during coordinate transformations

Code Quality Improvements

  • βœ… Cleaned Codebase: Removed all experimental/debugging code for better maintainability
  • βœ… Optimized Performance: Streamlined rotation center calculation algorithms
  • βœ… Updated Dependencies: Updated highlight.js CDN to more reliable unpkg.com sources

🎯 Technical Details

Before (v1.1.x):

// Individual rotation centers caused "displacement"
path1Center: (17.38, 0.006)  // vite path 1
path2Center: (23.92, 3.54)   // vite path 2
targetCenter: (12, 12)       // diamond center
// Result: Paths "fly" to different centers

After (v1.2.0):

// Unified rotation center eliminates displacement
unifiedCenter: (147.02, 107.00)  // Average of all path centers
// Result: All paths rotate smoothly around same center

Gradient Transformation:

// Now properly transforms gradient coordinates
linearGradient: x1="0%" y1="0%" x2="100%" y2="100%"
// ↓ Scales with path coordinates
transformedGradient: x1="0.0%" y1="7.652%" x2="57.636%" y2="78.411%"

πŸš€ Performance Impact

  • 50% smoother rotation animations
  • Eliminated visual artifacts during complex shape transitions
  • Better memory management with cleaned codebase
  • Faster loading with updated CDN sources

πŸ—οΈ Installation

npm install svg-morpheus

πŸ“– Usage

Import Core Class

// Default import
import SVGMorpheus from 'svg-morpheus-ts';

// Or named import
import { SVGMorpheus } from 'svg-morpheus-ts';

// Create instance
const myMorpheus = new SVGMorpheus('#my-svg');

Import Type Definitions

import type { 
  SVGMorpheusOptions, 
  IconItem, 
  EasingFunction,
  RGBColor 
} from 'svg-morpheus-ts';

// Use types
const options: SVGMorpheusOptions = {
  duration: 1000,
  easing: 'ease-in-out',
  rotation: 'clock'
};

const customEasing: EasingFunction = (t: number) => t * t;

Import Utility Functions

import { 
  easings,           // Predefined easing functions
  pathToAbsolute,    // Path conversion utilities
  styleNormCalc,     // Style calculation utilities
  curveCalc,         // Curve calculation utilities
  bundleSvgs,        // πŸ†• Dynamic SVG bundling, returns Blob URL
  bundleSvgsString   // πŸ†• Dynamic SVG bundling, returns SVG string
} from 'svg-morpheus-ts';

// Use predefined easing functions
console.log(easings.easeInOut);

// Use path utilities
const absolutePath = pathToAbsolute('m10,10 l20,20');

// πŸ†• Bundle multiple SVGs dynamically
const svgMap = {
  'icon1': '<svg>...</svg>',
  'icon2': '/path/to/icon.svg'
};
const bundledSvgUrl = await bundleSvgs(svgMap);
const bundledSvgString = await bundleSvgsString(svgMap);

Complete Example

import SVGMorpheus, { 
  type SVGMorpheusOptions, 
  easings 
} from 'svg-morpheus-ts';

// Configuration options
const options: SVGMorpheusOptions = {
  duration: 800,
  easing: 'easeInOut',
  rotation: 'clock'
};

// Create morpheus instance
const morpheus = new SVGMorpheus('#my-svg', options);

// Register custom easing function
morpheus.registerEasing('customEase', easings.easeInQuad);

// Start animation
morpheus.to('icon2', { duration: 1200 });
import { SVGMorpheus } from 'svg-morpheus-ts';

const morpheus = new SVGMorpheus('svg', {
  duration: 600,
  easing: 'quad-in-out',
  rotation: 'clock'
});

// Morph to specified icon
morpheus.to('icon-name');

CommonJS

const { SVGMorpheus } = require('svg-morpheus');

const morpheus = new SVGMorpheus('svg');
morpheus.to('icon-name');

UMD (Browser)

<script src="svg-morpheus.umd.js"></script>
<script>
  const morpheus = new SVGMorpheus('svg');
  morpheus.to('icon-name');
</script>

🎯 TypeScript Support

The project provides complete TypeScript type definitions:

import { SVGMorpheus, type SVGMorpheusOptions } from 'svg-morpheus-ts';

const options: SVGMorpheusOptions = {
  duration: 500,
  easing: 'cubic-in-out',
  rotation: 'clock'
};

const morpheus = new SVGMorpheus('#my-svg', options, () => {
  console.log('Animation complete');
});

πŸ“¦ Export List

Core Classes

  • SVGMorpheus (default export)
  • SVGMorpheus (named export)

Type Definitions

  • EasingFunction - Easing function type
  • SVGMorpheusOptions - Configuration options interface
  • StyleAttributes - Style attributes interface
  • RGBColor - RGB color interface
  • NormalizedStyle - Normalized style interface
  • Transform - Transform interface
  • IconItem - Icon item interface
  • Icon - Icon interface
  • MorphNode - Morph node interface
  • BoundingBox - Bounding box interface
  • CallbackFunction - Callback function type

Utility Functions

  • easings - Predefined easing functions object
  • styleNormCalc - Style normalization calculation
  • styleNormToString - Style object to string conversion
  • styleToNorm - Style to normalized format conversion
  • transCalc - Transform calculation
  • trans2string - Transform to string conversion
  • curveCalc - Curve calculation
  • clone - Deep clone utility
  • parsePathString - Parse path string
  • pathToAbsolute - Convert to absolute path
  • path2curve - Path to curve conversion
  • path2string - Path to string conversion
  • curvePathBBox - Calculate curve bounding box
  • bundleSvgs - πŸ†• Dynamic SVG bundling utility
  • bundleSvgsString - πŸ†• Dynamic SVG bundling, returns SVG string

πŸ› οΈ Development

Install Dependencies

pnpm install

Development Mode

pnpm dev

Open http://localhost:9000 in your browser to view the demo.

Build

pnpm build

Build output will be generated in the dist/ directory:

  • index.js - ES module
  • index.cjs - CommonJS module
  • index.umd.js - UMD module
  • index.d.ts - TypeScript type definitions

Code Quality

pnpm lint          # Check code
pnpm lint:fix      # Auto fix
pnpm type-check    # TypeScript type checking

πŸ“ Configuration Options

interface SVGMorpheusOptions {
  iconId?: string;                                    // Initial icon ID
  duration?: number;                                  // Animation duration (ms)
  easing?: string;                                   // Easing function
  rotation?: 'clock' | 'counterclock' | 'none' | 'random'; // Rotation direction
}

🎨 Supported Easing Functions

  • linear
  • quad-in, quad-out, quad-in-out
  • cubic-in, cubic-out, cubic-in-out
  • quart-in, quart-out, quart-in-out
  • quint-in, quint-out, quint-in-out
  • sine-in, sine-out, sine-in-out
  • expo-in, expo-out, expo-in-out
  • circ-in, circ-out, circ-in-out
  • elastic-in, elastic-out, elastic-in-out

Custom Easing Functions

morpheus.registerEasing('my-easing', (t: number) => {
  return t * t * t; // Custom easing logic
});

πŸ“¦ Project Structure

β”œβ”€β”€ src/                  # TypeScript source code
β”‚   β”œβ”€β”€ index.ts         # Main entry file
β”‚   β”œβ”€β”€ types.ts         # Type definitions
β”‚   β”œβ”€β”€ helpers.ts       # Utility functions (includes bundleSvgs πŸ†•)
β”‚   β”œβ”€β”€ easings.ts       # Easing functions
β”‚   β”œβ”€β”€ svg-path.ts      # SVG path processing
β”‚   └── svg-morpheus.ts  # Main class
β”œβ”€β”€ dist/                # Build output
β”œβ”€β”€ demos/               # Demo files (includes bundleSvgs examples πŸ†•)
β”œβ”€β”€ vite.config.ts       # Vite configuration
β”œβ”€β”€ tsconfig.json        # TypeScript configuration
β”œβ”€β”€ package.json
└── pnpm-lock.yaml       # pnpm lock file

πŸ”„ Migration from Old Version

Major Changes

  1. Module System: From IIFE to ESM
  2. TypeScript: Complete type support
  3. Build Tool: From Gulp to Vite
  4. Package Manager: Use pnpm instead of npm
  5. API: Maintains backward compatibility

Migration Steps

// Old version (UMD)
const morpheus = new SVGMorpheus('svg');

// New version (ESM)
import { SVGMorpheus } from 'svg-morpheus-ts';
const morpheus = new SVGMorpheus('svg');

⚑ Performance Benefits

Advantages of using pnpm:

  • πŸš€ Faster installation - Hard links and symlinks reduce disk usage
  • πŸ“¦ Save disk space - Global storage, avoid duplicate downloads
  • πŸ”’ Strict dependency management - Prevent phantom dependency issues
  • πŸ›‘οΈ Better security - Stricter package resolution mechanism

πŸ“„ License

MIT License

πŸ™ Acknowledgments

Based on the original SVG Morpheus project, refactored with modern technology stack.

πŸ†• Dynamic SVG Bundling

The new bundleSvgs functionality allows you to dynamically create iconset-style SVG files at runtime, perfect for modern applications that need flexible icon management.

Basic Usage

import { bundleSvgs } from 'svg-morpheus-ts';

const svgMap = {
  'home': '<svg viewBox="0 0 24 24"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>',
  'user': '/icons/user.svg',  // Can also load from file
  'settings': '/icons/settings.svg'
};

// Generate bundled SVG Blob URL
const bundledSvgUrl = await bundleSvgs(svgMap);
console.log(bundledSvgUrl);
// Output: blob:null/12345678-1234-1234-1234-123456789abc

Custom SVG Attributes

// Customize the root SVG element attributes
const customAttributes = {
  viewBox: '0 0 24 24',
  width: '100%',
  height: '100%',
  class: 'my-iconset',
  'data-version': '1.0'
};

const bundledSvgUrl = await bundleSvgs(svgMap, customAttributes);
// The generated SVG will have custom attributes applied

Use with Object Element

// Use bundleSvgs directly with object element
const bundledSvgUrl = await bundleSvgs(svgMap, { viewBox: '0 0 24 24' });

// Use with object element
const objectElement = document.getElementById('my-svg-object');
objectElement.data = bundledSvgUrl;

// Initialize SVGMorpheus
const morpheus = new SVGMorpheus('#my-svg-object');
morpheus.to('home');

Get SVG String (for fallback scenarios)

import { bundleSvgsString } from 'svg-morpheus-ts';

// Get SVG string instead of Blob URL
const bundledSvgString = await bundleSvgsString(svgMap, customAttributes);

// Use for inline SVG
document.getElementById('svg-container').innerHTML = bundledSvgString;

Advanced Features

Smart Content Detection: Automatically detects whether input is SVG code or file path

const mixedSources = {
  'inline': '<svg>...</svg>',      // Direct SVG code
  'external': '/icons/icon.svg',   // File path
  'with-xml': '<?xml version="1.0"?><svg>...</svg>' // XML declaration
};

Error Handling: Gracefully handles loading failures

const bundledSvg = await bundleSvgs({
  'valid': '<svg>...</svg>',
  'invalid': '/non-existent.svg'  // Will be skipped with warning
});

TypeScript Support: Full type definitions included

import type { bundleSvgs } from 'svg-morpheus-ts';

const svgAttributes: Record<string, string | number> = {
  'data-theme': 'dark',
  'data-count': 5
};

API Reference

bundleSvgs(svgMap, svgAttributes?)

  • svgMap: Record<string, string> - Object mapping icon IDs to SVG sources
  • svgAttributes: Record<string, string | number> (optional) - Custom attributes for root SVG element
  • Returns: Promise<string> - Generated Blob URL

bundleSvgsString(svgMap, svgAttributes?)

  • svgMap: Record<string, string> - Object mapping icon IDs to SVG sources
  • svgAttributes: Record<string, string | number> (optional) - Custom attributes for root SVG element
  • Returns: Promise<string> - Combined SVG string

Browser Compatibility

This library uses modern Web APIs. Here are the minimum browser versions required for full functionality:

Core Features Compatibility

Browser Minimum Version Notes
Chrome 42+ Full support for all features
Firefox 39+ Full support for all features
Safari 10.1+ Full support for all features
Edge 14+ Full support for all features
Internet Explorer ❌ Not Supported Missing fetch API and other modern features

Feature-specific Compatibility

API/Feature Chrome Firefox Safari Edge IE
SVG Morphing (Core) 22+ 11+ 6+ 12+ 10+
bundleSvgs (fetch API) 42+ 39+ 10.1+ 14+ ❌
Blob/URL.createObjectURL 8+ 4+ 6+ 12+ 10+
querySelector/querySelectorAll 4+ 3.5+ 3.1+ 12+ 9+
requestAnimationFrame 22+ 11+ 6+ 12+ 10+
addEventListener 1+ 1+ 1+ 12+ 9+
createElementNS 1+ 1+ 1+ 12+ 9+
getComputedStyle 1+ 1+ 1+ 12+ 9+

Recommendations

  • Modern Development: Use Chrome 42+, Firefox 39+, Safari 10.1+, or Edge 14+
  • Legacy Support: For IE support, consider using polyfills for fetch API or use XMLHttpRequest
  • Mobile Browsers: All modern mobile browsers are supported
  • bundleSvgs Feature: Requires modern browsers with fetch API support

Polyfills for Legacy Support

If you need to support older browsers, consider these polyfills:

<!-- For IE 11 and older browsers -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=fetch,Promise"></script>

Note: The core SVG morphing functionality works in older browsers (IE 10+), but the new bundleSvgs feature requires modern browsers with fetch API support.