@amplo/snapshot-host
v0.1.0
Published
Angular utility for capturing DOM elements as HTML or image snapshots using pluggable capture strategies.
Maintainers
Readme
@amplo/snapshot-host
A lightweight, extensible Angular utility for capturing DOM elements as snapshots.
snapshot-host provides a simple way to:
- Register elements in the DOM
- Capture them as HTML or image snapshots
- Extend capture logic using pluggable strategies (capturers)
It is designed to be fully generic — no assumptions about charts, reports, or UI structure.
Features
- ✅ Directive-based element registration
- ✅ Capture snapshots as HTML or image (data URL)
- ✅ Pluggable capture strategies via Angular DI
- ✅ Deterministic capture routing using
kind - ✅ Default fallback (full HTML capture)
- ✅ Utilities for SVG, canvas, and HTML cloning
- ✅ Zero domain-specific assumptions
Installation
npm install @amplo/snapshot-hostBasic Usage
Template
<div snapshotKey="section-1">
<h2>Hello World</h2>
</div>Component
constructor(private snapshots: SnapshotHostService) {}
async capture() {
await this.snapshots.captureAll();
const snap = this.snapshots.getSnapshot('section-1');
console.log(snap);
}Default Behavior
If no custom capturer is provided:
- The entire element is cloned
- Returned as HTML (
type: 'html')
Snapshot Model
export interface SnapshotItem {
key: string;
type: 'image' | 'html';
html?: string;
dataUrl?: string;
meta?: Record<string, any>;
}Custom Capturers
You can define your own capture logic using a capturer.
export interface SnapshotCapturer {
kind: string;
capture(
context: SnapshotCaptureContext
): SnapshotItem | null | Promise<SnapshotItem | null>;
}Registering Capturers
import { provideSnapshotCapturers } from '@amplo/snapshot-host';
bootstrapApplication(AppComponent, {
providers: [
...provideSnapshotCapturers(
new MyCustomCapturer()
)
]
});Targeting a Capturer
Use data-snapshot-kind to select which capturer should run.
<div
snapshotKey="chart-1"
data-snapshot-kind="chart"
>
</div>Your capturer:
export class ChartCapturer implements SnapshotCapturer {
kind = 'chart';
capture(context: SnapshotCaptureContext): SnapshotItem | null {
return {
key: context.key,
type: 'image',
dataUrl: '...'
};
}
}Directive
<div snapshotKey="my-key"></div>Behavior
- Registers element on init
- Unregisters on destroy
- Reads
data-snapshot-kind(defaults to'default-html')
Capture Flow
- Element is registered via directive
captureAll()iterates over elements- Matching capturer is selected by
kind - Capturer returns snapshot
- If no match → fallback to default HTML capture
Utilities
Canvas
import { canvasToDataUrl } from '@amplo/snapshot-host';
canvasToDataUrl(canvas);SVG
import { serializeSvgToDataUrl } from '@amplo/snapshot-host';
serializeSvgToDataUrl(svg);HTML
import { cloneElementHtml } from '@amplo/snapshot-host';
cloneElementHtml(element, ['.no-print']);Example: SVG / Canvas Capturer
import {
SnapshotCapturer,
SnapshotCaptureContext,
SnapshotItem,
canvasToDataUrl,
serializeSvgToDataUrl,
} from '@amplo/snapshot-host';
export class SvgCanvasCapturer implements SnapshotCapturer {
kind = 'chart';
capture(context: SnapshotCaptureContext): SnapshotItem | null {
const { key, element } = context;
const svg = element.querySelector('svg');
const canvas = element.querySelector('canvas');
if (svg) {
return {
key,
type: 'image',
dataUrl: serializeSvgToDataUrl(svg as SVGSVGElement),
};
}
if (canvas) {
return {
key,
type: 'image',
dataUrl: canvasToDataUrl(canvas as HTMLCanvasElement) ?? undefined,
};
}
return null;
}
}Design Principles
- Generic first — no domain coupling
- Explicit routing via
kind - Angular-native extensibility (DI + multi providers)
- No magic fallback chains
- Separation of concerns (core vs app-specific logic)
When to Use
- Capturing UI blocks for printing
- Generating report snapshots
- Exporting charts or visual components
- Creating preview thumbnails
- Preparing content for PDF generation
License
MIT
