Created
February 25, 2014 20:41
-
-
Save simon-engledew/9217233 to your computer and use it in GitHub Desktop.
HTML5 Line Cards
This file contains hidden or 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> | |
<script src="http://zeptojs.com/zepto.js" type="text/javascript"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.2/raphael-min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/bacon.js/0.7.2/bacon.js" type="text/javascript"></script> | |
<style> | |
html, body { | |
height: 100%; | |
width: 100%; | |
margin: 0; | |
padding: 0; | |
} | |
.card { | |
position: absolute; | |
background: rgba(200, 200, 200, 0.95); | |
border-radius: 5px; | |
-webkit-user-select: none; | |
cursor: pointer; | |
padding: 20px; | |
border: solid 2px #333; | |
white-space: nowrap; | |
box-shadow: 0 0 10px rgba(0, 0, 0, 0.25); | |
} | |
.card:active { | |
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); | |
z-index: 999; | |
} | |
#wires { | |
height: 100%; | |
width: 100%; | |
padding: 0; | |
margin: 0; | |
overflow: hidden; | |
position: relative; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="wires"> | |
<div class="card" style="top: 20px; left: 20px"> | |
Hello 1 | |
</div> | |
<div class="card" style="top: 300px; left: 20px"> | |
Hello 2 | |
</div> | |
<div class="card" style="top: 200px; left: 500px"> | |
<h2>Hello 3</h2> | |
</div> | |
</div> | |
<script> | |
Raphael.fn.connection = function (obj1, obj2, line, bg) { | |
if (obj1.line && obj1.from && obj1.to) { | |
line = obj1; | |
obj1 = line.from; | |
obj2 = line.to; | |
} | |
bb1 = obj1.offset(), | |
bb2 = obj2.offset(); | |
bb1.x = bb1.left; bb1.y = bb1.top; | |
bb2.x = bb2.left; bb2.y = bb2.top; | |
var p = [{x: bb1.x + bb1.width / 2, y: bb1.y - 1}, | |
{x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1}, | |
{x: bb1.x - 1, y: bb1.y + bb1.height / 2}, | |
{x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2}, | |
{x: bb2.x + bb2.width / 2, y: bb2.y - 1}, | |
{x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1}, | |
{x: bb2.x - 1, y: bb2.y + bb2.height / 2}, | |
{x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2}], | |
d = {}, dis = []; | |
for (var i = 0; i < 4; i++) { | |
for (var j = 4; j < 8; j++) { | |
dx = Math.abs(p[i].x - p[j].x), | |
dy = Math.abs(p[i].y - p[j].y); | |
if ((i == j - 4) || (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) { | |
dis.push(dx + dy); | |
d[dis[dis.length - 1]] = [i, j]; | |
} | |
} | |
} | |
if (dis.length == 0) { | |
res = [0, 4]; | |
} else { | |
res = d[Math.min.apply(Math, dis)]; | |
} | |
x1 = p[res[0]].x, | |
y1 = p[res[0]].y, | |
x4 = p[res[1]].x, | |
y4 = p[res[1]].y; | |
dx = Math.max(Math.abs(x1 - x4) / 2, 10); | |
dy = Math.max(Math.abs(y1 - y4) / 2, 10); | |
x2 = [x1, x1, x1 - dx, x1 + dx][res[0]].toFixed(3), | |
y2 = [y1 - dy, y1 + dy, y1, y1][res[0]].toFixed(3), | |
x3 = [0, 0, 0, 0, x4, x4, x4 - dx, x4 + dx][res[1]].toFixed(3), | |
y3 = [0, 0, 0, 0, y1 + dy, y1 - dy, y4, y4][res[1]].toFixed(3); | |
path = ["M", x1.toFixed(3), y1.toFixed(3), "C", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)].join(","); | |
if (line && line.line) { | |
line.bg && line.bg.attr({path: path}); | |
line.line.attr({path: path}); | |
} else { | |
color = typeof line == "string" ? line : "#000"; | |
return { | |
bg: bg && bg.split && this.path(path).attr({stroke: bg.split("|")[0], fill: "none", "stroke-width": bg.split("|")[1] || 3}), | |
line: this.path(path).attr({stroke: color, fill: "none"}), | |
from: obj1, | |
to: obj2 | |
}; | |
} | |
}; | |
var r = Raphael("wires", '100%', '100%'); | |
var connections = []; | |
var card1 = $('.card:nth-of-type(1)'); | |
var card2 = $('.card:nth-of-type(2)'); | |
connections.push(r.connection(card1, card2, '#333')); | |
mousedown = $(document).asEventStream('mousedown', '.card'); | |
mousemove = $(document).asEventStream('mousemove'); | |
mouseup = $(document).asEventStream('mouseup'); | |
Bacon.Observable.prototype.unshift = function(value) { | |
var self = this; | |
return new Bacon.EventStream(function(sink) { | |
return self.onValue(function(x) { | |
x.unshift(value); | |
return sink(new Bacon.Next(x)); | |
}); | |
}) | |
} | |
function toCoords(then, now) { | |
for (var i = connections.length; i--;) { | |
r.connection(connections[i]); | |
} | |
r.safari(); | |
return [now.x - then.offsetX, now.y - then.offsetY]; | |
} | |
mousedown.flatMapLatest(function(cardEvent) { | |
target = $(cardEvent.currentTarget) | |
className = 'mousedown'; | |
if (cardEvent.currentTarget !== cardEvent.target) { | |
offsetA = $(cardEvent.currentTarget).offset(), offsetB = $(cardEvent.target).offset(); | |
cardEvent.offsetX += offsetB.left - offsetA.left; | |
cardEvent.offsetY += offsetB.top - offsetA.top; | |
} | |
target.parent().append(target); | |
return mousemove.map(toCoords, cardEvent).unshift(target).takeUntil(mouseup); | |
}).onValues(function(target, x, y) { | |
target.offset({top: y, left: x}); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment