简体   繁体   English

如何更改我的画布色轮,使其边缘像 CSS 版本一样平滑?

[英]How could I change my canvas color wheel so that its edges are smooth like the CSS version?

How could I change my canvas so that it's smooth (I think it's called anti-aliased) like the CSS version?我怎样才能改变我的画布,使它像 CSS 版本一样平滑(我认为它被称为抗锯齿)?

在此处输入图片说明

 // https://codepen.io/private_akongkj/pen/RwRMzqY?editors=1010 came from https://codepen.io/bantic/pen/zNKopG?editors=0010 and https://medium.com/@bantic/hand-coding-a-color-wheel-with-canvas-78256c9d7d43 function xy2polar(x, y) { const r = Math.sqrt(x * x + y * y); const phi = Math.atan2(y, x); return [r, phi]; } // rad in [-π, π] range // return degree in [0, 360] range function rad2deg(rad) { return ((rad + Math.PI) / (2 * Math.PI)) * 360; } function createColorWheel(canvas) { console.log('createColorWheel(canvas)', canvas); const ctx = canvas.getContext('2d'); const radius = canvas.width / 2; const image = ctx.createImageData(2 * radius, 2 * radius); const data = image.data; for (let x = -radius; x < radius; x++) { for (let y = -radius; y < radius; y++) { const [r, phi] = xy2polar(x, y); if (r > radius) { // skip all (x,y) coordinates that are outside of the circle continue; } const deg = rad2deg(phi); // Figure out the starting index of this pixel in the image data array. const rowLength = 2 * radius; const adjustedX = x + radius; // convert x from [-50, 50] to [0, 100] (the coordinates of the image data array) const adjustedY = y + radius; // convert y from [-50, 50] to [0, 100] (the coordinates of the image data array) const pixelWidth = 4; // each pixel requires 4 slots in the data array const index = (adjustedX + adjustedY * rowLength) * pixelWidth; const hue = deg; const saturation = 1.0; const value = 1.0; const [red, green, blue] = hsv2rgb(hue, saturation, value); const alpha = 255; data[index] = red; data[index + 1] = green; data[index + 2] = blue; data[index + 3] = alpha; } } ctx.putImageData(image, 0, 0); } // hue in range [0, 360] // saturation, value in range [0,1] // return [r,g,b] each in range [0,255] // See: https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV function hsv2rgb(hue, saturation, value) { const chroma = value * saturation; const hue1 = hue / 60; const x = chroma * (1 - Math.abs((hue1 % 2) - 1)); let r1, g1, b1; if (hue1 >= 0 && hue1 <= 1) { [r1, g1, b1] = [chroma, x, 0]; } else if (hue1 >= 1 && hue1 <= 2) { [r1, g1, b1] = [x, chroma, 0]; } else if (hue1 >= 2 && hue1 <= 3) { [r1, g1, b1] = [0, chroma, x]; } else if (hue1 >= 3 && hue1 <= 4) { [r1, g1, b1] = [0, x, chroma]; } else if (hue1 >= 4 && hue1 <= 5) { [r1, g1, b1] = [x, 0, chroma]; } else if (hue1 >= 5 && hue1 <= 6) { [r1, g1, b1] = [chroma, 0, x]; } const m = value - chroma; const [r, g, b] = [r1 + m, g1 + m, b1 + m]; // Change r,g,b values from [0,1] to [0,255] return [255 * r, 255 * g, 255 * b]; } createColorWheel(document.getElementById('canvas'));
 #wheel { width: 100px; height: 100px; border-radius: 50%; background: conic-gradient(rgb(255, 0, 0), rgb(255, 255, 0), rgb(0, 255, 0), rgb(0, 255, 255), rgb(0, 0, 255), rgb(255, 0, 255), rgb(255, 0, 0)); transform: rotate(270deg); display: inline-block; }
 <div id="wheel"></div><canvas id="canvas" width="100" height="100"></canvas>

