src_js/iconolab-bundle/src/components/zoomview/Zoomview.vue
changeset 146 f912b591e1c1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src_js/iconolab-bundle/src/components/zoomview/Zoomview.vue	Fri Aug 19 19:04:26 2016 +0200
@@ -0,0 +1,164 @@
+
+<template src='./template.html'></template>
+
+<script>
+
+import {eventEmitter, computeElementSize} from '../utils'
+import ZoomHandler from '../cutout/snapsvg-zoom'
+
+import Snap from 'snapsvg'
+
+export default {
+
+	props: ['image-url', 'image-width', 'image-height', 'zoomTarget', 'main-image-id'],
+	
+	mounted () {
+		this.root = new Snap(this.$refs['root-svg']);
+		this.handler = this.root.select('#zoom-handler');
+		this.image = this.root.select('#small-image');
+		this.root.attr({width: 101, height: 101});
+		var imageWidth = parseInt(this.image.attr("width"));
+		var imageHeight = parseInt(this.image.attr("height"));
+		/* center image in the viewport */
+		this.root.attr({viewBox: [0, 0, imageWidth, imageHeight]});
+		this.imgMinSize = Math.min(imageWidth, imageHeight);
+
+		this.handlerSize = 20;
+		this.handler.attr({'width': this.handlerSize, 'height': this.handlerSize});
+		this.currentViewBox  = null;
+		this.currentViewport = null;
+		this.updateFunction = null;
+		var target = document.getElementById('zoomTarget');
+
+		if (target) {
+			this.setZoomTarget(target);
+		}
+		this.handleEvents();
+	},
+
+	data () {
+		return {
+			showHandler: false
+		}
+	},
+	methods: {
+		
+		setZoomTarget: function (zoomtarget) {
+			
+			if (zoomtarget.hasOwnProperty("type") && zoomtarget.type === 'svg') {
+				this.paper = zoomtarget; 	
+			} else {
+
+				this.paper = new Snap(zoomtarget);
+				var mainImage = this.paper.select("#" + this.mainImageId);
+				if (!mainImage) { throw new Error("A main image wasn't found."); };
+			}
+
+			this.zoomHandler =  ZoomHandler.enable_zoom(this.paper);
+		},
+
+		incraseDrawingZoom: function () {
+			this.zoomHandler.zoomIn();
+		},
+
+		resetDrawingZoom: function () {
+			this.zoomHandler.reset();
+		},
+
+		decreaseDrawingZoom: function () {
+			this.zoomHandler.zoomOut();
+		},
+		
+		handleEvents: function () {
+			eventEmitter.on('zoomChanged', this.handleZoomChanged.bind(this));
+			var self = this;
+			
+			this.handler.drag(function (dx, dy) {
+				var bbox = this.getBBox();
+				var startX = this.data("startPosition").x;
+				var startY = this.data("startPosition").y;
+				var imageWidth = parseInt(self.image.attr('width'));
+				var imageHeight = parseInt(self.image.attr('height'));
+
+				/* New X */
+				var newX = startX + dx;
+				var newY = startY + dy;
+				
+				/* XBound */
+				if (newX + bbox.w >= imageWidth) {
+					newX = imageWidth - bbox.w; 
+				}
+				/* YBound */
+				if (newY + bbox.h >= imageHeight) {
+					newY = imageHeight - bbox.h;
+				}
+
+				newX = newX < 0 ? 0: newX;
+				newY = newY < 0 ? 0: newY;
+
+				var transformedValue = "T" + [newX, newY];
+				this.attr("transform", transformedValue);
+				self.notifyMove(this.getBBox().x, this.getBBox().y);
+
+			}, function () {
+				this.data("startPosition", {x: this.getBBox().x, y: this.getBBox().y});
+				this.data("origTransform", this.transform().local);
+			}, function () {});
+		},
+
+		moveHandlerToCenter: function (x, c) {
+			cx = cx ? cx : this.width / 2;
+			cy = cy ? cy : this.height / 2;
+			var moveX = cx - this.handler.getBBox().w / 2;
+			var moveY = cy - this.handler.getBBox().h / 2;
+			this.handler.transform( "T" + [moveX, moveY]);
+		},
+		
+		notifyMove: function (x, y) {
+			eventEmitter.emit("moveZoomHandler", {
+				x: x,
+			 	y: y, 
+			 viewport: {
+			 	width: this.image.attr("width"),
+			 	height: this.image.attr("height")
+			 }});
+
+			if (!this.currentViewBox || !this.currentViewport || typeof this.updateFunction !== 'function') { return false; }
+
+			/*longueur image=> longueur viewbox */
+			var xRatio = this.currentImageSize.width / this.image.attr('width');
+			var yRatio = this.currentImageSize.height / this.image.attr('height');
+			var newX = x * xRatio;
+			var newY = y * yRatio;
+			this.currentViewBox[0] = newX;
+			this.currentViewBox[1] = newY;
+			this.updateFunction(this.currentViewBox);
+		},
+
+		handleZoomChanged: function (zoomInfos) {
+			
+			if (zoomInfos.currentScale === 1) { 
+				this.showHandler = false;
+				return; 
+			}
+
+			this.showHandler = true;
+
+			this.currentViewport = zoomInfos.viewport;
+			this.currentViewBox = zoomInfos.currentViewBox;
+			this.currentImageSize = zoomInfos.imageSize; 
+			this.updateFunction = zoomInfos.updateFunction;
+			var handlerSize = zoomInfos.currentViewBox[2] * this.imgMinSize / zoomInfos.minSize;
+			
+			this.handler.attr("width", handlerSize);
+			this.handler.attr("height", handlerSize);
+
+			/*compute handler x, y */
+			var x = zoomInfos.currentViewBox[0] * this.image.attr("width") / zoomInfos.imageSize.width;
+			var y = zoomInfos.currentViewBox[1] * this.image.attr("height")/ zoomInfos.imageSize.height;
+			this.handler.transform( "T" + [x, y]);
+		} 
+	}
+}
+
+</script>
\ No newline at end of file