JSFiddle - React, Tailwind, and code Playground
HTML
<p>
As
<span class="chunk" data-chord="C"></span>I was going over <span class="chunk" data-chord="Am"></span>th<span class="chunk" data-chord="E"></span>e
</p>
<p>
<span class="chunk" data-chord="Am"></span>far fam'd Kerry <span class="chunk" data-chord="Am"></span>Mountains,</p>
CSS
p {
margin-top:20px;
}
span.chunk {
position:relative;
}
span.chunk:before {
content:attr(data-chord);
position:absolute;
top:-15px;
color: red;
}
JavaScript
function getTextWidth(text, font) {
// if given, use cached canvas for better performance
// else, create new canvas
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
var context = canvas.getContext("2d");
context.font = font;
var metrics = context.measureText(text);
return metrics.width;
};
function getCSS( element, property ) {
return window.getComputedStyle( element, null ).getPropertyValue( property );
}
function chordsOverlap(el1, el2) {
const domElement1 = el1.getBoundingClientRect();
const domElement1Text = getTextWidth(el1.getAttribute('data-chord'), getCSS( el1, 'font' ));
const domElement2 = el2.getBoundingClientRect();
const domElement2Text = getTextWidth(el2.getAttribute('data-chord'), getCSS( el2, 'font' ));
return !(
domElement1.top > domElement2.bottom ||
domElement1.left + domElement1Text < domElement2.left ||
domElement1.bottom < domElement2.top ||
domElement1.left > domElement2.left + domElement2Text
);
}
function xOffset(el1,el2) {
const domElement1 = el1.getBoundingClientRect();
const domElement1Text = getTextWidth(el1.getAttribute('data-chord'), getCSS( el1, 'font' ));
const domElement2 = el2.getBoundingClientRect();
const domElement2Text = getTextWidth(el2.getAttribute('data-chord'), getCSS( el2, 'font' ));
return domElement1.left + domElement1Text - domElement2.left;
}
const chords = document.querySelectorAll('span.chunk');
const spaceWidth = getTextWidth('\u00A0', getCSS( chords[0], 'font' ));
function callibrateChords() {
for (let i = 0; i < chords.length - 1; i++) {
let ch1 = chords[i];
let ch2 = chords[i+1];
if (chordsOverlap(ch1, ch2)) {
console.log(i, i+1, true, xOffset(ch1, ch2))
let chordContent = ch2.getAttribute('data-chord');//.replace(/\u00A0/g, '');
//console.log(Math.round(xOffset(ch1, ch2)/spaceWidth))
//console.log('\u00A0'.repeat(Math.round(xOffset(ch1,...