Composite your aliased circle with an anti-aliased one:将您的锯齿圈与抗锯齿圈合成

 // https://codepen.io/private_akongkj/pen/RwRMzqY?editors=1010 came from https://codepen.io/bantic/pen/zNKopG?editors=0010 and https://medium.com/@bantic/hand-coding-a-color-wheel-with-canvas-78256c9d7d43 function xy2polar(x, y) { const r = Math.sqrt(x * x + y * y); const phi = Math.atan2(y, x); return [r, phi]; } // rad in [-π, π] range // return degree in [0, 360] range function rad2deg(rad) { return ((rad + Math.PI) / (2 * Math.PI)) * 360; } function createColorWheel(canvas) { console.log('createColorWheel(canvas)', canvas); const ctx = canvas.getContext('2d'); const radius = canvas.width / 2; const image = ctx.createImageData(2 * radius, 2 * radius); const data = image.data; for (let x = -radius; x < radius; x++) { for (let y = -radius; y < radius; y++) { const [r, phi] = xy2polar(x, y); if (r > radius) { // skip all (x,y) coordinates that are outside of the circle continue; } const deg = rad2deg(phi); // Figure out the starting index of this pixel in the image data array. const rowLength = 2 * radius; const adjustedX = x + radius; // convert x from [-50, 50] to [0, 100] (the coordinates of the image data array) const adjustedY = y + radius; // convert y from [-50, 50] to [0, 100] (the coordinates of the image data array) const pixelWidth = 4; // each pixel requires 4 slots in the data array const index = (adjustedX + adjustedY * rowLength) * pixelWidth; const hue = deg; const saturation = 1.0; const value = 1.0; const [red, green, blue] = hsv2rgb(hue, saturation, value); const alpha = 255; data[index] = red; data[index + 1] = green; data[index + 2] = blue; data[index + 3] = alpha; } } ctx.putImageData(image, 0, 0); // apply antialias ctx.beginPath(); ctx.arc(radius+0.5, radius+0.5, radius-0.5, 0, Math.PI*2); ctx.globalCompositeOperation = "destination-in"; ctx.fill(); // revert to defaults ctx.globalCompositeOperation = "source-over"; } // hue in range [0, 360] // saturation, value in range [0,1] // return [r,g,b] each in range [0,255] // See: https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV function hsv2rgb(hue, saturation, value) { const chroma = value * saturation; const hue1 = hue / 60; const x = chroma * (1 - Math.abs((hue1 % 2) - 1)); let r1, g1, b1; if (hue1 >= 0 && hue1 <= 1) { [r1, g1, b1] = [chroma, x, 0]; } else if (hue1 >= 1 && hue1 <= 2) { [r1, g1, b1] = [x, chroma, 0]; } else if (hue1 >= 2 && hue1 <= 3) { [r1, g1, b1] = [0, chroma, x]; } else if (hue1 >= 3 && hue1 <= 4) { [r1, g1, b1] = [0, x, chroma]; } else if (hue1 >= 4 && hue1 <= 5) { [r1, g1, b1] = [x, 0, chroma]; } else if (hue1 >= 5 && hue1 <= 6) { [r1, g1, b1] = [chroma, 0, x]; } const m = value - chroma; const [r, g, b] = [r1 + m, g1 + m, b1 + m]; // Change r,g,b values from [0,1] to [0,255] return [255 * r, 255 * g, 255 * b]; } createColorWheel(document.getElementById('canvas'));
 #wheel { width: 100px; height: 100px; border-radius: 50%; background: conic-gradient(rgb(255, 0, 0), rgb(255, 255, 0), rgb(0, 255, 0), rgb(0, 255, 255), rgb(0, 0, 255), rgb(255, 0, 255), rgb(255, 0, 0)); transform: rotate(270deg); display: inline-block; }
 <div id="wheel"></div><canvas id="canvas" width="100" height="100"></canvas>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么[my] CSS3 / jQuery转换得如此不完美,如何使它们更加流畅? - Why are [my] CSS3/jQuery transitions so imperfectly smooth, and how do I make them more smooth? 画布线边缘不光滑。 如何解决这个问题? - Canvas line edges not smooth. How to fix this? Javascript画布颜色亮度不平滑变化 - Javascript canvas color not smooth change in brightness 如何更改按钮的颜色,以便在使用jQuery单击按钮时将其更改为另一种颜色? - How do I change the color of a button so that it changes to another color when its clicked using jQuery? 如何更改Farbtastic拾色轮的宽度和高度? - How can I change the width and height of Farbtastic Color Picker Wheel? 如何用圆弧平滑在画布中绘制的圆的边缘? - How to smooth out edges of circles drawn in canvas with arc? 如何重新绘制背景,使其看起来像我的“播放器”在html5-画布中移动 - How do I redraw the background, so it will look like my “player” moving in html5-canvas 是否可以覆盖时钟功能以便我可以更改其小时数? - Is it possible to override a clock function so I could change its hours? 如何创建一个有很多圆圈的表格,以便我可以更改任何圆圈的背景颜色? - How to create a form with many circles so that I could change the background-color of any circle? 如何修改CSS,以便可以在DOM中以特定颜色显示元素? - How do I modify my CSS so that I can display an element in the DOM with a specific color?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM