/* 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);
}
}