JSFiddle - React, Tailwind, and code Playground
HTML
<div id="panel">
<svg id="svg">
</svg>
</div>
CSS
@import url(https://fonts.googleapis.com/css?family=PT+Serif);
JavaScript
// Initial setup
var panel = d3.select('#panel')
var w = 500;
var h = 200;
var padding = 10;
var kerning = 0;
var trigger_buf = 50;
var svg = d3.select('#svg')
.style('width', '100%')
.attr('height', h)
.style('font-size', '2.5em')
.style('font-family', '"PT Serif"');
var str1 = transform('the neural bit');
var str2 = transform('brian hulette');
var mouse_node = {};
var curr_str = str1;
// Turn strings into lists of objects with some additional information
function transform(str) {
var x = d3.scale.ordinal()
.domain(d3.range(str.length))
.rangePoints([20, w-20], 1);
var rtrn = []
var char_count = {};
var tester = svg.append('text')
var curr_x = padding;
var bbox, this_object, is_space;
for (var i = 0; i < str.length; i++) {
if (typeof char_count[str[i]] !== 'undefined') {
char_count[str[i]] += 1;
} else {
char_count[str[i]] = 0;
}
is_space = str[i] == " "
tester.text(is_space ? "T" : str[i])
.each(function(d) {
bbox = this.getBBox();
});
curr_x += bbox.width/2;
// These are the objects were adding to the list
// c: the char
// count: # of previous occurrences of this letter (used for the d3 key)
// x, y: initial positions for force layour
// cx, cy: assigned positions for gravity force - letters will be attracted
// here
// radius: used for collision detection
// w, h: width and height of the letter
this_object = {
c: str[i],
count: char_count[str[i]],
x: curr_x,
y: h/2,
cx: curr_x,
cy: h/2,
radius: is_space ? 0 : bbox.width/2 - 2,
w: bbox.width,
h: bbox.height
};
rtrn.push(this_object);
curr_x += bbox.width/2;
}
tester.remove()
return rtrn;
}
// Use this key for d3 selections, so that when we change out strings we
// associate corresponding characters in the anagrams...