Hm... Upon closer inspection, this seems to work in CodePen but not when I use this in a Tampermonkey injected userscript. The issue is, that when I inject this, the timeline seems to play once (Colors are set to rainbows) but then it doesn't repeat/animate so there's no change over time.
This is how the code gets called:
if (possible_child.nodeType !== Node.TEXT_NODE) {
new_node.appendChild(possible_child)
} else {
new_node.appendChild(make_text_sinebow(possible_child.nodeValue))
}
function make_text_sinebow(text_to_rainbowify) {
let container_div = document.createElement('div')
container_div.setAttribute('class', 'rainbow')
console.log(container_div)
let split = text_to_rainbowify.split("");
let words = split.reduce(wrapText, container_div);
let chars = words.children;
let total = words.children.length;
let tl = gsap.timeline({repeat: -1})
.set(words, {red: 0})
.to(words, 15, {
red: 255,
modifiers: {
red: function (x) {
console.log(x)
for (let i = 0; i < total; i++) {
let index = i + 25 + x * 0.4;
chars[i].style.color = sinebow(freq, freq, freq, 0, 2, 4, index);
}
return x;
}
}
});
return container_div
}
function wrapText(parent, letter, i) {
let span = document.createElement("span");
span.textContent = letter;
span.style.color = sinebow(freq, freq, freq, 0, 2, 4, i + 25);
console.log(parent)
parent.appendChild(span);
return parent;
}
function sinebow(freq1, freq2, freq3, phase1, phase2, phase3, i) {
let width = 127;
let center = 128;
let r = Math.sin(freq1 * i + phase1) * width + center;
let g = Math.sin(freq2 * i + phase2) * width + center;
let b = Math.sin(freq3 * i + phase3) * width + center;
return `rgb(${r >> 0},${g >> 0},${b >> 0})`;
}