色轮选择器画布javascript

问题描述 投票:-5回答:2

我想用帆布来实现这样的东西

Color Wheel

我想要实现的是我可以像这样生成色轮

$("#id").colorWheel({
  width: 200,
  height: 200
});

我已经尝试谷歌它,我找不到一个完美的色轮选择器,我只需要没有任何滑块的色轮,我已经尝试iro js,但我不能从插件中删除滑块,可以有人帮助我用javascript / Jquery和canvas创建这个色轮?

javascript jquery css html5 canvas
2个回答
3
投票

codereview.stackexchange.com上有一个问题的答案:https://codereview.stackexchange.com/questions/69887/drawing-a-color-wheel-faster

只是为了好玩,这是一个实现:

/**
 * degreesToRadians
 *
 * @param {number} degrees
 * @returns {number}  radians
 */
function degreesToRadians(degrees) {
    return degrees * (Math.PI / 180);
}
/**
 * generateColorWheel
 *
 * @param {number} [size=400]
 * @param {string} [centerColor="white"]
 * @returns {HTMLCanvasElement}
 */
function generateColorWheel(size, centerColor) {
    if (size === void 0) { size = 400; }
    if (centerColor === void 0) { centerColor = "white"; }
    //Generate main canvas to return
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    canvas.width = canvas.height = size;
    //Generate canvas clone to draw increments on
    var canvasClone = document.createElement("canvas");
    canvasClone.width = canvasClone.height = size;
    var canvasCloneCtx = canvasClone.getContext("2d");
    //Initiate variables
    var angle = 0;
    var hexCode = [255, 0, 0];
    var pivotPointer = 0;
    var colorOffsetByDegree = 4.322;
    //For each degree in circle, perform operation
    while (angle++ < 360) {
        //find index immediately before and after our pivot
        var pivotPointerbefore = (pivotPointer + 3 - 1) % 3;
        var pivotPointerAfter = (pivotPointer + 3 + 1) % 3;
        //Modify colors
        if (hexCode[pivotPointer] < 255) {
            //If main points isn't full, add to main pointer
            hexCode[pivotPointer] = (hexCode[pivotPointer] + colorOffsetByDegree > 255 ? 255 : hexCode[pivotPointer] + colorOffsetByDegree);
        }
        else if (hexCode[pivotPointerbefore] > 0) {
            //If color before main isn't zero, subtract
            hexCode[pivotPointerbefore] = (hexCode[pivotPointerbefore] > colorOffsetByDegree ? hexCode[pivotPointerbefore] - colorOffsetByDegree : 0);
        }
        else if (hexCode[pivotPointer] >= 255) {
            //If main color is full, move pivot
            hexCode[pivotPointer] = 255;
            pivotPointer = (pivotPointer + 1) % 3;
        }
        //clear clone
        canvasCloneCtx.clearRect(0, 0, size, size);
        //Generate gradient and set as fillstyle
        var grad = canvasCloneCtx.createRadialGradient(size / 2, size / 2, 0, size / 2, size / 2, size / 2);
        grad.addColorStop(0, centerColor);
        grad.addColorStop(1, "rgb(" + hexCode.map(function (h) { return Math.floor(h); }).join(",") + ")");
        canvasCloneCtx.fillStyle = grad;
        //draw full circle with new gradient
        canvasCloneCtx.globalCompositeOperation = "source-over";
        canvasCloneCtx.beginPath();
        canvasCloneCtx.arc(size / 2, size / 2, size / 2, 0, Math.PI * 2);
        canvasCloneCtx.closePath();
        canvasCloneCtx.fill();
        //Switch to "Erase mode"
        canvasCloneCtx.globalCompositeOperation = "destination-out";
        //Carve out the piece of the circle we need for this angle
        canvasCloneCtx.beginPath();
        canvasCloneCtx.arc(size / 2, size / 2, 0, degreesToRadians(angle + 1), degreesToRadians(angle + 1));
        canvasCloneCtx.arc(size / 2, size / 2, size / 2 + 1, degreesToRadians(angle + 1), degreesToRadians(angle + 1));
        canvasCloneCtx.arc(size / 2, size / 2, size / 2 + 1, degreesToRadians(angle + 1), degreesToRadians(angle - 1));
        canvasCloneCtx.arc(size / 2, size / 2, 0, degreesToRadians(angle + 1), degreesToRadians(angle - 1));
        canvasCloneCtx.closePath();
        canvasCloneCtx.fill();
        //Draw carved-put piece on main canvas
        ctx.drawImage(canvasClone, 0, 0);
    }
    //return main canvas
    return canvas;
}
//TEST
//Get color wheel canvas
var colorWheel = generateColorWheel(300);
//Add color wheel canvas to document
document.body.appendChild(colorWheel);
//Add ouput field
var p = document.body.appendChild(document.createElement("p"));
/**
 * colorWheelMouse
 *
 * @param {MouseEvent} evt
 */
function colorWheelMouse(evt) {
    var ctx = colorWheel.getContext("2d");
    var data = ctx.getImageData(evt.offsetX, evt.offsetY, 1, 1);
    p.innerHTML = "RGB: " + data.data.slice(0, 3).join(',');
}
//Bind mouse event
colorWheel.onmousemove = colorWheelMouse;

0
投票

我创建了上面接受的答案的简化版本。

function degreesToRadians(degrees) {
  return degrees * (Math.PI / 180);
}

function drawColorWheel(canvas, size = 150) {
  const context = canvas.getContext('2d');
  canvas.width = size;
  canvas.height = size;

  const centerColor = 'white';

  // Initiate variables
  let angle = 0;
  const hexCode = [0, 0, 255];
  let pivotPointer = 0;
  const colorOffsetByDegree = 4.322;
  const radius = size / 2;

  // For each degree in circle, perform operation
  while (angle < 360) {
    // find index immediately before and after our pivot
    const pivotPointerbefore = (pivotPointer + 3 - 1) % 3;

    // Modify colors
    if (hexCode[pivotPointer] < 255) {
      // If main points isn't full, add to main pointer
      hexCode[pivotPointer] =
        hexCode[pivotPointer] + colorOffsetByDegree > 255 ?
        255 :
        hexCode[pivotPointer] + colorOffsetByDegree;
    } else if (hexCode[pivotPointerbefore] > 0) {
      // If color before main isn't zero, subtract
      hexCode[pivotPointerbefore] =
        hexCode[pivotPointerbefore] > colorOffsetByDegree ?
        hexCode[pivotPointerbefore] - colorOffsetByDegree :
        0;
    } else if (hexCode[pivotPointer] >= 255) {
      // If main color is full, move pivot
      hexCode[pivotPointer] = 255;
      pivotPointer = (pivotPointer + 1) % 3;
    }

    const rgb = `rgb(${hexCode.map(h => Math.floor(h)).join(',')})`;
    const grad = context.createRadialGradient(
      radius,
      radius,
      0,
      radius,
      radius,
      radius
    );
    grad.addColorStop(0, centerColor);
    grad.addColorStop(1, rgb);
    context.fillStyle = grad;

    // draw circle portion
    context.globalCompositeOperation = 'source-over';
    context.beginPath();
    context.moveTo(radius, radius);
    context.arc(
      radius,
      radius,
      radius,
      degreesToRadians(angle),
      degreesToRadians(360)
    );
    context.closePath();
    context.fill();
    angle++;
  }
}

const canvas = document.getElementById('canvas');

drawColorWheel(canvas, 150);

https://codepen.io/Dianoga/pen/BbKawE

© www.soinside.com 2019 - 2024. All rights reserved.