var Snap = require('snapsvg');
/* custom plugin */
Snap.plugin(function (Snap, Element, Paper, glob) {
var elproto = Element.prototype;
elproto.toBack = function () {
this.prependTo(this.paper);
};
elproto.toFront = function () {
this.appendTo(this.paper);
};
});
var paper = null;
var pointData = [];
var config = null;
var startPoint = null;
var drawing_path = null;
var canDraw = false;
var rectZone = null;
var PATH_COLOR = "#ff00ff";
var SELECTED_COLOR = "#ffff00";
var FIRST_NODE_COLOR = "#FF0000";
var HANDLE_SIZE = 6;
var isDragged = false;
var enablePoint = true;
var pathIsClosed = false;
var ENABLE_NEW_NODE = true;
var RECT_MODE ='RECT';
var drawingMode = RECT_MODE; //free
var FREE_MODE = 'FREE';
var getId = (function () {
var cpt = 0;
var defautPrefix = "item_";
return function (prefix) {
prefix = (typeof prefix === 'string') ? prefix : defautPrefix;
cpt = cpt + 1;
return prefix + cpt;
}
}());
var pathToPoint = function (path) {
if (typeof path === "string") { return false; }
};
//transform point to path
var updatePath = function (paper, updateCallback) {
var path = "M";
if (pointData.length <= 1) {
return;
}
/*if (pathIsClosed) {
pointData.pop();
}*/
path += pointData[0].x + ',' + pointData[0].y;
for (var i=0; i < pointData.length; i++) {
if (i == 0) continue;
var pointInfos = pointData[i];
lPath = "L" + pointInfos.x + "," + pointInfos.y;
path += " " + lPath;
}
path += (pathIsClosed) ? " Z": "";
console.log("stra", updateCallback);
if (typeof updateCallback === 'function' && pathIsClosed) {
updateCallback();
}
/* remove prev path */
if (drawing_path) {
drawing_path.remove();
}
drawing_path = paper.path(path);
drawing_path.attr({
stroke: "red",
opacity: 0.6
});
/* bring all handler to front */
pointData.map(function (point) {
if (point.handler) {
point.handler.toFront();
}
});
console.log("radical...", path);
console.log({isDragged: isDragged, enablePoint: enablePoint, pathIsClosed: pathIsClosed});
};
var onClosePath = function () {
ENABLE_NEW_NODE = false;
/* Group path an handler - add remove_btn */
jQuery("#action-wrapper").show();
};
var onClickOnHandler = function (point, p, e) {
//close path
console.log("new click handler ...");
if (point.isFirst && pointData.length > 2) {
pathIsClosed = true;
}
};
var updatePointPosition = function (newPoint, x, y) {
var index = pointData.indexOf(newPoint);
if (index !== -1) {
pointData[index].x = x;
pointData[index].y = y;
return true;
} else {
return false;
}
};
var clearPreviousPath = function () {
drawing_path.remove();
};
var onMoveHandler = function (dx, dy, posX, posY, e) {
console.log("in onMoveHandler...");
isDragged = true;
/* update point then update the view */
var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy];
this.attr({ transform: transformValue});
var boxSize = this.getBBox();
var wasUpdated = updatePointPosition(this.data('point'), boxSize.x + (HANDLE_SIZE / 2) , boxSize.y + (HANDLE_SIZE / 2));
if (wasUpdated) {
updatePath(this.paper);
}
}
var bindHandlerEvent = function (point, p) {
point.handler.click(onClickOnHandler.bind(this, point, p));
/* -- handler -- */
point.handler.hover(function () {
point.handler.attr({fill: 'yellow'});
}, function () {
var fillColor = point.isFirst ? FIRST_NODE_COLOR : "";
point.handler.attr({fill: fillColor});
});
point.handler.drag(onMoveHandler, function () {
this.data('origTransform', this.transform().local );
}, function () {
if (!isDragged) { return true; }
isDragged = false;
enablePoint = false;
});
}
var createPointHandler = function (p, point) {
var handleX = point.x - HANDLE_SIZE/2;
var handleY = point.y - HANDLE_SIZE/2;
handler = p.rect(handleX, handleY, HANDLE_SIZE, HANDLE_SIZE);
point.handler = handler;
point.handler.data('point', point);
if (pointData.length === 0) {
point.isFirst = true;
}
bindHandlerEvent(point, p);
point.handler.attr({
fill: (pointData.length === 0) ? FIRST_NODE_COLOR : "",
opacity: 0.9,
stroke: PATH_COLOR
});
return point;
}
//create paper
var createPoint = function (paper, x, y, pointData) {
var point = {x:x, y:y, id: getId()};
/**/
if (pathIsClosed) {
updatePath(paper, onClosePath);
return;
}
if (!enablePoint) {
enablePoint = true;
return false;
}
point = createPointHandler(paper, point);
pointData.push(point);
updatePath(paper);
};
var attachRectEvents = function (paper) {
var startPosition = {};
var currentPosition = {};
/* add resizer */
paper.mousedown(function (e) {
if (drawingMode === FREE_MODE || pathIsClosed) { return; }
startPosition.x = e.offsetX;
startPosition.y = e.offsetY;
canDraw = true;
});
paper.mousemove(function (e) {
if (drawingMode === FREE_MODE) { return; }
if (!canDraw) { return; }
var x, y;
currentPosition.x = e.offsetX;
currentPosition.y = e.offsetY;
if (rectZone) {
rectZone.remove();
}
/* bas -> droite */
var width = Math.abs(currentPosition.x - startPosition.x);
var height = Math.abs(startPosition.y - currentPosition.y);
if (currentPosition.y > startPosition.y && currentPosition.x > startPosition.x) {
x = startPosition.x;
y = startPosition.y;
}
/* haut -> droite */
if (currentPosition.y < startPosition.y && currentPosition.x > startPosition.x) {
x = currentPosition.x - width;
y = currentPosition.y;
}
/* haut -> gauche */
if (currentPosition.y < startPosition.y && currentPosition.x < startPosition.x) {
x = currentPosition.x;
y = currentPosition.y;
}
/* bas -> gauche */
if (currentPosition.y > startPosition.y && currentPosition.x < startPosition.x) {
x = currentPosition.x
y = currentPosition.y - height;
}
if(!x || !y) { return; }
rectZone = paper.rect(x, y, width, height);
rectZone.attr({opacity: 0.4});
});
paper.mouseup(function () {
if ((drawingMode === FREE_MODE) || pathIsClosed || !rectZone) { return false; }
rectZone.drag();
canDraw = false;
pathIsClosed = true;
});
};
var attachPointEvents = function (paper) {
paper.click( function(e) {
if (drawingMode === RECT_MODE) {
return true;
}
if (!ENABLE_NEW_NODE) { return true; }
createPoint(paper, e.offsetX, e.offsetY, pointData);
});
};
var API = {
setMode: function (mode) {
var availableMode = ['RECT', 'FREE'];
console.log("undefined", mode);
if (availableMode.indexOf(mode) !== -1) {
drawingMode = mode;
}
this.clear();
},
clear: function () {
/* clear previous path, point, handler */
pointData.map(function (point) {
if (point.handler) {
point.handler.remove();
}
});
/*clear path is exists*/
if (drawing_path) {
drawing_path.remove();
}
if (rectZone) {
rectZone.remove();
}
pointData = [];
startPoint = null;
drawing_path = null;
isDragged = false;
enablePoint = true;
pathIsClosed = false;
ENABLE_NEW_NODE = true;
/* clear path */
},
getPath: function () {
/* retourne le chemin */
console.log();
}
};
module.exports = {
init: function(config) {
/* strange ... */
var mainImage = jQuery(config.wrapperId).find('img').eq(0);
var cutCanvas = jQuery(config.wrapperId).find('.cut-canvas').eq(0);
var path = jQuery(config.wrapperId).find('.image-path').eq(0);
if (path.length) {
jQuery(cutCanvas).append(path);
}
if (!cutCanvas.length) {
var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
cutCanvas.css({border: "1px solid red"});
jQuery(config.wrapperId).append(cutCanvas);
}
if (!mainImage) {
new Error(config.wrapperId + "Can't be found ...");
}
cutCanvas.css({
position: 'absolute',
top: '0px',
left: '15px', //margin from bootstrap
marginLeft: 'auto',
marginRight: 'auto',
width: mainImage.width(),
height: mainImage.height()
});
paper = new Snap(cutCanvas.get(0));
/* handle drawin here */
attachPointEvents(paper);
attachRectEvents(paper);
return API;
},
};