diff --git a/.babelrc b/.babelrc index 3c87491..5e3027d 100644 --- a/.babelrc +++ b/.babelrc @@ -1,7 +1,6 @@ { - "plugins": - ["transform-decorators-legacy","transform-class-properties","transform-function-bind",], + "plugins": [], "presets":[ - "es2015", "stage-1", "stage-0" + "@babel/preset-env" ] } diff --git a/.storybook/.babelrc b/.storybook/.babelrc index 719446f..a8a2d46 100644 --- a/.storybook/.babelrc +++ b/.storybook/.babelrc @@ -1,6 +1,6 @@ { - "plugins": ["transform-decorators-legacy","transform-class-properties"], + "plugins": [], "presets":[ - "es2015", "stage-1", "stage-0", "react" + "@babel/preset-env", ] } diff --git a/Changes b/Changes index 9ed324e..0719477 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,9 @@ Release history for vue-svg-pan-zoom +v1.0.0 2019-04-30 + +- reworks thumbnail logic to be more vue-like. + v0.1.0 2018-03-24 - component can now access the underlying svgpanzoom js object. (GH#1) diff --git a/package.json b/package.json index 5466288..e17855d 100644 --- a/package.json +++ b/package.json @@ -5,21 +5,26 @@ "main": "dist/vue-svg-pan-zoom.js", "author": "Yanick Champoux", "license": "MIT", - "keywords": [ "svg", "vuejs" ], + "keywords": [ + "svg", + "vuejs" + ], "homepage": "https://github.com/yanick/vue-svg-pan-zoom", - "bugs": { "url" : "https://github.com/yanick/vue-svg-pan-zoom/issues" }, + "bugs": { + "url": "https://github.com/yanick/vue-svg-pan-zoom/issues" + }, "devDependencies": { - "@storybook/addon-knobs": "^3.3.6", - "@storybook/addons": "^3.3.6", - "@storybook/vue": "^3.3.6", - "babel-core": "^6.26.0", - "babel-loader": "^7.1.2", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators-legacy": "^1.3.4", - "babel-preset-es2015": "^6.24.1", - "babel-preset-stage-1": "^6.24.1", + "@babel/cli": "^7.4.3", + "@babel/core": "^7.4.3", + "@babel/preset-env": "^7.4.3", + "@storybook/addon-actions": "^5.0.10", + "@storybook/addon-knobs": "^5.0.10", + "@storybook/addons": "^5.0.10", + "@storybook/vue": "^5.0.10", + "babel-loader": "^8.0.5", + "babel-preset-vue": "^2.0.2", "vue": "^2.5.13", - "vue-loader": "^13.7.0", + "vue-loader": "^15.7.0", "vue-template-compiler": "^2.5.13" }, "dependencies": { diff --git a/src/EventBus.js b/src/EventBus.js new file mode 100644 index 0000000..f7fd4da --- /dev/null +++ b/src/EventBus.js @@ -0,0 +1,3 @@ +import Vue from 'vue'; + +export const EventBus = () => new Vue(); diff --git a/src/Scope.vue b/src/Scope.vue new file mode 100644 index 0000000..5c99bf6 --- /dev/null +++ b/src/Scope.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/src/SvgPanZoom.vue b/src/SvgPanZoom.vue index d359554..1b42811 100644 --- a/src/SvgPanZoom.vue +++ b/src/SvgPanZoom.vue @@ -1,10 +1,16 @@ @@ -13,7 +19,8 @@ import svg_pan_zoom from 'svg-pan-zoom'; import props from './props'; -import thumbnailViewer from './thumbnailViewer'; +import { EventBus } from './EventBus'; + import SvgPanZoomThumbnail from './SvgPanZoomThumbnail.vue'; export default { @@ -38,20 +45,21 @@ export default { Object.keys(props).filter( k => this[k] !== undefined ).forEach( k => options[k] = this[k] ); - let svgpanzoom; - if( this.has_thumbnail ) { - this.$slots.thumbnail[0].elm.id = 'thumbView'; - svgpanzoom = thumbnailViewer({ - mainViewId: this.$slots.default[0].elm.id, - thumbViewId: 'thumbView', - }); - } - else { - svgpanzoom = svg_pan_zoom( this.$slots.default[0].elm , options ); - } + options.onZoom = (...args) => { + this.bus.$emit( 'mainZoom' ); + if( this.onZoom ) this.onZoom(args); + }; - this.$emit( 'svgpanzoom', svgpanzoom ); + options.onPan = (...args) => { + this.bus.$emit( 'mainPan' ); + if( this.onPan ) this.onPan(args); + }; + + this.spz = svg_pan_zoom( this.$slots.default[0].elm , options ); + + this.$emit( 'svgpanzoom', this.spz ); }, + data: () => ({ spz: null, bus: EventBus() }), }; diff --git a/src/SvgPanZoomThumbnail.vue b/src/SvgPanZoomThumbnail.vue index f6d8379..35f571b 100644 --- a/src/SvgPanZoomThumbnail.vue +++ b/src/SvgPanZoomThumbnail.vue @@ -1,26 +1,55 @@ diff --git a/src/index.vue b/src/index.vue deleted file mode 100644 index c3fda34..0000000 --- a/src/index.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - diff --git a/src/props.js b/src/props.js index c1812d9..3fdcdfd 100644 --- a/src/props.js +++ b/src/props.js @@ -19,6 +19,7 @@ export default { , onPan: { } , onUpdatedCTM: { } , customEventsHandler: { } - , eventsListenerElement: { } + , eventsListenerElement: { }, + onThumbnailShown: { }, }; diff --git a/src/stories.js b/src/stories.js index 10a317d..02d5947 100644 --- a/src/stories.js +++ b/src/stories.js @@ -14,5 +14,5 @@ const stories = storiesOf('SvgPanZoom', module) .add('single inline SVG', () => SingleStory) .add('event', () => Event ) .add( 'layers', () => LayerStory ) -.add( 'thumbnail -- needs to be first story loaded to work', () => ThumbnailStory ) +.add( 'thumbnail', () => ThumbnailStory ) ; diff --git a/src/thumbnail.stories.vue b/src/thumbnail.stories.vue index 614f3af..fb15d15 100644 --- a/src/thumbnail.stories.vue +++ b/src/thumbnail.stories.vue @@ -1,12 +1,10 @@ @@ -18,6 +16,9 @@ import RawTiger from './RawTiger.vue'; export default { components: { SvgPanZoom, RawTiger, SvgPanZoomThumbnail }, + methods: { + honk(){ console.log( "thumbnail was mounted!" ) } + }, }; diff --git a/src/thumbnailViewer.js b/src/thumbnailViewer.js deleted file mode 100644 index 44f0ae2..0000000 --- a/src/thumbnailViewer.js +++ /dev/null @@ -1,197 +0,0 @@ -import svgPanZoom from 'svg-pan-zoom'; - -export default function(options){ - - var getSVGDocument = function(objectElem){ - var svgDoc = objectElem.contentDocument; - if(! svgDoc){ - try { - svgDoc = objectElem.getSVGDocument(); - } - catch(e) { - svgDoc = objectElem; - } - } - return svgDoc; - } - - var bindThumbnail = function(main, thumb){ - - if(! window.main && main){ - window.main = main; - } - if(! window.thumb && thumb){ - window.thumb = thumb; - } - if(! window.main || ! window.thumb){ - return; - } - - var resizeTimer; - var interval = 300; //msec - window.addEventListener('resize', function(event){ - if (resizeTimer !== false) { - clearTimeout(resizeTimer); - } - resizeTimer = setTimeout(function () { - window.main.resize(); - window.thumb.resize(); - }, interval); - }); - - window.main.setOnZoom(function(level){ - window.thumb.updateThumbScope(); - if(options.onZoom){ - options.onZoom(window.main, window.thumb, level); - } - }); - - window.main.setOnPan(function(point){ - window.thumb.updateThumbScope(); - if(options.onPan){ - options.onPan(window.main, window.thumb, point); - } - }); - - var _updateThumbScope = function (main, thumb, scope, line1, line2){ - var mainPanX = main.getPan().x - , mainPanY = main.getPan().y - , mainWidth = main.getSizes().width - , mainHeight = main.getSizes().height - , mainZoom = main.getSizes().realZoom - , thumbPanX = thumb.getPan().x - , thumbPanY = thumb.getPan().y - , thumbZoom = thumb.getSizes().realZoom; - - var thumByMainZoomRatio = thumbZoom / mainZoom; - - var scopeX = thumbPanX - mainPanX * thumByMainZoomRatio; - var scopeY = thumbPanY - mainPanY * thumByMainZoomRatio; - var scopeWidth = mainWidth * thumByMainZoomRatio; - var scopeHeight = mainHeight * thumByMainZoomRatio; - - scope.setAttribute("x", scopeX + 1); - scope.setAttribute("y", scopeY + 1); - scope.setAttribute("width", scopeWidth - 2); - scope.setAttribute("height", scopeHeight - 2); - /* - line1.setAttribute("x1", scopeX + 1); - line1.setAttribute("y1", scopeY + 1); - line1.setAttribute("x2", scopeX + 1 + scopeWidth - 2); - line1.setAttribute("y2", scopeY + 1 + scopeHeight - 2); - line2.setAttribute("x1", scopeX + 1); - line2.setAttribute("y1", scopeY + 1 + scopeHeight - 2); - line2.setAttribute("x2", scopeX + 1 + scopeWidth - 2); - line2.setAttribute("y2", scopeY + 1); - */ - }; - - window.thumb.updateThumbScope = function(){ - var scope = document.getElementById('scope'); - var line1 = document.getElementById('line1'); - var line2 = document.getElementById('line2'); - _updateThumbScope(window.main, window.thumb, scope, line1, line2); - } - window.thumb.updateThumbScope(); - - var _updateMainViewPan = function(clientX, clientY, scopeContainer, main, thumb){ - var dim = scopeContainer.getBoundingClientRect() - , mainWidth = main.getSizes().width - , mainHeight = main.getSizes().height - , mainZoom = main.getSizes().realZoom - , thumbWidth = thumb.getSizes().width - , thumbHeight = thumb.getSizes().height - , thumbZoom = thumb.getSizes().realZoom; - - var thumbPanX = clientX - dim.left - thumbWidth / 2; - var thumbPanY = clientY - dim.top - thumbHeight / 2; - var mainPanX = - thumbPanX * mainZoom / thumbZoom; - var mainPanY = - thumbPanY * mainZoom / thumbZoom; - main.pan({x:mainPanX, y:mainPanY}); - }; - - var updateMainViewPan = function(evt){ - if(evt.which == 0 && evt.button == 0){ - return false; - } - var scopeContainer = document.getElementById('scopeContainer'); - _updateMainViewPan(evt.clientX, evt.clientY, scopeContainer, window.main, window.thumb); - } - - var scopeContainer = document.getElementById('scopeContainer'); - scopeContainer.addEventListener('click', function(evt){ - updateMainViewPan(evt); - }); - - scopeContainer.addEventListener('mousemove', function(evt){ - updateMainViewPan(evt); - }); - }; - - var mainViewObjectElem = document.getElementById(options.mainViewId); - console.log(mainViewObjectElem); - mainViewObjectElem.addEventListener("load", function(){ - - var mainViewSVGDoc = getSVGDocument(mainViewObjectElem); - if(options.onMainViewSVGLoaded){ - options.onMainViewSVGLoaded(mainViewSVGDoc); - } - - var beforePan = function(oldPan, newPan){ - var stopHorizontal = false - , stopVertical = false - , gutterWidth = 100 - , gutterHeight = 100 - // Computed variables - , sizes = this.getSizes() - , leftLimit = -((sizes.viewBox.x + sizes.viewBox.width) * sizes.realZoom) + gutterWidth - , rightLimit = sizes.width - gutterWidth - (sizes.viewBox.x * sizes.realZoom) - , topLimit = -((sizes.viewBox.y + sizes.viewBox.height) * sizes.realZoom) + gutterHeight - , bottomLimit = sizes.height - gutterHeight - (sizes.viewBox.y * sizes.realZoom); - let customPan = {}; - customPan.x = Math.max(leftLimit, Math.min(rightLimit, newPan.x)); - customPan.y = Math.max(topLimit, Math.min(bottomLimit, newPan.y)); - return customPan; - }; - - var main = svgPanZoom('#'+options.mainViewId, { - zoomEnabled: true, - controlIconsEnabled: true, - fit: false, - center: true, - beforePan: beforePan - }); - - bindThumbnail(main, undefined); - if(options.onMainViewShown){ - options.onMainViewShown(mainViewSVGDoc, main); - } - - }, false); - - var thumbViewObjectElem = document.getElementById(options.thumbViewId); - thumbViewObjectElem.addEventListener("load", function(){ - - var thumbViewSVGDoc = getSVGDocument(thumbViewObjectElem); - if(options.onThumbnailSVGLoaded){ - options.onThumbnailSVGLoaded(thumbViewSVGDoc); - } - - var thumb = svgPanZoom('#'+options.thumbViewId, { - zoomEnabled: false, - panEnabled: false, - controlIconsEnabled: false, - dblClickZoomEnabled: false, - preventMouseEventsDefault: true, - }); - - bindThumbnail(undefined, thumb); - if(options.onThumbnailShown){ - options.onThumbnailShown(thumbViewSVGDoc, thumb); - } - - }, false); - - return main; -}; -