typography-canvas-renderer
v1.2.0
Published
A lightweight npm package for rendering typographic content (text and images) on HTML5 Canvas with full CSS styling support including borders, border-radius, multiple border styles, inline text rendering, auto height calculation, and image support
Maintainers
Readme
Typography Canvas Renderer
A lightweight npm package for rendering typographic content (text and images) on HTML5 Canvas in a browser environment. The package is designed to generate images in high resolution (up to 3000x4244 pixels) with minimal dependencies and full support for modern CSS styling including borders, border-radius, and various border styles.
Features
- 🎨 High Resolution Support: Generate images up to 3000x4244 pixels
- 📝 Text Rendering: Support for custom fonts, colors, positioning, and styling with multi-line text support, automatic text wrapping, custom padding, vertical alignment, and inline text rendering
- 🖼️ Image Rendering: Load and render images from URLs or base64 data
- 🎯 Absolute Positioning: All elements use absolute positioning for precise control
- 📐 Z-Index Layering: Proper element layering with z-index support
- 🔄 Automatic Scaling: Smart scaling for high-resolution canvases
- 🎨 Advanced Border Support: Complete border system with rounded corners and multiple styles
- 🔲 Border Radius: Full support for rounded corners on both text and images
- 📏 Border Styles: Support for solid, dashed, dotted, and double borders
- 📐 Text Fitting: Proper text positioning and padding within borders
- 🔄 Auto Height Calculation: Automatic height calculation based on content and padding
- 📏 Inline Text Rendering: Text renders inline when width is not specified
- 🖼️ Image Support: Full image rendering with borders, padding, and styling
- ⚡ Minimal Dependencies: Only one external dependency (
csstree-validator) - 🌐 Browser-First: Optimized for Chrome 100+, Firefox 100+, Safari 15+
Installation
npm install typography-canvas-rendererMinified Versions
For production use, you can import minified versions for smaller bundle sizes:
// Regular versions
import { renderCanvas } from 'typography-canvas-renderer';
// Minified versions (65% smaller)
import { renderCanvas } from 'typography-canvas-renderer/min';File Sizes:
index.js: 34KB (regular)index.min.js: 12KB (minified) - 65% smallerindex.esm.js: 34KB (regular ESM)index.esm.min.js: 12KB (minified ESM) - 65% smallerindex.umd.js: 38KB (regular UMD)index.umd.min.js: 12KB (minified UMD) - 68% smaller
Quick Start
import { renderCanvas, renderCanvasAsDataURL } from 'typography-canvas-renderer';
const input = {
canvas: {
width: 1000,
height: 1000,
background: 'white',
format: 'png'
},
texts: [
{
text: 'Hello World',
css: {
'font-size': '48px',
'color': 'black',
'left': '10px',
'top': '10px',
'background-color': '#f0f0f0',
'border': '2px solid #333',
'border-radius': '10px',
'z-index': '1'
}
}
],
images: [
{
src: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
css: {
'width': '200px',
'height': '200px',
'left': '50px',
'top': '50px',
'border': '3px dashed blue',
'border-radius': '15px',
'z-index': '2'
}
}
]
};
// Render as Blob
const blob = await renderCanvas(input);
// Render as Data URL
const dataURL = await renderCanvasAsDataURL(input);API Reference
renderCanvas(input, canvasContext?)
Renders typography content on canvas and returns a Blob.
Parameters:
input(Input): Input object containing canvas configuration and elementscanvasContext?(CanvasRenderingContext2D): Optional existing canvas context
Returns: Promise<Blob>
renderCanvasAsDataURL(input, canvasContext?)
Renders typography content on canvas and returns a data URL string.
Parameters:
input(Input): Input object containing canvas configuration and elementscanvasContext?(CanvasRenderingContext2D): Optional existing canvas context
Returns: Promise<string>
clearCache()
Clears the internal image cache.
Input Object Structure
interface Input {
canvas: {
width: number; // Width in pixels (1-3000)
height: number; // Height in pixels (1-4244)
background?: string; // CSS background color (default 'white')
format?: 'png' | 'jpeg'; // Export format (default 'png')
quality?: number; // For JPEG (0-1, default 0.9)
scaleFactor?: number; // Scaling factor (default 1)
};
texts: Array<{
text: string; // Text string
css: Record<string, string>; // CSS properties
}>;
images: Array<{
src: string; // URL or base64 image string
css: Record<string, string>; // CSS properties
}>;
}Supported CSS Properties
Here you can see full css properties list. Open link
Text Elements
| Property | Type | Description | Example |
|----------|------|-------------|---------|
| position | string | Only absolute supported | 'absolute' |
| left | string | X position in pixels | '50px' |
| top | string | Y position in pixels | '100px' |
| width | string | Element width in pixels | '200px' |
| height | string | Element height in pixels | '80px' |
| font-size | string | Font size in pixels | '24px' |
| font-family | string | Font family | 'Arial, sans-serif' |
| color | string | Text color | '#333333' or 'red' |
| background-color | string | Background color | '#f0f0f0' or 'transparent' |
| opacity | string | Opacity (0-1) | '0.8' |
| text-align | string | Text alignment | 'left', 'center', 'right' |
| vertical-align | string | Vertical text alignment | 'top', 'middle', 'center', 'bottom' |
| line-height | string | Line height in pixels | '32px' |
| padding | string | Custom padding in pixels | '10px' |
| border | string | Border style | '2px solid red' |
| border-radius | string | Border radius in pixels | '10px' |
| z-index | string | Layer order (number) | '1' |
Text Rendering Modes
The package supports two text rendering modes based on whether the width property is specified:
Inline Text Rendering (No Width)
When width is not specified, text renders inline with automatic sizing:
{
text: 'Inline Text with Auto Sizing',
css: {
'font-size': '20px',
'color': '#2c3e50',
'left': '50px',
'top': '50px',
'background-color': '#e8f4f8',
'border': '2px solid #3498db',
'border-radius': '8px',
'padding': '15px'
// No width specified - renders inline
}
}Features:
- ✅ Automatic width calculation based on text content
- ✅ Automatic height calculation with padding
- ✅ Proper text alignment (left, center, right)
- ✅ Multiline support with automatic height adjustment
- ✅ Background and border sizing based on content
Block Text Rendering (With Width)
When width is specified, text renders as a block with text wrapping:
{
text: 'Block Text with Width Constraint and Automatic Wrapping',
css: {
'font-size': '18px',
'color': '#ffffff',
'left': '50px',
'top': '50px',
'width': '300px', // Width specified - renders as block
'background-color': '#e74c3c',
'border': '2px solid #c0392b',
'border-radius': '10px',
'padding': '20px',
'text-align': 'center'
// Height can be auto-calculated or specified
}
}Features:
- ✅ Text wrapping within specified width
- ✅ Automatic height calculation based on wrapped lines
- ✅ Padding reduces available width for text
- ✅ Vertical alignment support
- ✅ Proper background and border sizing
Image Elements
| Property | Type | Description | Example |
|----------|------|-------------|---------|
| position | string | Only absolute supported | 'absolute' |
| left | string | X position in pixels | '50px' |
| top | string | Y position in pixels | '100px' |
| width | string | Image width in pixels | '300px' |
| height | string | Image height in pixels | '200px' |
| opacity | string | Opacity (0-1) | '0.9' |
| background-color | string | Background color | '#f0f0f0' |
| border | string | Border style | '3px dashed blue' |
| border-radius | string | Border radius in pixels | '15px' |
| z-index | string | Layer order (number) | '2' |
Border Styles
The package supports comprehensive border styling with proper rendering:
Border Style Syntax
border: [width] [style] [color]Supported Border Styles
| Style | Description | Example | Visual Effect |
|-------|-------------|---------|---------------|
| solid | Solid line border | '2px solid red' | Continuous line |
| dashed | Dashed line border | '3px dashed blue' | Dashed line pattern |
| dotted | Dotted line border | '2px dotted green' | Dotted line pattern |
| double | Double line border | '4px double purple' | Two parallel lines |
Border Radius Support
- Text Elements: Rounded backgrounds and borders with proper text fitting
- Image Elements: Rounded corners with proper image clipping
- Border Compatibility: All border styles work with border-radius
- Padding: Automatic padding ensures text fits properly within borders
Examples
Text with Padding and Vertical Alignment
const input = {
canvas: { width: 800, height: 600 },
texts: [
{
text: 'Top Aligned\nwith Custom Padding\n20px padding',
css: {
'font-size': '20px',
'font-family': 'Arial, sans-serif',
'color': '#2c3e50',
'left': '50px',
'top': '50px',
'width': '200px',
'height': '120px',
'background-color': '#e8f4f8',
'text-align': 'center',
'vertical-align': 'top',
'padding': '20px',
'border': '3px solid #3498db',
'border-radius': '10px',
'line-height': '28px',
'z-index': '1'
}
},
{
text: 'Middle Aligned\nwith Custom Padding\n15px padding',
css: {
'font-size': '18px',
'color': '#ffffff',
'left': '300px',
'top': '50px',
'width': '200px',
'height': '120px',
'background-color': '#e74c3c',
'text-align': 'center',
'vertical-align': 'middle',
'padding': '15px',
'border': '2px solid #c0392b',
'border-radius': '12px',
'line-height': '26px',
'z-index': '2'
}
},
{
text: 'Bottom Aligned\nwith Custom Padding\n10px padding',
css: {
'font-size': '16px',
'color': '#34495e',
'left': '550px',
'top': '50px',
'width': '200px',
'height': '120px',
'background-color': '#ffffff',
'text-align': 'center',
'vertical-align': 'bottom',
'padding': '10px',
'border': '2px dashed #7f8c8d',
'border-radius': '8px',
'line-height': '24px',
'z-index': '3'
}
}
],
images: []
};Image Rendering with Styling
The package supports full image rendering with borders, padding, and styling:
const input = {
canvas: { width: 600, height: 400 },
texts: [],
images: [
{
src: 'https://example.com/image.jpg',
css: {
'width': '200px',
'height': '150px',
'left': '100px',
'top': '75px',
'border': '3px dashed blue',
'border-radius': '15px',
'z-index': '1'
}
},
{
src: 'data:image/png;base64,...',
css: {
'width': '150px',
'height': '100px',
'left': '350px',
'top': '100px',
'border': '2px dotted red',
'border-radius': '20px',
'background-color': '#f0f0f0', // Background behind image
'opacity': '0.9', // Image opacity
'z-index': '2'
}
}
]
};Image Features:
- ✅ Support for URLs and base64 data
- ✅ All border styles (solid, dashed, dotted, double)
- ✅ Border radius with proper clipping
- ✅ Background colors behind images
- ✅ Opacity control
- ✅ Z-index layering
- ✅ Automatic error handling with fallback
Auto Height Calculation with Padding
The package automatically calculates height when not specified, properly accounting for padding:
const input = {
canvas: { width: 800, height: 600 },
texts: [
{
text: 'This text will automatically calculate height based on content and padding. The height will adjust to fit all wrapped lines plus the specified padding.',
css: {
'font-size': '20px',
'color': '#2c3e50',
'left': '50px',
'top': '50px',
'width': '300px',
// No height specified - auto-calculated
'background-color': '#e8f4f8',
'border': '2px solid #3498db',
'border-radius': '5px',
'padding': '20px', // Padding reduces available width, creating more lines
'text-align': 'center'
}
},
{
text: 'Inline Text\nWith Multiline\nAuto Height',
css: {
'font-size': '18px',
'color': '#ffffff',
'left': '400px',
'top': '50px',
// No width or height specified - inline rendering with auto sizing
'background-color': '#e74c3c',
'border': '2px solid #c0392b',
'border-radius': '8px',
'padding': '15px',
'text-align': 'center'
}
}
],
images: []
};Mixed Content with Various Border Styles
const input = {
canvas: { width: 1000, height: 800 },
texts: [
{
text: 'Solid Border',
css: {
'font-size': '24px',
'color': '#ffffff',
'left': '50px',
'top': '50px',
'width': '200px',
'height': '60px',
'background-color': '#e74c3c',
'text-align': 'center',
'border': '3px solid #c0392b',
'border-radius': '10px',
'z-index': '1'
}
},
{
text: 'Double Border',
css: {
'font-size': '22px',
'color': '#2c3e50',
'left': '300px',
'top': '50px',
'width': '200px',
'height': '60px',
'background-color': '#f39c12',
'text-align': 'center',
'border': '4px double #e67e22',
'border-radius': '5px',
'z-index': '2'
}
}
],
images: [
{
src: 'data:image/png;base64,...',
css: {
'width': '150px',
'height': '100px',
'left': '550px',
'top': '50px',
'border': '2px dotted #8e44ad',
'border-radius': '25px',
'z-index': '3'
}
}
]
};High Resolution with Scaling
const input = {
canvas: {
width: 2500,
height: 2500,
scaleFactor: 1.5 // Automatically applied for canvases > 2000px
},
texts: [
{
text: 'High Resolution',
css: {
'font-size': '72px',
'left': '100px',
'top': '100px',
'border': '4px solid #333',
'border-radius': '20px',
'background-color': '#f8f9fa'
}
}
],
images: []
};Complete Example
A comprehensive example file (complete-example.html) is included that demonstrates all features:
- Interactive Presets: 10+ different preset configurations
- Live Rendering: Real-time canvas updates
- JSON Editor: Edit configurations directly
- All Features: Inline text, block text, images, borders, padding, alignment
- Auto Height: Demonstrates automatic height calculation with padding
- Mixed Content: Shows text and images working together
To use the complete example:
- Open
complete-example.htmlin a web browser - Select different presets from the dropdown
- Edit the JSON configuration
- Click "Render" to see results
- Download the canvas as PNG
Browser Compatibility
- Chrome 100+
- Firefox 100+
- Safari 15+
Error Handling
The package throws custom errors for better debugging:
InvalidInputError: Invalid input dataCssValidationError: CSS validation errorsImageLoadError: Image loading failures
import { InvalidInputError, CssValidationError, ImageLoadError } from 'typography-canvas-renderer';
try {
const blob = await renderCanvas(input);
} catch (error) {
if (error instanceof InvalidInputError) {
console.error('Invalid input:', error.message);
} else if (error instanceof CssValidationError) {
console.error('CSS error:', error.message);
} else if (error instanceof ImageLoadError) {
console.error('Image error:', error.message);
}
}Performance Tips
- Image Caching: Images are automatically cached during rendering
- Clear Cache: Use
clearCache()to free memory when done - High Resolution: Use
scaleFactorfor better performance on large canvases - Minimize Elements: Fewer elements = faster rendering
- Border Optimization: Simple borders render faster than complex double borders
Demo
You can test the package functionality using the included example-standalone.html file. Simply open it in your browser to see various examples of text and image rendering with different border styles and border-radius effects.
Future Plans
The package is browser-oriented. Support for Node.js may be added in the future via a separate module (typography-canvas-renderer-node).
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
