{"_id":"@arcmantle/image-viewer","name":"@arcmantle/image-viewer","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@arcmantle/image-viewer","version":"1.0.0","description":"Image viewer web component based on web-worker canvas image manipulation.","license":"Apache-2.0","author":{"name":"Kristoffer Roen-Lie"},"sideEffects":false,"type":"module","exports":{".":"./dist/image-viewer.js"},"main":"./dist/image-viewer.js","types":"./dist/image-viewer.d.ts","dependencies":{"@arcmantle/adapter-element":"^1.0.0","@arcmantle/library":"^1.0.0","lit-html":"^3.3.0","tslib":"^2.8.1"},"devDependencies":{"@arcmantle/lit-jsx":"^1.0.0","@arcmantle/tsconfig":"^1.0.6","@arcmantle/vite-lib-config":"^1.0.0","@types/node":"^24.0.14","rimraf":"^6.0.1","typescript":"^5.8.3","vite":"^7.0.5"},"scripts":{"build":"pnpm run --sequential \"/^build::.*/\"","build-demo":"vite build --config ./demo/vite.config.ts","build::js":"vite build","build::ts":"tsc --project ./src/tsconfig.json","dev":"vite --config ./demo/vite.config.ts","preview-demo":"vite preview --config ./demo/vite.config.ts"},"_id":"@arcmantle/image-viewer@1.0.0","_integrity":"sha512-lQt+qpuKa3I9rIjaFPyz5irYW+8m5I9wIVYZKpczUWWKsiJdPqxrSnNr8GyBM3LN9msiu/DtTuQcQWI4Bjty7A==","_resolved":"/tmp/57bf3c054c14ccc6f850c914f900afec/arcmantle-image-viewer-1.0.0.tgz","_from":"file:arcmantle-image-viewer-1.0.0.tgz","_nodeVersion":"24.4.1","_npmVersion":"11.4.2","dist":{"integrity":"sha512-lQt+qpuKa3I9rIjaFPyz5irYW+8m5I9wIVYZKpczUWWKsiJdPqxrSnNr8GyBM3LN9msiu/DtTuQcQWI4Bjty7A==","shasum":"313c6f3173700b77c5d9e09de16fb26c86e83124","tarball":"https://registry.npmjs.org/@arcmantle/image-viewer/-/image-viewer-1.0.0.tgz","fileCount":27,"unpackedSize":116308,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHgCq3gffil8H3gqnNy6no8EWeGep7+YDfesl7+LbcmoAiEAm4oa2l7t4M11XmC1vr5fd8x0QHsOTTSYdSyQaxaU1/4="}]},"_npmUser":{"name":"roenlie","email":"kristofferroenlie@gmail.com"},"directories":{},"maintainers":[{"name":"roenlie","email":"kristofferroenlie@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/image-viewer_1.0.0_1752759221470_0.38350498081784967"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-17T13:33:41.414Z","1.0.0":"2025-07-17T13:33:41.664Z","modified":"2025-07-17T13:33:41.906Z"},"maintainers":[{"name":"roenlie","email":"kristofferroenlie@gmail.com"}],"description":"Image viewer web component based on web-worker canvas image manipulation.","author":{"name":"Kristoffer Roen-Lie"},"license":"Apache-2.0","readme":"# @arcmantle/image-viewer\n\nA high-performance image viewer web component built with web workers and offscreen canvas for smooth image manipulation and display.\n\n## Features\n\n- **🚀 High Performance**: Uses web workers and OffscreenCanvas for non-blocking image operations\n- **🎯 Interactive Navigation**: Pan, zoom, and rotate images with mouse and touch support\n- **📱 Touch Gestures**: Multi-touch zoom and pan support for mobile devices\n- **⚡ Hardware Accelerated**: Leverages GPU acceleration through canvas rendering\n- **🎨 Smooth Animations**: Frame-rate limited interactions for optimal performance\n- **🔧 Programmatic API**: Full control through JavaScript API\n\n## Installation\n\n```bash\nnpm install @arcmantle/image-viewer\n\npnpm add @arcmantle/image-viewer\n\nyarn add @arcmantle/image-viewer\n```\n\n## Usage\n\n### Basic HTML Usage\n\n```html\n<iv-image-viewer\n  image-src=\"/path/to/your/image.jpg\"\n  reset-on-new-image\n  fit-on-new-image\n></iv-image-viewer>\n```\n\n### JavaScript/TypeScript Usage\n\n```typescript\nimport { ImageViewer } from '@arcmantle/image-viewer';\n\n// Using the component\nconst viewer = document.createElement('iv-image-viewer');\nviewer.imageSrc = '/path/to/image.jpg';\nviewer.resetOnNewImage = true;\ndocument.body.appendChild(viewer);\n\n// Programmatic control\nviewer.adapter.api.zoom(1.5);\nviewer.adapter.api.rotate(90);\nviewer.adapter.api.fitToView();\nviewer.adapter.api.reset();\n```\n\n### React/JSX Usage\n\n```tsx\nimport { ImageViewer } from '@arcmantle/image-viewer';\n\nfunction App() {\n  return (\n    <ImageViewer\n      image-src=\"/spiral.jpg\"\n      reset-on-new-image\n      fit-on-new-image\n    />\n  );\n}\n```\n\n## Properties\n\n| Property | Type | Default | Description |\n|----------|------|---------|-------------|\n| `imageSrc` | `string` | `''` | URL or path to the image to display |\n| `resetOnNewImage` | `boolean` | `false` | Whether to reset view transformations when a new image is loaded |\n| `fitOnNewImage` | `boolean` | `false` | Whether to automatically fit the image to view when loaded |\n\n## API Methods\n\nThe component exposes an API object with the following methods:\n\n```typescript\n// Access the API\nconst api = imageViewer.adapter.api;\n\n// Reset view to default state\napi.reset();\n\n// Fit image to viewport\napi.fitToView();\n\n// Zoom by factor (1.5 = 150%, 0.5 = 50%)\napi.zoom(1.5);\n\n// Rotate by degrees (positive = clockwise)\napi.rotate(90);\n```\n\n## Interaction Controls\n\n### Mouse Controls\n\n- **Left Click + Drag**: Pan the image\n- **Mouse Wheel**: Zoom in/out at cursor position\n\n### Touch Controls\n\n- **Single Touch + Drag**: Pan the image\n- **Pinch Gesture**: Zoom in/out at gesture center\n- **Two Finger Touch**: Multi-touch zoom and pan\n\n### Keyboard Support\n\nThe component is focusable and can receive keyboard events when focused.\n\n## Architecture\n\nThe image viewer uses a sophisticated architecture for optimal performance:\n\n### Web Worker Architecture\n\n- **Main Thread**: Handles UI interactions and event management\n- **Worker Thread**: Performs all canvas operations and image transformations\n- **OffscreenCanvas**: Enables GPU-accelerated rendering off the main thread\n\n### Performance Optimizations\n\n- **Frame Rate Limiting**: Interactions are throttled to 100fps to prevent overwhelming the system\n- **Transferable Objects**: Efficiently passes data between main thread and worker\n- **Smart Rendering**: Only redraws when necessary\n- **Image Smoothing**: Automatically adjusted based on zoom level\n\n### Canvas Management\n\nThe component uses a `WorkerView` class that provides:\n\n- Viewport calculations and transformations\n- Scale, rotation, and translation management\n- Automatic image centering and fitting\n- Boundary constraints and limits\n\n## Styling\n\nThe component can be styled with CSS:\n\n```css\niv-image-viewer {\n  width: 800px;\n  height: 600px;\n  border: 1px solid #ccc;\n  border-radius: 8px;\n}\n\n/* The component focuses cleanly */\niv-image-viewer:focus {\n  outline: 2px solid #0066cc;\n}\n```\n\n## Advanced Usage\n\n### Custom Controls\n\n```typescript\n// Create custom zoom controls\nfunction createZoomControls(viewer) {\n  const zoomIn = document.createElement('button');\n  zoomIn.textContent = 'Zoom In';\n  zoomIn.onclick = () => viewer.adapter.api.zoom(1.2);\n\n  const zoomOut = document.createElement('button');\n  zoomOut.textContent = 'Zoom Out';\n  zoomOut.onclick = () => viewer.adapter.api.zoom(0.8);\n\n  const reset = document.createElement('button');\n  reset.textContent = 'Reset';\n  reset.onclick = () => viewer.adapter.api.reset();\n\n  return { zoomIn, zoomOut, reset };\n}\n```\n\n### Dynamic Image Loading\n\n```typescript\nasync function loadImage(viewer, imageUrl) {\n  try {\n    // Set the image source\n    viewer.imageSrc = imageUrl;\n\n    // Optionally fit to view after loading\n    // The component will handle the loading automatically\n    setTimeout(() => {\n      viewer.adapter.api.fitToView();\n    }, 100);\n  } catch (error) {\n    console.error('Failed to load image:', error);\n  }\n}\n```\n\n## Browser Support\n\n- **Modern Browsers**: Chrome 69+, Firefox 105+, Safari 15+\n- **Required Features**:\n  - OffscreenCanvas support\n  - Web Workers\n  - ImageBitmap API\n  - ES2020+ JavaScript features\n\n## Development\n\n### Building\n\n```bash\npnpm install\npnpm build\n```\n\n### Development Server\n\n```bash\npnpm dev\n```\n\n### Running Demo\n\n```bash\npnpm build-demo\npnpm preview-demo\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests if applicable\n5. Submit a pull request\n\n## License\n\nThis project is licensed under the Apache 2.0 License - see the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) for details.\n\n## Related Packages\n\nThis component is part of the @arcmantle ecosystem:\n\n- `@arcmantle/adapter-element` - Base web component framework\n- `@arcmantle/library` - Core utilities and canvas helpers\n- `@arcmantle/lit-jsx` - JSX support for Lit-based components\n\n.\n","readmeFilename":"README.md","_rev":"1-a0b5da42497764b1e941637357c225aa"}