Javascript HTML5画布-在圆上绘制线性渐变(色轮)
我试图画一个圆,不是径向梯度,而是围绕圆的线性梯度。。。基本上,我正在尝试创建一个色轮,它必须是动态的,因为颜色可以自定义。。。然而,我完全困惑于如何处理这件事 我想我可以画我自己的圆并给它上色,然后用一个更大的半径循环这个过程来填充它。但事实证明,这不仅是非常低效的,而且是非常有问题的 这是我的第一次尝试: 我坚持使用这种方法,但改变了它,为圆上的每个点填充一个2x2的正方形。它可以很好地混合3种颜色,但是你开始注意到它的失真 不管怎么说,我一直在继续努力,这就是我现在所拥有的: 我试图实现的是这样的目标: “亮度”从白色到黑色的渐变不是问题,因为我知道,在绘制光谱后,可以通过使用径向渐变来实现。不过,如果能帮我弄清楚如何绘制光谱,我将不胜感激 我甚至在想我可以画一个线性的,然后弯曲变换它,但是没有任何本机函数可以做到这一点,并且可以处理一些超出我技能水平的事情-/ 看看这个: 例如,可以按如下方式设置渐变停止:Javascript HTML5画布-在圆上绘制线性渐变(色轮),javascript,html5-canvas,linear-gradients,radial-gradients,color-wheel,Javascript,Html5 Canvas,Linear Gradients,Radial Gradients,Color Wheel,我试图画一个圆,不是径向梯度,而是围绕圆的线性梯度。。。基本上,我正在尝试创建一个色轮,它必须是动态的,因为颜色可以自定义。。。然而,我完全困惑于如何处理这件事 我想我可以画我自己的圆并给它上色,然后用一个更大的半径循环这个过程来填充它。但事实证明,这不仅是非常低效的,而且是非常有问题的 这是我的第一次尝试: 我坚持使用这种方法,但改变了它,为圆上的每个点填充一个2x2的正方形。它可以很好地混合3种颜色,但是你开始注意到它的失真 不管怎么说,我一直在继续努力,这就是我现在所拥有的: 我试图实现的
h = 360-(ang-start)/(end-start) * 360;
s = '100%';
grad.addColorStop(0, 'hsl('+[h,s,'0%'].join()+')'); //black
grad.addColorStop(.5,'hsl('+[h,s,'50%'].join()+')'); //color
grad.addColorStop(1, 'hsl('+[h,s,'100%'].join()+')');//white
看看这个:
例如,可以按如下方式设置渐变停止:
h = 360-(ang-start)/(end-start) * 360;
s = '100%';
grad.addColorStop(0, 'hsl('+[h,s,'0%'].join()+')'); //black
grad.addColorStop(.5,'hsl('+[h,s,'50%'].join()+')'); //color
grad.addColorStop(1, 'hsl('+[h,s,'100%'].join()+')');//white
我的第一个注意事项是,您链接到的图像包含所有3个组件,它不需要更改,可以只是一个静态图像 我改编了一个项目中的一些代码:
这是按像素进行的,这是精确的,但您可能希望绘制一个轮廓来消除锯齿。它可以调整为使用自定义颜色,而不是插值色调。我的第一个注意事项是,您链接的图像包含所有3个组件,无需更改,可以只是静态图像 我改编了一个项目中的一些代码:
这是按像素进行的,这是精确的,但您可能希望绘制一个轮廓来消除锯齿。它可以调整为使用自定义颜色,而不是插入色调。创建类似于链接图像的内容最好是从HSB转换为RGB,我在上发布了一个示例,但正如您所说,您需要自定义颜色,您需要不同的吗?@Kris您应该将其作为一个答案发布,比我的好多了。@Kris哇!这是一些很好的编码。。。不幸的是,由于我的数学能力不足,我很难理解它。有一天,我希望我能创造出这样的东西。谢谢分享!创建像你链接的图像这样的东西最好通过从HSB转换为RGB来完成,我在上发布了一个例子,但正如你所说的,你需要定制颜色吗?你需要一些不同的东西吗?@Kris你应该把它作为一个答案,它比我的好得多。@Kris哇!这是一些很好的编码。。。不幸的是,由于我的数学能力不足,我很难理解它。有一天,我希望我能创造出这样的东西。谢谢分享!哦,有趣的方法!我喜欢!一定要玩一下这个!啊,我不知道hsl,已经重写了你的第一个计算hsv然后转换成rgb。。。但是谢谢你的更新,这是如此简单!只发现一个问题,在//Knockout下圆弧上的位置应为0,0,因为仍在应用ctx.translate。或者,您可以在翻译之前执行ctx.save,然后在/之前执行另一个ctx.restoreKnockout@user1960364实际上,你可以忽略掉淘汰赛。这是我尝试的第一件事的一部分,不再需要了。哦,有趣的方法!我喜欢!一定要玩一下这个!啊,我不知道hsl,已经重写了你的第一个计算hsv然后转换成rgb。。。但是谢谢你的更新,这是如此简单!只发现一个问题,在//Knockout下圆弧上的位置应为0,0,因为仍在应用ctx.translate。或者,您可以在翻译之前执行ctx.save,然后在/之前执行另一个ctx.restoreKnockout@user1960364实际上,你可以忽略掉淘汰赛。这是我尝试的第一件事的一部分,现在已经不需要了。这是解决我问题的另一个很好的方法!数学是高于我的技能水平,但每像素解决方案的简单性是伟大的!再次感谢分享令人惊讶的是,@shmiddy的方法似乎比另一种解决我的问题的方法快了一点!数学是高于我的技能水平,但每像素解决方案的简单性是伟大的!再次感谢分享令人惊讶的是,@shmiddy的速度似乎稍微快一点
step = Math.PI / 360
ctx.fillRect(0, radius - thickness, radius/10, thickness);
h = 360-(ang-start)/(end-start) * 360;
s = '100%';
grad.addColorStop(0, 'hsl('+[h,s,'0%'].join()+')'); //black
grad.addColorStop(.5,'hsl('+[h,s,'50%'].join()+')'); //color
grad.addColorStop(1, 'hsl('+[h,s,'100%'].join()+')');//white
function drawColourArc(image) {
var data = image.data;
var i = 0;
var w = image.width, h = image.height;
var result = [0, 0, 0, 1];
var outer = 1, inner = 0.5;
var mid = 0.75;
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
var dx = (x / w) - 1, dy = (y / w) - 1;
var angular = ((Math.atan2(dy, dx) + Math.PI) / (2 * Math.PI)) * 4;
var radius = Math.sqrt((dx * dx) + (dy * dy));
if (radius < inner || radius > outer) {
data[i++] = 255;
data[i++] = 255;
data[i++] = 255;
data[i++] = 0;
}
else {
if (radius < mid) {
var saturation = 1;
var brightness = (radius - 0.5) * 4;
}
else {
var saturation = 1- ((radius - 0.75) * 4);
var brightness = 1;
}
result[0] = angular;
result[1] = saturation;
result[2] = brightness;
result[3] = 1;
//Inline HSBToRGB
if (result[1] == 0) {
result[0] = result[1] = result[2] = result[2];
}
else {
var varH = result[0] * 6;
var varI = Math.floor(varH); //Or ... var_i = floor( var_h )
var var1 = result[2] * (1 - result[1]);
var var2 = result[2] * (1 - result[1] * (varH - varI));
var var3 = result[2] * (1 - result[1] * (1 - (varH - varI)));
if (varI == 0 || varI == 6) {
result[0] = result[2];
result[1] = var3;
result[2] = var1;
}
else if (varI == 1) {
result[0] = var2;
result[1] = result[2];
result[2] = var1;
}
else if (varI == 2) {
result[0] = var1;
result[1] = result[2];
result[2] = var3;
}
else if (varI == 3) {
result[0] = var1;
result[1] = var2;
result[2] = result[2];
}
else if (varI == 4) {
result[0] = var3;
result[1] = var1;
result[2] = result[2];
}
else {
result[0] = result[2];
result[1] = var1;
result[2] = var2;
}
}
//End of inline
data[i++] = result[0] * 255;
data[i++] = result[1] * 255;
data[i++] = result[2] * 255;
data[i++] = result[3] * 255;
}
}
}
};
var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext("2d");
var image = ctx.createImageData(canvas.width, canvas.height);
drawColourArc(image);
ctx.putImageData(image, 0, 0);