Rainbow Cursor

Turn your cursor into a rainbow trail

  1. // ==UserScript==
  2. // @name Rainbow Cursor
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Turn your cursor into a rainbow trail
  6. // @author Jyomama28
  7. // @match *://*/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13. const cursor = document.createElement('div');
  14. cursor.id = 'rainbow-cursor';
  15.  
  16. const trailCount = 20;
  17. const trail = [];
  18. for (let i = 0; i < trailCount; i++) {
  19. const dot = document.createElement('div');
  20. dot.className = 'rainbow-trail-dot';
  21. document.body.appendChild(dot);
  22. trail.push({
  23. element: dot,
  24. x: 0,
  25. y: 0
  26. });
  27. }
  28.  
  29. const style = document.createElement('style');
  30. style.innerHTML = `
  31. html, body {
  32. cursor: none !important;
  33. }
  34. #rainbow-cursor {
  35. position: fixed;
  36. pointer-events: none;
  37. width: 10px;
  38. height: 10px;
  39. background: white;
  40. border-radius: 50%;
  41. box-shadow: 0 0 5px rgba(0,0,0,0.5);
  42. z-index: 9999;
  43. transform: translate(-50%, -50%);
  44. }
  45. .rainbow-trail-dot {
  46. position: fixed;
  47. pointer-events: none;
  48. width: 8px;
  49. height: 8px;
  50. border-radius: 50%;
  51. z-index: 9998;
  52. transform: translate(-50%, -50%);
  53. opacity: 0.8;
  54. transition: width 0.1s, height 0.1s;
  55. }
  56. `;
  57. document.head.appendChild(style);
  58. document.body.appendChild(cursor);
  59.  
  60. let mouseX = 0;
  61. let mouseY = 0;
  62. document.addEventListener('mousemove', (e) => {
  63. mouseX = e.clientX;
  64. mouseY = e.clientY;
  65. cursor.style.left = mouseX + 'px';
  66. cursor.style.top = mouseY + 'px';
  67. });
  68.  
  69. function updateTrail() {
  70.  
  71. for (let i = trail.length - 1; i > 0; i--) {
  72. trail[i].x = trail[i-1].x;
  73. trail[i].y = trail[i-1].y;
  74. }
  75.  
  76. trail[0].x = mouseX;
  77. trail[0].y = mouseY;
  78.  
  79. trail.forEach((dot, index) => {
  80.  
  81. const hue = (Date.now() / 20 + index * 10) % 360;
  82.  
  83. dot.element.style.left = dot.x + 'px';
  84. dot.element.style.top = dot.y + 'px';
  85. dot.element.style.backgroundColor = `hsl(${hue}, 100%, 50%)`;
  86.  
  87. const size = 8 - (index * 0.3);
  88. if (size > 0) {
  89. dot.element.style.width = size + 'px';
  90. dot.element.style.height = size + 'px';
  91. dot.element.style.opacity = 1 - (index / trail.length);
  92. }
  93. });
  94. requestAnimationFrame(updateTrail);
  95. }
  96. updateTrail();
  97.  
  98. window.addEventListener('blur', () => {
  99. cursor.style.display = 'none';
  100. trail.forEach(dot => {
  101. dot.element.style.display = 'none';
  102. });
  103. });
  104. window.addEventListener('focus', () => {
  105. cursor.style.display = 'block';
  106. trail.forEach(dot => {
  107. dot.element.style.display = 'block';
  108. });
  109. });
  110. })();