【问题标题】:Color Wheel Picker Canvas javascript色轮选择器画布 javascript
【发布时间】:2017-09-14 08:25:23
【问题描述】:

我想用画布实现这样的目标

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

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

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

【问题讨论】:

    标签: javascript jquery css html canvas


    【解决方案1】:

    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;

    【讨论】:

      【解决方案2】:

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

      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

      【讨论】:

        猜你喜欢
        • 2012-08-13
        • 1970-01-01
        • 2011-10-12
        • 2011-01-29
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 2011-11-02
        • 2023-04-06
        相关资源
        最近更新 更多