JSFiddle - React, Tailwind, and code Playground
HTML
<div id="wrap">
<div id="inner-canvas">
<div class="block me">me</div>
</div>
</div>
<form action="" method="POST">
<select id="add">
<option value="parents">add parents</option>
<option value="father">add father</option>
<option value="mother">add mother</option>
<option value="child">add child</option>
</select>
<input type="submit" value="go">
</form>
CSS
body { background: darkgray; }
.block {
width: 100px;
background:#fff;
height: 90px;
border: 1px solid #ddd;
text-align: center;
line-height: 90px;
position: absolute;
}
#inner-canvas {
width:5000px;
height: 5000px;
position: absolute;
}
#wrap {
width: 100%;
height: 100%;
position: absolute;
overflow: hidden;
}
.active { border: 3px solid #000; }
form { position: absolute; top:0; left: 0; }
JavaScript
(function() {
$(function() {
var genCounter = 0,
blockWidth = 100,
blockHeight = 90,
currentNode = null,
canvas = $('#inner-canvas'),
RELATIONSHIPS = {
'PARTNER' : 1
}
$.fn.center = function() {
var width = canvas.width(), height = canvas.height();
var offset = $(this).offset();
$(this).css({
top: ((width-blockWidth)/2),
left: ( (height-blockHeight)/2 )
})
return this;
}
$.fn.scrollIntoView = function() {
$('.block').removeClass('active')
$(this).addClass('active')
currentNode = this;
$('#wrap').animate({
scrollTop: $(this).offset().top - $(canvas).offset().top - $('#wrap').height() / 2 + 60,
scrollLeft: $(this).offset().left - $(canvas).offset().left - $('#wrap').width() / 2 + 60
}, 500)
return this;
}
$(canvas).on('click', '.block', function() {
$(this).scrollIntoView();
});
$('.block.me').center().scrollIntoView();
$('form').on('submit', function(e) {
e.preventDefault();
addNode( $('#add').val() );
});
// get the current nodes offset to use as a base for the next node
function getCurrentNodeOffset() {
var nodeOffset = $(currentNode).offset(), parentOffset = $(canvas).offset();
var offset = {
top: nodeOffset.top - parentOffset.top,
left: nodeOffset.left - parentOffset.left
};
return offset;
}
function generateBlock( caption, offset ) {
var div = $('<div/>').addClass('block').css({
top:offset.top,
...