$(function() {
var startPath = $(".fragment-path").val();
var PATHCOLOR = "#ff00ff",
SELECTEDCOLOR = "#ffff00",
HANDLESIZE = 6;
var jqs = $(".cutout-canvas"),
offset = jqs.offset(),
paper = new Raphael(jqs[0]),
closed = false,
rectangleMode = false,
closeTimeout,
points = [];
paper.rect(0, 0, paper.width, paper.height)
.attr({
stroke: "none",
fill: "#fff",
"fill-opacity": .01
})
.click(clickAddPoint)
.drag(
function(dx, dy, mx, my) {
if (dx*dx+dy*dy < 4) {
return;
}
if (!pathDragging) {
clearTimeout(closeTimeout);
closed = true;
resetPoints();
for (var i = 0; i < 4; i++) {
addPoint(mx - offset.left, my - offset.top)
}
redrawPath();
pathDragging = true;
rectangleMode = true;
}
var x = mx - offset.left,
y = my - offset.top;
points[1].x = points[2].x = x;
points[2].y = points[3].y = y;
redrawPath();
},
function(mx, my) {
pathDragging = false;
},
function() {
setTimeout(function() {
pointDragging = false;
},0);
}
);
function resetPoints() {
rectangleMode = false;
points.forEach(function(p) {
p.handle.remove();
});
points = [];
}
function addPoint(x, y) {
var dragdeltax, dragdeltay, pointDragging,
point = {
x: Math.floor(x),
y: Math.floor(y)
}
var pointsWithSameX = [], pointsWithSameY = [];
var pointrect = paper.rect(0, 0, HANDLESIZE, HANDLESIZE)
.attr({
stroke: PATHCOLOR,
fill: PATHCOLOR,
"fill-opacity": .3
})
.hover(shapeMouseOver, shapeMouseOut)
.drag(
function(dx, dy) {
pointDragging = true;
point.x = dx + dragdeltax;
point.y = dy + dragdeltay;
if (rectangleMode) {
pointsWithSameX.forEach(function(p) {
p.x = point.x;
});
pointsWithSameY.forEach(function(p) {
p.y = point.y;
});
}
redrawPath();
},
function() {
dragdeltax = point.x;
dragdeltay = point.y;
if (rectangleMode) {
pointsWithSameX = points.filter(function(p) {
return p !== point && p.x === point.x;
});
pointsWithSameY = points.filter(function(p) {
return p !== point && p.y === point.y;
});
}
},
function() {
setTimeout(function() {
pointDragging = false;
shapeMouseOut(pointrect);
},0);
}
)
.click(function() {
if (pointDragging) {
return;
}
this.remove();
points = points.filter(function(p) {
return p != point;
});
redrawPath();
});
point.handle = pointrect;
points.push(point);
}
function clickAddPoint(e, mx, my) {
if (pathDragging) {
return;
}
if (rectangleMode) {
resetPoints();
}
clearTimeout(closeTimeout);
closed = false;
addPoint(mx - offset.left, my - offset.top);
redrawPath();
closeTimeout = setTimeout(function() {
closed = true;
redrawPath();
}, 1000)
}
function shapeMouseOver() {
points.forEach(function(point) {
if (point.handle !== this) {
point.handle.attr({
stroke: PATHCOLOR,
fill: PATHCOLOR
});
}
});
if (this !== path) {
path.attr({
stroke: PATHCOLOR,
fill: PATHCOLOR
});
}
this.attr({
stroke: SELECTEDCOLOR,
fill: SELECTEDCOLOR
});
}
function shapeMouseOut() {
if (pathDragging || !this || !this.attr) {
return;
}
this.attr({
stroke: PATHCOLOR,
fill: PATHCOLOR
});
}
function redrawPath() {
var d = "M"
+ points.map(function(p) { return p.x + " " + p.y }).join("L")
+ (closed ? "Z" : "");
path.attr({
path: d
});
points.forEach(function(point) {
point.handle.attr({
x: point.x - HANDLESIZE / 2,
y: point.y - HANDLESIZE / 2
});
});
var transd = "M"
+ points.map(function(p) { return (p.x / paper.width).toString().replace(/(\.\d{4})\d*/,"$1") + " " + (p.y / paper.height).toString().replace(/(\.\d{4})\d*/,"$1") }).join("L")
+ "Z";
$(".fragment-path").val(transd);
}
var dragdeltax, dragdeltay, pathDragging;
var path = paper.path()
.attr({
stroke: PATHCOLOR,
fill: PATHCOLOR,
"fill-opacity": .1
})
.click(clickAddPoint)
.hover(shapeMouseOver, shapeMouseOut)
.drag(
function(dx, dy) {
pathDragging = true;
points.forEach(function(point) {
point.x += dx - dragdeltax;
point.y += dy - dragdeltay;
});
dragdeltax = dx;
dragdeltay = dy;
redrawPath();
},
function() {
dragdeltax = 0;
dragdeltay = 0;
},
function() {
setTimeout(function() {
pathDragging = false;
shapeMouseOut(path);
},0);
}
);
$(".clear-fragment").click(function() {
resetPoints();
redrawPath();
return false;
});
function revertPath() {
startPath.split(/\s*[A-Z]\s*/).forEach(function(coords) {
xy = coords.split(/[\s,]/);
if (xy.length === 2) {
addPoint(paper.width * parseFloat(xy[0]), paper.height * parseFloat(xy[1]));
}
});
if (points.length) {
closed = true;
}
if (
points.length === 4
&& points[0].x === points[3].x
&& points[0].y === points[1].y
&& points[1].x === points[2].x
&& points[2].y === points[3].y
) {
rectangleMode = true;
}
redrawPath();
}
revertPath();
$(".reset-fragment").click(function() {
resetPoints();
revertPath();
return false;
})
});