-
-
Save jrbramble76/9937253 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>SVG Lines</title> | |
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> | |
<script src="belay.js"></script> | |
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> | |
<style> | |
body{ | |
background: #eee; | |
} | |
.grid{ | |
padding: 30px; | |
} | |
.fact,.source, .child, .parent{ | |
background: #fff; | |
margin: 10px 0px; | |
border-radius: 4px; | |
min-height: 30px; | |
padding: 10; | |
} | |
ol{ | |
margin: 0; | |
padding: 0; | |
} | |
li{ | |
list-style:none; | |
padding: 0; | |
} | |
h1,h2,h3{ | |
margin-top:0; | |
} | |
li p{margin-bottom:0;} | |
</style> | |
</head> | |
<body> | |
<div class="grid"> | |
<div class="row"> | |
<h1>On Belay!</h1> | |
</div> | |
<div class="row"> | |
<div class="col-sm-5"> | |
<ol id="wives"> | |
<li class="parent" id="parent-1"> | |
<h3>Kendall</h3> | |
</li> | |
<li class="parent" id="parent-2"> | |
<h3>Dave</h3> | |
</li> | |
<li class="parent" id="parent-3"> | |
<h3>Tana</h3> | |
</li> | |
</ol> | |
</div> | |
<div class="col-sm-2"></div> | |
<div class="col-sm-5"> | |
<ol id="children"> | |
<li class="child parent-1">John</li> | |
<li class="child parent-1">Jed</li> | |
<li class="child parent-1">Josh</li> | |
<li class="child parent-1">Kory</li> | |
<li class="child parent-1">Bonnie</li> | |
<li class="child parent-2">Rob</li> | |
<li class="child parent-3">Freestone</li> | |
</ol> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script> | |
function drawConnectors(){ | |
//Draws a line from the wife to her children, based on each child having a class that is the id of the parent. | |
$(".parent").each(function(){ | |
var theID = this.id; | |
$("."+theID).each(function(i,e){ | |
var rand = Math.random() * .7 + .3; | |
Belay.set('animationDuration', rand) | |
Belay.on($("#"+theID), e) | |
}); | |
}) | |
} | |
// redraw if window is resized | |
$(window).resize(function(){ | |
Belay.off(); | |
drawConnectors(); | |
}); | |
Belay.init({strokeWidth: 1}); | |
Belay.set('strokeColor', '#999'); | |
drawConnectors(); | |
</script> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Belay = (function () { | |
var settings = { | |
strokeColor: '#fff', | |
strokeWidth: 2, | |
opacity: 1, | |
fill: 'none', | |
animate: true, | |
animationDirection: 'right', | |
animationDuration: .35 | |
}; | |
var me = {}; | |
me.init = function (initObj) { | |
if (initObj) { | |
$.each(initObj, function (index, value) { | |
//TODO validation on settings | |
settings[index] = value; | |
}); | |
} | |
} | |
me.set = function (prop, val) { | |
//TODO validate | |
settings[prop] = val; | |
} | |
me.on = function (el1, el2) { | |
var svgheight, | |
p, | |
svgleft, | |
svgtop, | |
svgwidth; | |
var el1pos = $(el1).offset(); | |
var el2pos = $(el2).offset(); | |
var el1H = $(el1).outerHeight(); | |
var el1W = $(el1).outerWidth(); | |
var el2H = $(el2).outerHeight(); | |
var el2W = $(el2).outerWidth(); | |
svgleft = Math.round(el1pos.left + el1W); | |
svgwidth = Math.round(el2pos.left - svgleft); | |
////Determine which is higher/lower | |
//If lower/higher | |
if ((el2pos.top + (el2H / 2)) <= (el1pos.top + (el1H / 2))) { | |
svgheight = Math.round((el1pos.top) + el1H / 2) - (el2pos.top + el2H / 2); | |
svgtop = Math.round(el2pos.top + el2H / 2); | |
// Curve Up -- (Left,Bottom Right,Bottom Left,Top Right,Top) http://blogs.sitepointstatic.com/examples/tech/svg-curves/cubic-curve.html | |
p = "M0," + (svgheight + settings.strokeWidth) + " C" + (svgwidth / 2) + "," + (svgheight + settings.strokeWidth) + " " + (svgwidth / 2) + "," + settings.strokeWidth + " " + svgwidth + "," + settings.strokeWidth; | |
} else { | |
svgheight = Math.round((el2pos.top) + el2H / 2) - (el1pos.top + el1H / 2); | |
svgtop = Math.round(el1pos.top + el1H / 2); | |
// Curve Down -- (Left,Top Right,Top Left,Bottom, Right,Bottom) | |
p = "M0," + settings.strokeWidth + " C" + (svgwidth / 2) + "," + settings.strokeWidth + " " + (svgwidth / 2) + "," + (svgheight + settings.strokeWidth) + " " + svgwidth + "," + (svgheight + settings.strokeWidth); | |
} | |
//ugly one-liner | |
$ropebag = $('#ropebag').length ? $('#ropebag') : $('body').append($("<div id='ropebag' />")).find('#ropebag'); | |
var svgnode = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); | |
var newpath = document.createElementNS('http://www.w3.org/2000/svg', "path"); | |
newpath.setAttributeNS(null, "d", p); | |
newpath.setAttributeNS(null, "stroke", settings.strokeColor); | |
newpath.setAttributeNS(null, "stroke-width", settings.strokeWidth); | |
newpath.setAttributeNS(null, "opacity", settings.opacity); | |
newpath.setAttributeNS(null, "fill", settings.fill); | |
svgnode.appendChild(newpath); | |
// Adding the stroke width * 2 to the height so path is not cropped and adjusting the top offset by the stroke width | |
$(svgnode).css({ height: svgheight + (settings.strokeWidth * 2), left: svgleft, position: 'absolute', top: svgtop - settings.strokeWidth, width: svgwidth }); | |
$ropebag.append(svgnode); | |
if (settings.animate) { | |
// THANKS to http://jakearchibald.com/2013/animated-line-drawing-svg/ | |
var pl = newpath.getTotalLength(); | |
// Set up the starting positions | |
newpath.style.strokeDasharray = pl + ' ' + pl; | |
if (settings.animationDirection == 'right') { | |
newpath.style.strokeDashoffset = pl; | |
} else { | |
newpath.style.strokeDashoffset = -pl; | |
} | |
// Trigger a layout so styles are calculated & the browser | |
// picks up the starting position before animating | |
// WON'T WORK IN IE. If you want that, use requestAnimationFrame to update instead of CSS animation | |
newpath.getBoundingClientRect(); | |
newpath.style.transition = newpath.style.WebkitTransition = 'stroke-dashoffset ' + settings.animationDuration + 's ease-in-out'; | |
// Go! | |
newpath.style.strokeDashoffset = '0'; | |
} | |
} | |
me.off = function () { | |
$("#ropebag").empty(); | |
} | |
return me; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When using the plugin I found that it didn't animate correctly in Firefox and the lines didn't end and begin flush/horizontally, and even were cropped by the svg container. This update expands the svg to account for the stroke width to not crop and also to make the path of the svg begin and end correctly/horizontally.