{"_id":"@beoe/pan-zoom","_rev":"1-86d004fb7ac83ccd2faf3d1057e4504d","name":"@beoe/pan-zoom","dist-tags":{"latest":"0.0.4"},"versions":{"0.0.3":{"name":"@beoe/pan-zoom","version":"0.0.3","keywords":["svg","pan","zoom","gestures","touchscreen"],"author":{"name":"stereobooster"},"license":"MIT","_id":"@beoe/pan-zoom@0.0.3","maintainers":[{"name":"stereobooster","email":"stereobooster@gmail.com"}],"homepage":"https://github.com/stereobooster/beoe#readme","bugs":{"url":"https://github.com/stereobooster/beoe/issues"},"dist":{"shasum":"b27accfd4a6670deeb0779904be7ed22f073b799","tarball":"https://registry.npmjs.org/@beoe/pan-zoom/-/pan-zoom-0.0.3.tgz","fileCount":16,"integrity":"sha512-IWHMf0CzRwQawENVpnbkxLMicWdzgFMst8IPVe3qFgXyIn2PDDTzJE1avMhuwUPWchJuQFgXwzuc820gPJ/K+A==","signatures":[{"sig":"MEUCIQCod+rwHqaSAsks8mIrMuZ8xSwzMVue07MvMLwJjYqZ3QIgBH+t2cNx093Grrj0F2cuAT2072C+GyPdeLmCUm2B1tE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":23859},"main":"./dist/index.js","type":"module","_from":"file:beoe-pan-zoom-0.0.3.tgz","types":"./dist/index.d.js","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.js","import":"./dist/index.js","default":"./dist/index.js"},"./css/*.css":{"import":"./css/*.css","require":"./css/*.css"}},"scripts":{"dev":"tsc --watch","tsc":"tsc","test":"vitest","build":"rm -rf dist && tsc","clean":"rm -rf dist"},"_npmUser":{"name":"stereobooster","email":"stereobooster@gmail.com"},"_resolved":"/private/var/folders/vv/fk4322kj49bcxmxz9kbnwjv00000gp/T/9666aa2bc4e260838e8054c6f9d72509/beoe-pan-zoom-0.0.3.tgz","_integrity":"sha512-IWHMf0CzRwQawENVpnbkxLMicWdzgFMst8IPVe3qFgXyIn2PDDTzJE1avMhuwUPWchJuQFgXwzuc820gPJ/K+A==","repository":{"url":"git+https://github.com/stereobooster/beoe.git","type":"git","directory":"packages/pan-zoom"},"_npmVersion":"9.6.7","description":"Pan and zoom for SVG images","directories":{},"_nodeVersion":"18.17.1","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"mathjs":"^12.4.0"},"_npmOperationalInternal":{"tmp":"tmp/pan-zoom_0.0.3_1715174937581_0.4938467476515487","host":"s3://npm-registry-packages"}},"0.0.4":{"name":"@beoe/pan-zoom","version":"0.0.4","description":"Pan and zoom for SVG images","author":{"name":"stereobooster"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/stereobooster/beoe.git","directory":"packages/pan-zoom"},"keywords":["svg","pan","zoom","gestures","touchscreen"],"type":"module","exports":{".":{"types":"./dist/index.d.js","default":"./dist/index.js","import":"./dist/index.js"},"./css/*.css":{"import":"./css/*.css","require":"./css/*.css"}},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.js","devDependencies":{"mathjs":"^14.0.0"},"scripts":{"test":"vitest","build":"rm -rf dist && tsc","dev":"tsc --watch","clean":"rm -rf dist","tsc":"tsc"},"_id":"@beoe/pan-zoom@0.0.4","bugs":{"url":"https://github.com/stereobooster/beoe/issues"},"homepage":"https://github.com/stereobooster/beoe#readme","_integrity":"sha512-WsJBfvrnKNdoHiMQztF5/aUfEc5d5PhrVy0mcrufsV77HuBlG4bcEMZlIEKsfVXCJROkKEcdTEphHhZHu/xCDQ==","_resolved":"/private/var/folders/vv/fk4322kj49bcxmxz9kbnwjv00000gp/T/dd0c0e7287b75ea322716cb4ad630781/beoe-pan-zoom-0.0.4.tgz","_from":"file:beoe-pan-zoom-0.0.4.tgz","_nodeVersion":"20.18.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-WsJBfvrnKNdoHiMQztF5/aUfEc5d5PhrVy0mcrufsV77HuBlG4bcEMZlIEKsfVXCJROkKEcdTEphHhZHu/xCDQ==","shasum":"b2f7106e2b02ee988965bf0776ccba670dc8b04f","tarball":"https://registry.npmjs.org/@beoe/pan-zoom/-/pan-zoom-0.0.4.tgz","fileCount":15,"unpackedSize":23811,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHzClHQBor6gqLgcT5bvD10fnQPWlLRaSy38X/eKABpaAiEAqavB7uW2FXK5aKEbwPhe8a5dPSa1DYa+4OmZdXZWypo="}]},"_npmUser":{"name":"stereobooster","email":"stereobooster@gmail.com"},"directories":{},"maintainers":[{"name":"stereobooster","email":"stereobooster@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pan-zoom_0.0.4_1739470134448_0.7581294621723573"},"_hasShrinkwrap":false}},"time":{"created":"2024-05-08T13:28:57.412Z","modified":"2025-02-13T18:08:54.844Z","0.0.3":"2024-05-08T13:28:57.724Z","0.0.4":"2025-02-13T18:08:54.635Z"},"bugs":{"url":"https://github.com/stereobooster/beoe/issues"},"author":{"name":"stereobooster"},"license":"MIT","homepage":"https://github.com/stereobooster/beoe#readme","keywords":["svg","pan","zoom","gestures","touchscreen"],"repository":{"type":"git","url":"git+https://github.com/stereobooster/beoe.git","directory":"packages/pan-zoom"},"description":"Pan and zoom for SVG images","maintainers":[{"name":"stereobooster","email":"stereobooster@gmail.com"}],"readme":"# @beoe/pan-zoom\n\n<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"logo/logo-dark.svg\">\n    <img alt=\"\" src=\"logo/logo.svg\" width=\"200\" height=\"200\">\n  </picture>\n</p>\n\nSmall JS library to add **pan and zoom** functionality to **SVG** (inline or image). It supports **gestures** for all types of devices:\n\n| intention | mouse                   | trackpad/touchpad | touchscren      |\n| --------- | ----------------------- | ----------------- | --------------- |\n| pan       | click + move            | click + move      | two finger drag |\n| zoom      | <kbd>Ctrl</kbd> + wheel | pinch             | pinch           |\n| reset     | double click            | double click      | double tap      |\n|           |                         |                   |                 |\n| scroll    | wheel                   | two finger drag   | one finger drag |\n\nPay attention:\n\n- gestures intentionally selected to not interfere with the system's default scroll gestures, **to avoid \"scroll traps\"**\n- all actions are available through gestures, so it works without UI. You can add UI, though. Library exposes methods for this, like `pan(dx, dy)` and `zoom(scale)`\n- <kbd>Cmd</kbd> + click - zoom in\n- <kbd>Alt</kbd> + click - zoom out\n- First double click (tap) - zoom in x2\n\n## Demo\n\n[pan-zoom demo](https://beoe.stereobooster.com/other/pan-zoom/)\n\n## Usage\n\nThere are two flavors:\n\n- Headless - without UI\n- Default UI\n\n### Headless\n\nIf you **have container** element in HTML:\n\n```ts\nimport { PanZoom } from \"@beoe/pan-zoom\";\n\ndocument.querySelectorAll(\".beoe\").forEach((container) => {\n  const element = container.firstElementChild;\n  if (!element) return;\n  new PanZoom({ element, container }).on();\n});\n```\n\nIf you **don't have** container element in HTML:\n\n```ts\nimport { PanZoom } from \"@beoe/pan-zoom\";\n\ndocument.querySelectorAll(\"svg, img[src$='.svg' i]\").forEach((element) => {\n  if (element.parentElement?.tagName === \"PICTURE\") {\n    element = element.parentElement;\n  }\n  const container = document.createElement(\"div\");\n  container.className = \"beoe\";\n  element.replaceWith(container);\n  container.append(element);\n  new PanZoom({ element, container }).on();\n});\n```\n\nAdditionally following CSS is required:\n\n```css\n.beoe {\n  overflow: hidden;\n  touch-action: pan-x pan-y;\n  user-select: none;\n  cursor: grab;\n}\n\n.beoe svg,\n.beoe img {\n  /* need to center smaller images to fix bug in zoom functionality */\n  margin: auto;\n  display: block;\n  /* need to fit bigger images */\n  max-width: 100%;\n  height: auto;\n}\n\n.beoe img {\n  pointer-events: none;\n}\n```\n\nInstance methods:\n\n- `on()` - adds event listeners\n- `off()` - removes event listeners\n- `pan(dx, dy)` - pans image\n- `zoom(scale)` - zooms image\n- `reset()` - resets pan and zoom values\n\n### Default UI\n\n```ts\nimport \"@beoe/pan-zoom/css/PanZoomUi.css\";\nimport { PanZoomUi } from \"@beoe/pan-zoom\";\n\ndocument.querySelectorAll(\".beoe\").forEach((container) => {\n  const element = container.firstElementChild;\n  if (!element) return;\n  new PanZoomUi({ element, container }).on();\n});\n```\n\nAdditionally, CSS to style UI required (for example with Tailwind):\n\n```css\n.beoe .buttons {\n  @apply inline-flex;\n}\n.beoe .zoom-in {\n  @apply bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded-l;\n}\n.beoe .reset {\n  @apply bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4;\n}\n.beoe .zoom-out {\n  @apply bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded-r;\n}\n```\n\nYou can configure HTML classes used by UI:\n\n```ts\nconst classes = {\n  zoomIn: \"zoom-in\",\n  reset: \"reset\",\n  zoomOut: \"zoom-out\",\n  buttons: \"buttons\",\n  tsWarning: \"touchscreen-warning\",\n  tsWarningActive: \"active\",\n};\n\nnew PanZoomUi({ element, container, classes });\n```\n\nand message with instructions for the touchscreen:\n\n```ts\nconst message = \"Use two fingers to pan and zoom\";\n\nnew PanZoomUi({ element, container, message });\n```\n\n## Pixelation in Safari\n\nBe aware that some CSS will cause pixelation of SVG on zoom (bug in Safari), for example:\n\n- `will-change: transform;`\n- `transform: matrix3d(...);`\n- `transition-property: transform;` (it setles after animation, though)\n\n## Alternatives\n\nThere are a lot of solutions for this task:\n\n- https://github.com/bumbu/svg-pan-zoom\n- https://jillix.github.io/svg.pan-zoom.js/\n- https://github.com/anvaka/panzoom\n- https://www.npmjs.com/package/svg-pan-zoom-container\n- https://svgjs.dev/docs/3.0/plugins/svg-panzoom-js/\n- https://www.npmjs.com/package/react-svg-pan-zoom\n- https://timmywil.com/panzoom/\n- https://www.jqueryscript.net/other/SVG-Pan-Zoom-jQuery-SVGPanZoom.html\n- https://www.d3indepth.com/zoom-and-pan/\n- https://www.npmjs.com/package/react-zoom-pan-pinch\n\n## Logo\n\nspread by Tomas Knopp from <a href=\"https://thenounproject.com/browse/icons/term/spread/\" target=\"_blank\" title=\"spread Icons\">Noun Project</a> (CC BY 3.0)\n","readmeFilename":"README.md"}