src_js/iconolab-bundle/src/components/cutout/snapsvg-zoom.js
changeset 146 f912b591e1c1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src_js/iconolab-bundle/src/components/cutout/snapsvg-zoom.js	Fri Aug 19 19:04:26 2016 +0200
@@ -0,0 +1,173 @@
+/* enable zoom */
+import { eventEmitter } from '../utils'
+
+class ZoomHandler {
+
+	constructor (params) {
+		this.zoomFactor = 0.1 || params.zoomFactor;
+		this.paper = params.paper;
+		this.MIN_SIZE = 40;
+		this.imageWidth = parseInt(this.paper.select(".main-image").attr("width"));
+		this.imageHeight = parseInt(this.paper.select(".main-image").attr("height"));
+		
+		this.viewport = {
+			width: parseInt(this.paper.attr("width")),
+			height: parseInt(this.paper.attr("height"))
+		};
+
+		this.scale = 1;
+		this.paper.attr({stroke: 2, "fill": "blue" });
+		this.disableDrag = false;
+		this.imgMinSize = Math.min(this.imageWidth, this.imageHeight);
+		this.lastPosition = []; 
+		this.updateViewBox([0 , 0, this.imageWidth, this.imageHeight]);
+	}
+
+	testShowCenter (cx, cy) {
+	
+		if (this.center) {
+			this.center.remove();
+		}
+		this.center = this.paper.rect(cx - 3, cy - 3, 20, 20);
+		this.center.attr({"fill" : "red"});
+	}
+	
+	drawTestRectangle (cx, cy, w, h) {
+		var x = cx - w / 2;
+		var y = cy - h / 2;
+		this.paper.rect(x, y, w, h);
+	}
+
+	zoomIn () {
+
+		/* current center */
+		if ( this.scale === 9) { this.scale--; return; }
+		var currentCenterX = this.currentViewBox[0] + (this.currentViewBox[2] / 2);
+		var currentCenterY = this.currentViewBox[1] + (this.currentViewBox[3] / 2);
+		var scaleFactor = this.zoomFactor * this.scale;
+		var viewBoxW = this.imgMinSize - (this.imgMinSize * scaleFactor);  
+		var viewBoxH = viewBoxW;
+		
+		this.currentViewBox[0] = currentCenterX - viewBoxW / 2;
+		this.currentViewBox[1] = currentCenterY - viewBoxH / 2;
+
+		this.currentViewBox[2] = viewBoxW;
+		this.currentViewBox[3] = viewBoxH;
+		this.scale ++;
+		this.updateViewBox();
+	}
+	
+	updateViewBox (currentViewBox, notify) {
+		notify = (typeof notify === "boolean") ? notify : true;
+
+		if (currentViewBox && currentViewBox.length != 4) { throw new Error("Provided currentViewBox is not valid!"); }
+		if (currentViewBox) {
+			this.currentViewBox = currentViewBox;
+		}
+		
+		this.paper.attr({"viewBox": this.currentViewBox});
+
+		if (!notify) { return false; }
+
+		var self = this;		
+		eventEmitter.emit("zoomChanged", {
+			updateFunction: function (updatedViewBox) {
+				self.updateViewBox(updatedViewBox, false);
+			},
+			"zoomFactor": this.getZoomFactor(),
+			"viewport": this.viewport,
+			"currentScale": this.scale,
+			"imageSize": {width: this.imageWidth, height: this.imageHeight}, 
+			"minSize": Math.min(this.imageWidth, this.imageHeight),
+			"currentViewBox": this.currentViewBox.slice()
+		});
+	}
+	
+	getZoomFactor () {
+		return {
+			x: this.viewport.width / this.currentViewBox[2],
+			y: this.viewport.height / this.currentViewBox[3]	
+		};
+	}
+
+	onStart (x, y, e) {
+		
+		this.lastPosition[0] = this.currentViewBox[0];
+		this.lastPosition[1] = this.currentViewBox[1];
+
+		if (e.target.className.baseVal === "drawingHandler") {
+			this.disableDrag = true;
+		}
+	}
+
+	canDrag () {
+		return !this.disableDrag;
+	}
+
+	onStop () {
+		this.disableDrag = false;
+	}
+
+	onDrag (dx, dy, x, y, event) {
+
+		if (!this.canDrag()) { return true; }
+
+		var newX = this.lastPosition[0] - dx;
+		var newY = this.lastPosition[1] - dy;
+
+		/* maxX bound */
+		if (newX + this.currentViewBox[2] >= this.viewport.width) {
+			newX = this.viewport.width - this.currentViewBox[2];
+		}
+
+		/* maxY bound */
+		if (newY + this.currentViewBox[3] >= this.viewport.height) {
+			newY = this.viewport.height - this.currentViewBox[3];
+		}
+
+		if (newX <= 0) { newX = 0; }
+
+		if(newY <= 0) { newY = 0; }
+
+		this.currentViewBox[0] = newX;
+		this.currentViewBox[1] = newY;
+
+		this.updateViewBox();
+	}
+
+	reset () {
+		this.scale = 1;
+		this.currentViewBox = [0, 0, this.imageWidth, this.imageHeight];
+		this.updateViewBox();
+	}
+
+	zoomOut () {
+		if (this.scale == 1) { 
+			return false; 
+		}
+
+		var currentCenterX = this.currentViewBox[0] + (this.currentViewBox[2] / 2);
+		var currentCenterY = this.currentViewBox[1] + (this.currentViewBox[3] / 2);
+		var scaleFactor = this.zoomFactor * (this.scale - 1);
+
+		var viewBoxW = this.imgMinSize - (this.imgMinSize * scaleFactor);
+		var viewBoxH = viewBoxW;
+
+		var topX = currentCenterX - viewBoxW / 2;
+		var topY = currentCenterY - viewBoxH / 2;
+
+		this.currentViewBox[0] = topX; //deal with X and Y
+		this.currentViewBox[1] = topY; 
+		this.currentViewBox[2] = viewBoxW;
+		this.currentViewBox[3] = viewBoxH;
+		this.updateViewBox();
+		this.scale--;
+	}
+}
+
+export default {
+
+	enable_zoom: function (params) {
+		return new ZoomHandler(params);
+	}
+}
\ No newline at end of file