const tickSpeed = 20; const randomMouseMod = 500; const mouseOffset = [25,25]; const colorLongness = 5; const stepSize = 10; const cloneStep = 20; const shrinkRate = .1; let original = document.getElementById("original"); let id = 0; let mouse = [100,100]; function mouseMove(event) { mouse = [event.clientX, event.clientY]; } document.addEventListener("mousemove", mouseMove); document.addEventListener("touchmove", event => { mouseMove(event.touches[0]); }); document.addEventListener("touchstart", event => { mouseMove(event.touches[0]); }); function hueToRgb(hue, brightness) { hue = hue % 360; let red = 0; let green = 0; let blue = 0; if (hue < 60) { red = 1; green = hue / 60; } else if (hue < 120) { red = 1 - (hue - 60) / 60; green = 1; } else if (hue < 180) { green = 1; blue = (hue - 120) / 60; } else if (hue < 240) { green = 1 - (hue - 180) / 60; blue = 1; } else if (hue < 300) { blue = 1; red = (hue - 240) / 60; } else { blue = 1 - (hue - 300) / 60; red = 1; } return [red*brightness, green*brightness, blue*brightness]; } setInterval(() => { let clone = original.cloneNode(true); clone.id = id.toString(); clone.classList.remove("original"); clone.classList.add("clone"); clone.style.margin = "2px"; const color = hueToRgb(id/colorLongness, 255); const border = hueToRgb(id/colorLongness + 180, 255); clone.style.backgroundColor = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; clone.style.borderColor = `rgb(${border[0]}, ${border[1]}, ${border[2]})` let randomMouse = [mouse[0] + Math.random() * randomMouseMod - randomMouseMod/2, mouse[1] + Math.random() * randomMouseMod - randomMouseMod/2] let relativePos = [randomMouse[0] - parseFloat(original.style.left) - mouseOffset[0], randomMouse[1] - parseFloat(original.style.top) - mouseOffset[1]]; let length = Math.abs(Math.sqrt(relativePos[0]**2 + relativePos[1]**2)); let cossin; if (length > 0) { cossin = [relativePos[0] / length, relativePos[1] / length]; } else { cossin = [0,0]; } original.style.top = (parseFloat(original.style.top) + cossin[1] * stepSize).toString() + "px"; original.style.left = (parseFloat(original.style.left) + cossin[0] * stepSize).toString() + "px"; let interval = setInterval(() => { clone.style.top = (parseFloat(clone.style.top) + Math.random() * cloneStep - cloneStep/2).toString() + "px"; clone.style.left = (parseFloat(clone.style.left) + Math.random() * cloneStep - cloneStep/2).toString() + "px"; clone.style.width = (parseFloat(clone.style.width) - shrinkRate).toString() + "px"; clone.style.height = (parseFloat(clone.style.height) - shrinkRate).toString() + "px"; clone.style.margin = (parseFloat(clone.style.margin) + shrinkRate/2).toString() + "px"; if (parseFloat(clone.style.width) <= 1 || parseFloat(clone.style.height) <= 1) { clone.remove(); clearInterval(interval); } }, tickSpeed); id += 1; original.parentNode.insertBefore(clone, original); }, tickSpeed);