colour wheel

by Ben Gillbanks

HTML

<div class="layout">
<canvas id="color-wheel" width="400" height="400"></canvas>
<input type="range" id="lightness-slider" min="0" max="100" value="50" />
<input type="range" id="saturation-slider" min="0" max="100" value="100" />
<div id="palette"></div>
</div>

CSS

body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
  }
  .color-wheel-container {
    position: relative;
  }
  .color-wheel {
    width: 300px;
    height: 300px;
    border-radius: 50%;
    border: 2px solid black;
    position: relative;
    overflow: hidden;
  }
  .color-option {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    position: absolute;
    cursor: pointer;
    transform: translate(-50%, -50%);
  }
  .layout {
      display: flex;
      gap: 10px;
      flex-direction: column;
  }
  #palette {
      display: flex;
      height: 3rem;
  }
  #palette div {
      flex-grow: 1;
  }

JavaScript

// Function to create a color wheel on a canvas element
function createColorWheel(config) {
  // Retrieve canvas and context
  const canvas = document.getElementById(config.canvasId);
  const ctx = canvas.getContext('2d');

  // Calculate center and radii of the color wheel
  const centerX = canvas.width / 2;
  const centerY = canvas.height / 2;
  const outerRadius = (canvas.width - 2) / 2;
  const innerRadius = outerRadius - config.trackWidth;
  const dragCircleRadius = Math.round(config.trackWidth / 3);
  const dragCircleOffset = (config.trackWidth / 2) - dragCircleRadius;
  const dragCirclePosition = outerRadius - dragCircleRadius - dragCircleOffset;

  let dragCircleAngle = 0; // Initial angle of the draggable circle
  let isDragging = false; // Flag to track if mouse is being dragged
  let lightness = config.initialLightness; // Initial lightness value
  let saturation = config.initialSaturation; // Initial saturation value
  let whitePointsHSL = []; // Array to store HSL values for the white points

  // Function to calculate the positions of white circles based on the palette type
  function calculatePalettePositions(angle, paletteType) {
    const positions = [];
    switch (paletteType) {
      case 'analogous':
        positions.push(angle - 30, angle + 30);
        break;
      case 'complementary':
        positions.push(angle + 180);
        break;
      case 'triadic':
        positions.push(angle + 120, angle + 240);
        break;
      // Add more cases for other palette types as needed
      default:
        break;
    }
    return positions;
  }

  // Function to draw the color wheel and update palette
  function draw() {
    whitePointsHSL = [];
    ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas

    // Draw color wheel
    for (let angle = 0; angle < 360; angle++) {
      let gradient = `hsl(${angle}, ${saturation}%, ${lightness}%)`;

      ctx.beginPath();
      ctx.moveTo(centerX, centerY);
      ctx.arc(centerX, centerY,...