94 lines
No EOL
3.6 KiB
JavaScript
94 lines
No EOL
3.6 KiB
JavaScript
//helper functions, it turned out chrome doesn't support Math.sgn()
|
|
function signum(x) {
|
|
return (x < 0) ? -1 : 1;
|
|
}
|
|
function absolute(x) {
|
|
return (x < 0) ? -x : x;
|
|
}
|
|
|
|
function drawPath(svg, path, startX, startY, endX, endY) {
|
|
// get the path's stroke width (if one wanted to be really precize, one could use half the stroke size)
|
|
var stroke = parseFloat(path.attr("stroke-width"));
|
|
// check if the svg is big enough to draw the path, if not, set heigh/width
|
|
if (svg.attr("height") < endY) svg.attr("height", endY);
|
|
if (svg.attr("width" ) < (startX + stroke) ) svg.attr("width", (startX + stroke));
|
|
if (svg.attr("width" ) < (endX + stroke) ) svg.attr("width", (endX + stroke));
|
|
|
|
var deltaX = (endX - startX) * 0.15;
|
|
var deltaY = (endY - startY) * 0.15;
|
|
// for further calculations which ever is the shortest distance
|
|
var delta = deltaY < absolute(deltaX) ? deltaY : absolute(deltaX);
|
|
|
|
// set sweep-flag (counter/clock-wise)
|
|
// if start element is closer to the left edge,
|
|
// draw the first arc counter-clockwise, and the second one clock-wise
|
|
var arc1 = 0; var arc2 = 1;
|
|
if (startX > endX) {
|
|
arc1 = 1;
|
|
arc2 = 0;
|
|
}
|
|
// draw tha pipe-like path
|
|
// 1. move a bit down, 2. arch, 3. move a bit to the right, 4.arch, 5. move down to the end
|
|
path.attr("d", "M" + startX + " " + startY +
|
|
" V" + (startY + delta) +
|
|
" A" + delta + " " + delta + " 0 0 " + arc1 + " " + (startX + delta*signum(deltaX)) + " " + (startY + 2*delta) +
|
|
" H" + (endX - delta*signum(deltaX)) +
|
|
" A" + delta + " " + delta + " 0 0 " + arc2 + " " + endX + " " + (startY + 3*delta) +
|
|
" V" + endY );
|
|
}
|
|
|
|
function connectElements(svg, path, startElem, endElem) {
|
|
var svgContainer= $("#svgContainer");
|
|
|
|
// if first element is lower than the second, swap!
|
|
if(startElem.offset().top > endElem.offset().top){
|
|
var temp = startElem;
|
|
startElem = endElem;
|
|
endElem = temp;
|
|
}
|
|
|
|
// get (top, left) corner coordinates of the svg container
|
|
var svgTop = svgContainer.offset().top;
|
|
var svgLeft = svgContainer.offset().left;
|
|
|
|
// get (top, left) coordinates for the two elements
|
|
var startCoord = startElem.offset();
|
|
var endCoord = endElem.offset();
|
|
|
|
// calculate path's start (x,y) coords
|
|
// we want the x coordinate to visually result in the element's mid point
|
|
var startX = startCoord.left + 0.5*startElem.outerWidth() - svgLeft; // x = left offset + 0.5*width - svg's left offset
|
|
var startY = startCoord.top + startElem.outerHeight() - svgTop; // y = top offset + height - svg's top offset
|
|
|
|
// calculate path's end (x,y) coords
|
|
var endX = endCoord.left + 0.5*endElem.outerWidth() - svgLeft;
|
|
var endY = endCoord.top - svgTop;
|
|
|
|
// call function for drawing the path
|
|
drawPath(svg, path, startX, startY, endX, endY);
|
|
|
|
}
|
|
|
|
|
|
|
|
function connectAll() {
|
|
// connect all the paths you want!
|
|
connectElements($("#svg1"), $("#path1"), $(".current1"), $(".current2"));
|
|
connectElements($("#svg1"), $("#path2"), $(".current2"), $(".current3"));
|
|
connectElements($("#svg1"), $("#path3"), $(".current3"), $(".current4") );
|
|
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
// reset svg each time
|
|
$("#svg1").attr("height", "0");
|
|
$("#svg1").attr("width", "0");
|
|
connectAll();
|
|
});
|
|
|
|
$(window).resize(function () {
|
|
// reset svg each time
|
|
$("#svg1").attr("height", "0");
|
|
$("#svg1").attr("width", "0");
|
|
connectAll();
|
|
}); |