reworks the thumbnail
Redo the thumbnail logic to be much more vue-like.
This commit is contained in:
parent
1b1376f60d
commit
06305d6692
5
.babelrc
5
.babelrc
@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"plugins":
|
"plugins": [],
|
||||||
["transform-decorators-legacy","transform-class-properties","transform-function-bind",],
|
|
||||||
"presets":[
|
"presets":[
|
||||||
"es2015", "stage-1", "stage-0"
|
"@babel/preset-env"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["transform-decorators-legacy","transform-class-properties"],
|
"plugins": [],
|
||||||
"presets":[
|
"presets":[
|
||||||
"es2015", "stage-1", "stage-0", "react"
|
"@babel/preset-env",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
4
Changes
4
Changes
@ -1,5 +1,9 @@
|
|||||||
Release history for vue-svg-pan-zoom
|
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
|
v0.1.0 2018-03-24
|
||||||
|
|
||||||
- component can now access the underlying svgpanzoom js object. (GH#1)
|
- component can now access the underlying svgpanzoom js object. (GH#1)
|
||||||
|
29
package.json
29
package.json
@ -5,21 +5,26 @@
|
|||||||
"main": "dist/vue-svg-pan-zoom.js",
|
"main": "dist/vue-svg-pan-zoom.js",
|
||||||
"author": "Yanick Champoux",
|
"author": "Yanick Champoux",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [ "svg", "vuejs" ],
|
"keywords": [
|
||||||
|
"svg",
|
||||||
|
"vuejs"
|
||||||
|
],
|
||||||
"homepage": "https://github.com/yanick/vue-svg-pan-zoom",
|
"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": {
|
"devDependencies": {
|
||||||
"@storybook/addon-knobs": "^3.3.6",
|
"@babel/cli": "^7.4.3",
|
||||||
"@storybook/addons": "^3.3.6",
|
"@babel/core": "^7.4.3",
|
||||||
"@storybook/vue": "^3.3.6",
|
"@babel/preset-env": "^7.4.3",
|
||||||
"babel-core": "^6.26.0",
|
"@storybook/addon-actions": "^5.0.10",
|
||||||
"babel-loader": "^7.1.2",
|
"@storybook/addon-knobs": "^5.0.10",
|
||||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
"@storybook/addons": "^5.0.10",
|
||||||
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
"@storybook/vue": "^5.0.10",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-loader": "^8.0.5",
|
||||||
"babel-preset-stage-1": "^6.24.1",
|
"babel-preset-vue": "^2.0.2",
|
||||||
"vue": "^2.5.13",
|
"vue": "^2.5.13",
|
||||||
"vue-loader": "^13.7.0",
|
"vue-loader": "^15.7.0",
|
||||||
"vue-template-compiler": "^2.5.13"
|
"vue-template-compiler": "^2.5.13"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
3
src/EventBus.js
Normal file
3
src/EventBus.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
export const EventBus = () => new Vue();
|
101
src/Scope.vue
Normal file
101
src/Scope.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<svg class="thumbViewClass" @click="updateMainViewPan" @mousemove="updateMainViewPan">
|
||||||
|
<rect class="scope" :x="x" :y="y" :width="width" :height="height"/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function updateScope(){
|
||||||
|
let main = this.mainSPZ;
|
||||||
|
let thumb = this.thumbnailSPZ;
|
||||||
|
|
||||||
|
if( !main || !thumb ) return;
|
||||||
|
|
||||||
|
let 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;
|
||||||
|
|
||||||
|
let thumByMainZoomRatio = thumbZoom / mainZoom;
|
||||||
|
|
||||||
|
let scopeX = thumbPanX - mainPanX * thumByMainZoomRatio;
|
||||||
|
let scopeY = thumbPanY - mainPanY * thumByMainZoomRatio;
|
||||||
|
let scopeWidth = mainWidth * thumByMainZoomRatio;
|
||||||
|
let scopeHeight = mainHeight * thumByMainZoomRatio;
|
||||||
|
|
||||||
|
this.x = scopeX + 1;
|
||||||
|
this.y = scopeY + 1;
|
||||||
|
this.width = scopeWidth - 2;
|
||||||
|
this.height = scopeHeight - 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function updateMainViewPan(evt){
|
||||||
|
if(evt.which == 0 && evt.button == 0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let main = this.mainSPZ;
|
||||||
|
let thumb = this.thumbnailSPZ;
|
||||||
|
|
||||||
|
let dim = this.$el.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 = evt.clientX - dim.left - thumbWidth / 2;
|
||||||
|
var thumbPanY = evt.clientY - dim.top - thumbHeight / 2;
|
||||||
|
var mainPanX = - thumbPanX * mainZoom / thumbZoom;
|
||||||
|
var mainPanY = - thumbPanY * mainZoom / thumbZoom;
|
||||||
|
main.pan({x:mainPanX, y:mainPanY});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: [ 'bus', 'mainSPZ', 'thumbnailSPZ' ],
|
||||||
|
data: () => ({ x: 0, y: 0, width: 0, height: 0 }),
|
||||||
|
watch: {
|
||||||
|
mainSPZ() { updateScope.call(this) },
|
||||||
|
thumbnailSPZ() { updateScope.call(this) },
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const up = updateScope.bind(this);
|
||||||
|
[ 'mainZoom', 'mainPan', 'thumbnailCreated' ].forEach( event => this.bus.$on( event, up )
|
||||||
|
);
|
||||||
|
up();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateMainViewPan
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.scope {
|
||||||
|
fill: red;
|
||||||
|
fill-opacity: 0.1;
|
||||||
|
stroke: red;
|
||||||
|
stroke-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.thumbViewClass {
|
||||||
|
border: 1px solid black;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5px;
|
||||||
|
left: 5px;
|
||||||
|
width: 20%;
|
||||||
|
height: 30%;
|
||||||
|
margin: 3px;
|
||||||
|
padding: 3px;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 120;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,10 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<slot />
|
<slot />
|
||||||
<SvgPanZoomThumbnail v-if="has_thumbnail">
|
|
||||||
|
<SvgPanZoomThumbnail v-if="has_thumbnail"
|
||||||
|
:onThumbnailShown="onThumbnailShown"
|
||||||
|
:mainSPZ="spz"
|
||||||
|
:bus="bus"
|
||||||
|
>
|
||||||
<slot name="thumbnail" />
|
<slot name="thumbnail" />
|
||||||
</SvgPanZoomThumbnail>
|
</SvgPanZoomThumbnail>
|
||||||
</div>
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +19,8 @@ import svg_pan_zoom from 'svg-pan-zoom';
|
|||||||
|
|
||||||
import props from './props';
|
import props from './props';
|
||||||
|
|
||||||
import thumbnailViewer from './thumbnailViewer';
|
import { EventBus } from './EventBus';
|
||||||
|
|
||||||
import SvgPanZoomThumbnail from './SvgPanZoomThumbnail.vue';
|
import SvgPanZoomThumbnail from './SvgPanZoomThumbnail.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -38,20 +45,21 @@ export default {
|
|||||||
|
|
||||||
Object.keys(props).filter( k => this[k] !== undefined ).forEach( k => options[k] = this[k] );
|
Object.keys(props).filter( k => this[k] !== undefined ).forEach( k => options[k] = this[k] );
|
||||||
|
|
||||||
let svgpanzoom;
|
options.onZoom = (...args) => {
|
||||||
if( this.has_thumbnail ) {
|
this.bus.$emit( 'mainZoom' );
|
||||||
this.$slots.thumbnail[0].elm.id = 'thumbView';
|
if( this.onZoom ) this.onZoom(args);
|
||||||
svgpanzoom = thumbnailViewer({
|
};
|
||||||
mainViewId: this.$slots.default[0].elm.id,
|
|
||||||
thumbViewId: 'thumbView',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
svgpanzoom = svg_pan_zoom( this.$slots.default[0].elm , options );
|
|
||||||
}
|
|
||||||
|
|
||||||
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() }),
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,26 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="thumbViewContainer">
|
<div v-on:wheel="zoomMain">
|
||||||
<svg id="scopeContainer" class="thumbViewClass">
|
<SPZ class="thumbnail"
|
||||||
<g>
|
:zoomEnabled="false"
|
||||||
<rect id="scope" fill="red" fill-opacity="0.1" stroke="red" stroke-width="2px" x="0" y="0" width="0" height="0"/>
|
:panEnabled="false"
|
||||||
<line id="line1" stroke="red" stroke-width="2px" x1="0" y1="0" x2="0" y2="0"/>
|
:controlIconsEnabled="false"
|
||||||
<line id="line2" stroke="red" stroke-width="2px" x1="0" y1="0" x2="0" y2="0"/>
|
:dblClickZoomEnabled="false"
|
||||||
</g>
|
:preventMouseEventsDefault="true"
|
||||||
</svg>
|
v-on:svgpanzoom="thumbnailSPZcreated"
|
||||||
<slot />
|
>
|
||||||
|
<slot class="thumbnail" />
|
||||||
|
</SPZ>
|
||||||
|
<Scope :bus="bus" :mainSPZ="mainSPZ" :thumbnailSPZ="thumbnailSPZ" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Scope from './Scope.vue';
|
||||||
|
|
||||||
export const SvgPanZoomThumbnail = {};
|
export default {
|
||||||
export default SvgPanZoomThumbnail;
|
props: [ 'onThumbnailShown', 'mainSPZ', 'bus' ],
|
||||||
|
beforeCreate: function () {
|
||||||
|
this.$options.components.SPZ = require('./SvgPanZoom.vue').default
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
zoomMain(evt) {
|
||||||
|
this.mainSPZ[ event.deltaY < 0 ? 'zoomIn' : 'zoomOut' ]();
|
||||||
|
},
|
||||||
|
thumbnailSPZcreated(spz) {
|
||||||
|
this.thumbnailSPZ = spz;
|
||||||
|
this.bus.$emit( 'thumbnailCreated', spz );
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if( this.onThumbnailShown ) {
|
||||||
|
this.onThumbnailShown();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: { Scope },
|
||||||
|
data: () => ({ thumbnailSPZ: null })
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.thumbViewClass {
|
|
||||||
border: 1px solid black;
|
.thumbView {
|
||||||
|
z-index: 110;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 5px;
|
bottom: 5px;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
@ -29,14 +58,12 @@ export default SvgPanZoomThumbnail;
|
|||||||
margin: 3px;
|
margin: 3px;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
|
||||||
|
|
||||||
#thumbView {
|
|
||||||
z-index: 110;
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
#scopeContainer {
|
|
||||||
z-index: 120;
|
z-index: 120;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.thumbnail svg {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<slot />
|
|
||||||
<SvgPanZoomThumbnail v-if="has_thumbnail">
|
|
||||||
<slot name="thumbnail" />
|
|
||||||
</SvgPanZoomThumbnail>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import svg_pan_zoom from 'svg-pan-zoom';
|
|
||||||
|
|
||||||
import SvgPanZoomThumbnail from './SvgPanZoomThumbnail.vue';
|
|
||||||
export { SvgPanZoomThumbnail } from './SvgPanZoomThumbnail.vue';
|
|
||||||
|
|
||||||
import thumbnailViewer from './thumbnailViewer';
|
|
||||||
|
|
||||||
let props = {
|
|
||||||
'zoomEnabled': { type: Boolean, default: true },
|
|
||||||
'controlIconsEnabled': { type: Boolean, default: false },
|
|
||||||
'fit': { type: Boolean, default: true },
|
|
||||||
'panEnabled': { type: Boolean, default: true },
|
|
||||||
'dblClickZoomEnabled': { type: Boolean, default: true },
|
|
||||||
'mouseWheelZoomEnabled': { type: Boolean, default: true },
|
|
||||||
'preventMouseEventsDefault': { type: Boolean, default: true },
|
|
||||||
'contain': { type: Boolean, default: false },
|
|
||||||
'center': { type: Boolean, default: true },
|
|
||||||
viewportSelector: { default: '.svg-pan-zoom_viewport' }
|
|
||||||
, zoomScaleSensitivity: { default: 0.2}
|
|
||||||
, minZoom: { default: 0.5}
|
|
||||||
, maxZoom: { default: 10}
|
|
||||||
, refreshRate: { default: 'auto'}
|
|
||||||
, beforeZoom: { }
|
|
||||||
, onZoom: { }
|
|
||||||
, beforePan: { }
|
|
||||||
, onPan: { }
|
|
||||||
, onUpdatedCTM: { }
|
|
||||||
, customEventsHandler: { }
|
|
||||||
, eventsListenerElement: { }
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SvgPanZoom = {
|
|
||||||
props,
|
|
||||||
components: { SvgPanZoomThumbnail },
|
|
||||||
computed: {
|
|
||||||
has_thumbnail: function() { return this.$slots.thumbnail }
|
|
||||||
},
|
|
||||||
mounted: function() {
|
|
||||||
let options = {};
|
|
||||||
|
|
||||||
Object.keys(props).filter( k => this[k] !== undefined ).forEach( k => options[k] = this[k] );
|
|
||||||
|
|
||||||
if( this.has_thumbnail ) {
|
|
||||||
let svgpanzoom = thumbnailViewer({
|
|
||||||
mainViewId: this.$slots.default[0].elm.id,
|
|
||||||
thumbViewId: 'thumbView',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let svgpanzoom = svg_pan_zoom( this.$slots.default[0].elm , options );
|
|
||||||
}
|
|
||||||
// svg_pan_zoom( '#mainView', options );
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SvgPanZoom;
|
|
||||||
|
|
||||||
</script>
|
|
@ -19,6 +19,7 @@ export default {
|
|||||||
, onPan: { }
|
, onPan: { }
|
||||||
, onUpdatedCTM: { }
|
, onUpdatedCTM: { }
|
||||||
, customEventsHandler: { }
|
, customEventsHandler: { }
|
||||||
, eventsListenerElement: { }
|
, eventsListenerElement: { },
|
||||||
|
onThumbnailShown: { },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,5 +14,5 @@ const stories = storiesOf('SvgPanZoom', module)
|
|||||||
.add('single inline SVG', () => SingleStory)
|
.add('single inline SVG', () => SingleStory)
|
||||||
.add('event', () => Event )
|
.add('event', () => Event )
|
||||||
.add( 'layers', () => LayerStory )
|
.add( 'layers', () => LayerStory )
|
||||||
.add( 'thumbnail -- needs to be first story loaded to work', () => ThumbnailStory )
|
.add( 'thumbnail', () => ThumbnailStory )
|
||||||
;
|
;
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<SvgPanZoom
|
<SvgPanZoom
|
||||||
style="width: 880px; height: 720px; border:1px solid black; "
|
style="width: 880px; height: 720px; border:1px solid black; "
|
||||||
|
:onThumbnailShown="honk"
|
||||||
>
|
>
|
||||||
<RawTiger />
|
<RawTiger />
|
||||||
<RawTiger slot="thumbnail" class="thumbViewClass"
|
<RawTiger slot="thumbnail" />
|
||||||
style="position: absolute; width: 20%; height: 30% bottom: 5px;
|
|
||||||
left: 5px; margin: 3px; padding: 3px;"
|
|
||||||
/>
|
|
||||||
</SvgPanZoom>
|
</SvgPanZoom>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -18,6 +16,9 @@ import RawTiger from './RawTiger.vue';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { SvgPanZoom, RawTiger, SvgPanZoomThumbnail },
|
components: { SvgPanZoom, RawTiger, SvgPanZoomThumbnail },
|
||||||
|
methods: {
|
||||||
|
honk(){ console.log( "thumbnail was mounted!" ) }
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user