--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | public
4 | dist/*.gz
5 | dist/*.map
6 | coverage
7 | docs/.vuepress/dist
8 |
9 | # local env files
10 | .env.local
11 | .env.*.local
12 |
13 | # related test files
14 | /tests/e2e/reports
15 | /tests/e2e/videos
16 | /tests/e2e/screenshots
17 |
18 | # editor directories and files
19 | .idea
20 | .vscode
21 | *.suo
22 | *.ntvs*
23 | *.njsproj
24 | *.sln
25 | *.sw*
26 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | productionSourceMap: false,
3 | filenameHashing: false,
4 | chainWebpack: config => {
5 | config.plugins.delete('html');
6 | config.plugins.delete('preload');
7 | config.plugins.delete('prefetch');
8 | },
9 | configureWebpack: {
10 | output: {
11 | filename: 'vue-panzoom.js'
12 | },
13 | optimization: {
14 | splitChunks: false,
15 | },
16 | },
17 | }
18 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import panZoom from 'panzoom';
2 | import PanZoomComponent from './components/pan-zoom/component.vue';
3 |
4 | const PanZoomPlugin = {
5 | install(app, options) {
6 | var _name = options && options.componentName ? options.componentName : PanZoomComponent.name;
7 | app.component(_name, PanZoomComponent);
8 | if (app.hasOwnProperty('config') && app.config.hasOwnProperty('globalProperties')) {
9 | app.config.globalProperties.$panZoom = panZoom;
10 | }
11 | else {
12 | app.prototype.$panZoom = panZoom;
13 | }
14 | }
15 | };
16 |
17 | export default PanZoomPlugin;
18 |
19 | if (typeof window !== 'undefined' && window.Vue) {
20 | window.Vue.use(PanZoomPlugin);
21 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Isa Frimpong <mistabiggx@gmail.com>
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-panzoom",
3 | "version": "1.1.6",
4 | "private": false,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "build:umd": "rollup --config build/rollup.config.js --format umd --file dist/vue-panzoom.umd.js",
9 | "build:es": "rollup --config build/rollup.config.js --format es --file dist/vue-panzoom.esm.js",
10 | "build:unpkg": "rollup --config build/rollup.config.js --format iife --file dist/vue-panzoom.min.js",
11 | "build:all": "npm run build:umd && npm run build:es && npm run build:unpkg"
12 | },
13 | "dependencies": {
14 | "panzoom": "^9.4.1"
15 | },
16 | "devDependencies": {
17 | "@vue/cli-plugin-babel": "^3.3.0",
18 | "@vue/cli-service": "^4.4.6",
19 | "@vue/compiler-sfc": "^3.0.11",
20 | "node-sass": "^4.13.1",
21 | "rollup": "^1.22.0",
22 | "rollup-plugin-buble": "^0.19.8",
23 | "rollup-plugin-commonjs": "^10.1.0",
24 | "rollup-plugin-vue": "^6.0.0",
25 | "sass-loader": "^7.0.1",
26 | "vue-template-compiler": "^2.5.21",
27 | "websocket-extensions": ">=0.1.4"
28 | },
29 | "description": "Vue plugin to zoom/pan dom elements",
30 | "main": "dist/vue-panzoom.umd.js",
31 | "module": "dist/vue-panzoom.esm.js",
32 | "unpkg": "dist/vue-panzoom.min.js",
33 | "browser": {
34 | "./sfc": "src/main.js"
35 | },
36 | "repository": {
37 | "type": "git",
38 | "url": "git+https://github.com/thecodealer/vue-panzoom.git"
39 | },
40 | "keywords": [
41 | "vue",
42 | "zoom",
43 | "pan"
44 | ],
45 | "author": "Isa Frimpong ",
46 | "license": "MIT",
47 | "bugs": {
48 | "url": "https://github.com/thecodealer/vue-panzoom/issues"
49 | },
50 | "homepage": "https://github.com/thecodealer/vue-panzoom#readme"
51 | }
52 |
--------------------------------------------------------------------------------
/src/components/pan-zoom/script.js:
--------------------------------------------------------------------------------
1 | const PanZoomComponent = {
2 | name: 'panZoom',
3 | props: {
4 | options: Object,
5 | selector: String,
6 | },
7 | data() {
8 | return {
9 | $panZoomInstance: null,
10 | instanceId: null,
11 | defaultOptions: {
12 | autocenter: true,
13 | bounds: true,
14 | transformOrigin: {
15 | x: 0.5,
16 | y: 0.5,
17 | }
18 | }
19 | }
20 | },
21 | created() {
22 | this.instanceId = this.generateRandomId(20);
23 | },
24 | mounted() {
25 | if (this.scene) {
26 | var _options = Object.assign({}, this.defaultOptions, this.options);
27 | this.$panZoomInstance = this.$panZoom(this.scene, _options);
28 | this.$panZoomInstanceId = this.instanceId;
29 | this.attachEvents();
30 | }
31 | },
32 | computed: {
33 | scene() {
34 | var el;
35 | var _wrapper = this.$el.querySelector('.vue-pan-zoom-scene');
36 | if (this.selector) {
37 | el = _wrapper.querySelector(this.selector);
38 | }
39 | else {
40 | el = _wrapper.querySelector('svg, object, embed');
41 | if (!el) {
42 | el = _wrapper.firstChild;
43 | }
44 | }
45 | return el;
46 | },
47 | },
48 | methods: {
49 | generateRandomId(l) {
50 | l = l || 16;
51 | var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
52 | var charsLength = chars.length;
53 | var a = [];
54 |
55 | for(var i=0; i {
64 | this.$emit('panstart', e);
65 | });
66 |
67 | this.$panZoomInstance.on('panend', (e) => {
68 | this.$emit('panend', e);
69 | });
70 |
71 | this.$panZoomInstance.on('pan', (e) => {
72 | this.$emit('pan', e);
73 | });
74 |
75 | this.$panZoomInstance.on('zoom', (e) => {
76 | this.$emit('zoom', e);
77 | });
78 |
79 | this.$panZoomInstance.on('transform', (e) => {
80 | this.$emit('transform', e);
81 | });
82 |
83 | this.$panZoomInstance.on('zoomend', (e) => {
84 | this.$emit('zoomend', e);
85 | });
86 | },
87 | isPaused() {
88 | return this.$panZoomInstance.isPaused();
89 | },
90 | pause() {
91 | this.$panZoomInstance.pause();
92 | },
93 | resume() {
94 | this.$panZoomInstance.resume();
95 | }
96 | }
97 | }
98 |
99 | export default PanZoomComponent;
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-panzoom
2 |
3 | This is a [Vue.js](https://vuejs.org/) port of [panzoom](https://github.com/anvaka/panzoom), an extensible, mobile friendly pan and zoom framework (supports DOM and SVG).
4 |
5 | # Demo
6 |
7 | * [Regular DOM object](https://anvaka.github.io/panzoom/demo/dom.html)
8 | * [Standalone page](https://anvaka.github.io/panzoom/demo/index.html) - this repository
9 | * [YASIV](http://www.yasiv.com/#/Search?q=algorithms&category=Books&lang=US) - my hobby project
10 | * [SVG Tiger](https://jsfiddle.net/uwxcmbyg/609/) - js fiddle
11 |
12 | # Installation
13 |
14 | Using npm
15 |
16 | ```
17 | npm install vue-panzoom --save
18 | ```
19 |
20 | Using yarn
21 |
22 | ```
23 | yarn add vue-panzoom
24 | ```
25 |
26 | # Usage
27 |
28 | *main.js*
29 | ``` js
30 | // import Vuejs
31 | import Vue from 'vue'
32 | import App from './App.vue'
33 |
34 | // import vue-panzoom
35 | import panZoom from 'vue-panzoom'
36 |
37 | // install plugin
38 | Vue.use(panZoom);
39 |
40 | new Vue({
41 | render: h => h(App),
42 | }).$mount('#app')
43 | ```
44 |
45 | *App.vue*
46 | ``` html
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
You can zoom me
57 |
58 |
59 |
60 |
61 |
66 |
67 |
68 |
69 | ```
70 |
71 | ## Changing the component's name
72 |
73 | If you wish to change the name of the vue component from the default panZoom, you pass an option to the plugin like so:
74 | ``` js
75 | Vue.use(panZoom, {componentName: 'yourPanZoom'});
76 | ```
77 |
78 | and then use in your vue template like so:
79 | ``` html
80 |
81 | ```
82 |
83 | # Attributes
84 | ### selector
85 | Use this to specify an element within the scope of vue-panzoom component instance, to apply panZoom to. Default is the first root element of the vue-panzoom component. It accepts standard css selector specification.
86 | ``` html
87 |
88 |
I cannot be zoomed and panned
89 |
I can be zoomed and panned
90 |
91 | ```
92 |
93 | # Options
94 | The *options* prop is used to define [panzoom](https://github.com/anvaka/panzoom) options. All panzoom options are supported
95 | ``` html
96 |
97 | ```
98 |
99 | # Events
100 | You can listen to specific events in the lifecycle of a vue-panzoom instance. For example, in the code below the function *onPanStart* will be called when pan begins
101 | ``` html
102 |
103 | ```
104 |
105 | Another way to listen to events within the *init* event's callback, when you know for sure everything is ready and the panzoom instance is available. For example
106 | ``` html
107 |
108 | ```
109 | ``` js
110 | onInit: function(panzoomInstance, id) {
111 | panzoomInstance.on('panstart', function(e){
112 | console.log(e);
113 | });
114 | }
115 | ```
116 |
117 | ## init event
118 | This event is fired when the vue-panzoom instance has been initialized successfully. For example:
119 | ``` html
120 |
121 | ```
122 |
123 | ## [panzoom](https://github.com/anvaka/panzoom) events
124 | All events supported by [panzoom](https://github.com/anvaka/panzoom) are also supported here.
125 |
126 | # upgrading from 1.1.3 to 1.1.4
127 | Version 1.1.4 uses `"rollup-plugin-vue": "^6.0.0"`, which requires Vue 3. For projects using Vue 2, downgrade to 1.1.3, e.g.:
128 | ```sh
129 | npm install vue-panzoom@1.1.3
130 | ```
131 |
--------------------------------------------------------------------------------
/dist/vue-panzoom.esm.js:
--------------------------------------------------------------------------------
1 | import panZoom from 'panzoom';
2 | import { openBlock, createBlock, createVNode, renderSlot } from 'vue';
3 |
4 | var PanZoomComponent = {
5 | name: 'panZoom',
6 | props: {
7 | options: Object,
8 | selector: String,
9 | },
10 | data: function data() {
11 | return {
12 | $panZoomInstance: null,
13 | instanceId: null,
14 | defaultOptions: {
15 | autocenter: true,
16 | bounds: true,
17 | transformOrigin: {
18 | x: 0.5,
19 | y: 0.5,
20 | }
21 | }
22 | }
23 | },
24 | created: function created() {
25 | this.instanceId = this.generateRandomId(20);
26 | },
27 | mounted: function mounted() {
28 | if (this.scene) {
29 | var _options = Object.assign({}, this.defaultOptions, this.options);
30 | this.$panZoomInstance = this.$panZoom(this.scene, _options);
31 | this.$panZoomInstanceId = this.instanceId;
32 | this.attachEvents();
33 | }
34 | },
35 | computed: {
36 | scene: function scene() {
37 | var el;
38 | var _wrapper = this.$el.querySelector('.vue-pan-zoom-scene');
39 | if (this.selector) {
40 | el = _wrapper.querySelector(this.selector);
41 | }
42 | else {
43 | el = _wrapper.querySelector('svg, object, embed');
44 | if (!el) {
45 | el = _wrapper.firstChild;
46 | }
47 | }
48 | return el;
49 | },
50 | },
51 | methods: {
52 | generateRandomId: function generateRandomId(l) {
53 | l = l || 16;
54 | var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
55 | var charsLength = chars.length;
56 | var a = [];
57 |
58 | for(var i=0; i