Perfect Circle Drawer

Draws perfect circles dynamically on any webpage.

  1. // ==UserScript==
  2. // @name Perfect Circle Drawer
  3. // @namespace example.com
  4. // @version 1.1
  5. // @description Draws perfect circles dynamically on any webpage.
  6. // @author You
  7. // @match *://*/*
  8. // @grant GM_addStyle
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // --- Configuration ---
  15. const CANVAS_ID = 'perfectCircleCanvas';
  16. const DEFAULT_CANVAS_WIDTH = 800;
  17. const DEFAULT_CANVAS_HEIGHT = 600;
  18. const DEFAULT_CIRCLE_RADIUS = 50;
  19. const DEFAULT_CIRCLE_COLOR = 'rgba(255, 0, 0, 0.6)'; // Red with some transparency
  20.  
  21. // --- Canvas Management ---
  22. function getOrCreateCanvas() {
  23. let canvas = document.getElementById(CANVAS_ID);
  24. if (!canvas) {
  25. canvas = document.createElement('canvas');
  26. canvas.id = CANVAS_ID;
  27. canvas.width = DEFAULT_CANVAS_WIDTH;
  28. canvas.height = DEFAULT_CANVAS_HEIGHT;
  29. // Position the canvas fixed so it overlays content without disrupting layout
  30. canvas.style.position = 'fixed';
  31. canvas.style.top = '0';
  32. canvas.style.left = '0';
  33. canvas.style.zIndex = '9999'; // Ensure it's on top
  34. canvas.style.pointerEvents = 'none'; // Allow clicks to pass through
  35. document.body.appendChild(canvas);
  36. }
  37. return canvas;
  38. }
  39.  
  40. function clearCanvas() {
  41. const canvas = document.getElementById(CANVAS_ID);
  42. if (canvas) {
  43. const ctx = canvas.getContext('2d');
  44. ctx.clearRect(0, 0, canvas.width, canvas.height);
  45. }
  46. }
  47.  
  48. // --- Circle Drawing Function ---
  49. function drawCircle(x, y, radius, color) {
  50. const canvas = getOrCreateCanvas();
  51. const ctx = canvas.getContext('2d');
  52.  
  53. ctx.beginPath();
  54. ctx.arc(x, y, radius, 0, 2 * Math.PI);
  55. ctx.fillStyle = color;
  56. ctx.fill();
  57. ctx.strokeStyle = 'black'; // Add a border for better visibility
  58. ctx.lineWidth = 1;
  59. ctx.stroke();
  60. }
  61.  
  62. // --- UI Elements and Event Listeners ---
  63. function createUI() {
  64. // Create a container for the UI elements
  65. const uiContainer = document.createElement('div');
  66. uiContainer.id = 'circleDrawerUI';
  67. GM_addStyle(`
  68. #circleDrawerUI {
  69. position: fixed;
  70. bottom: 20px;
  71. right: 20px;
  72. background-color: #f0f0f0;
  73. border: 1px solid #ccc;
  74. padding: 10px;
  75. border-radius: 5px;
  76. z-index: 10000;
  77. font-family: sans-serif;
  78. box-shadow: 0 2px 10px rgba(0,0,0,0.2);
  79. }
  80. #circleDrawerUI button {
  81. margin-top: 5px;
  82. padding: 8px 12px;
  83. background-color: #007bff;
  84. color: white;
  85. border: none;
  86. border-radius: 4px;
  87. cursor: pointer;
  88. }
  89. #circleDrawerUI button:hover {
  90. background-color: #0056b3;
  91. }
  92. #circleDrawerUI label {
  93. display: block;
  94. margin-bottom: 5px;
  95. }
  96. #circleDrawerUI input[type="number"],
  97. #circleDrawerUI input[type="color"] {
  98. width: 80px;
  99. margin-bottom: 5px;
  100. }
  101. `);
  102.  
  103. // X, Y, Radius, Color inputs
  104. const xInput = createLabeledInput('X:', 'number', 'circleX', 100);
  105. const yInput = createLabeledInput('Y:', 'number', 'circleY', 100);
  106. const radiusInput = createLabeledInput('Radius:', 'number', 'circleRadius', DEFAULT_CIRCLE_RADIUS);
  107. const colorInput = createLabeledInput('Color:', 'color', 'circleColor', DEFAULT_CIRCLE_COLOR.substring(0, 7)); // Remove alpha for color input
  108.  
  109. // Draw Circle Button
  110. const drawButton = document.createElement('button');
  111. drawButton.textContent = 'Draw Circle';
  112. drawButton.addEventListener('click', function() {
  113. const x = parseInt(xInput.value);
  114. const y = parseInt(yInput.value);
  115. const radius = parseInt(radiusInput.value);
  116. const color = colorInput.value;
  117. drawCircle(x, y, radius, color);
  118. });
  119.  
  120. // Clear Canvas Button
  121. const clearButton = document.createElement('button');
  122. clearButton.textContent = 'Clear All Circles';
  123. clearButton.addEventListener('click', clearCanvas);
  124.  
  125. uiContainer.appendChild(xInput.parentElement); // Append the whole label+input container
  126. uiContainer.appendChild(yInput.parentElement);
  127. uiContainer.appendChild(radiusInput.parentElement);
  128. uiContainer.appendChild(colorInput.parentElement);
  129. uiContainer.appendChild(drawButton);
  130. uiContainer.appendChild(clearButton);
  131.  
  132. document.body.appendChild(uiContainer);
  133. }
  134.  
  135. function createLabeledInput(labelText, type, id, defaultValue) {
  136. const div = document.createElement('div');
  137. const label = document.createElement('label');
  138. label.textContent = labelText;
  139. label.htmlFor = id;
  140. const input = document.createElement('input');
  141. input.type = type;
  142. input.id = id;
  143. input.value = defaultValue;
  144. div.appendChild(label);
  145. div.appendChild(input);
  146. return input; // Return the input element for value retrieval
  147. }
  148.  
  149. // --- Initialize the UI when the page loads ---
  150. window.addEventListener('load', createUI);
  151.  
  152. })();