aki*_*uri 3 javascript canvas color-picker linear-gradients pixel-manipulation
我正在尝试在画布上绘制以下渐变图像,但是右下角存在问题。
所需效果:
电流输出:
我可能在这里错过了一些非常简单的事情。
function color(r, g, b) {
var args = Array.prototype.slice.call(arguments);
if (args.length == 1) {
args.push(args[0]);
args.push(args[0]);
} else if (args.length != 3 && args.length != 4) {
return;
}
return "rgb(" + args.join() + ")";
}
function drawPixel(x, y, fill) {
var fill = fill || "black";
context.beginPath();
context.rect(x, y, 1, 1);
context.fillStyle = fill;
context.fill();
context.closePath();
}
var canvas = document.getElementById("primary");
var context = canvas.getContext("2d");
canvas.width = 256;
canvas.height = 256;
for (var x = 0; x < canvas.width; x++) {
for (var y = 0; y < canvas.height; y++) {
var r = 255 - y;
var g = 255 - x - y;
var b = 255 - x - y;
drawPixel(x, y, color(r, g, b));
}
}Run Code Online (Sandbox Code Playgroud)
#primary {
display: block;
border: 1px solid gray;
}Run Code Online (Sandbox Code Playgroud)
<canvas id="primary"></canvas>Run Code Online (Sandbox Code Playgroud)
您可以让GPU为您完成大部分处理.2D合成运算可multiply有效地将每个像素的两种颜色相乘。因此,对于每个通道和每个像素colChanDest = Math.floor(colChanDest * (colChanSrc / 255)),都是通过GPU的大规模并行处理能力完成的,而不是通过在单个内核(JavaScript执行上下文)上运行的共享程度较低的线程来完成的。
一是背景从上到下从白到黑
var gradB = ctx.createLinearGradient(0,0,0,255);
gradB.addColorStop(0,"white");
gradB.addColorStop(1,"black");
另一个是从左到右从透明到不透明的色相
var swatchHue
var col = "rgba(0,0,0,0)"
var gradC = ctx.createLinearGradient(0,0,255,0);
gradC.addColorStop(0,``hsla(${hueValue},100%,50%,0)``);
gradC.addColorStop(1,``hsla(${hueValue},100%,50%,1)``);
请注意,上述字符串引号在SO上无法正确呈现,因此我将它们加倍显示,使用演示代码段中的单引号。
然后将两者叠加,首先是背景(灰度),然后使用合成操作“相乘”
ctx.fillStyle = gradB;
ctx.fillRect(0,0,255,255);
ctx.fillStyle = gradC;
ctx.globalCompositeOperation = "multiply";
ctx.fillRect(0,0,255,255);
ctx.globalCompositeOperation = "source-over";
Run Code Online (Sandbox Code Playgroud)
颜色(色相)是纯色值很重要,不能使用随机的rgb值。如果选择了rgb值,则需要从rgb中提取色相值。
以下函数会将RGB值转换为HSL颜色
function rgbToLSH(red, green, blue, result = {}){
value hue, sat, lum, min, max, dif, r, g, b;
r = red/255;
g = green/255;
b = blue/255;
min = Math.min(r,g,b);
max = Math.max(r,g,b);
lum = (min+max)/2;
if(min === max){
hue = 0;
sat = 0;
}else{
dif = max - min;
sat = lum > 0.5 ? dif / (2 - max - min) : dif / (max + min);
switch (max) {
case r:
hue = (g - b) / dif;
break;
case g:
hue = 2 + ((b - r) / dif);
break;
case b:
hue = 4 + ((r - g) / dif);
break;
}
hue *= 60;
if (hue < 0) {
hue += 360;
}
}
result.lum = lum * 255;
result.sat = sat * 255;
result.hue = hue;
return result;
}
Run Code Online (Sandbox Code Playgroud)
该示例每3秒呈现一个随机的红色,绿色,蓝色值的色板。
请注意,此示例使用Balel,以便它将在IE上运行
ctx.fillStyle = gradB;
ctx.fillRect(0,0,255,255);
ctx.fillStyle = gradC;
ctx.globalCompositeOperation = "multiply";
ctx.fillRect(0,0,255,255);
ctx.globalCompositeOperation = "source-over";
Run Code Online (Sandbox Code Playgroud)
要从x和y坐标计算颜色,您需要计算出的色相,然后是饱和度和值才能获得hsv颜色(注意hsl和hsv是不同的颜色模型)
// saturation and value are clamped to prevent rounding errors creating wrong colour
var rgbArray = hsv_to_rgb(
hue, // as used to create the swatch
Math.max(0, Math.min(1, x / 255)),
Math.max(0, Math.min(1, 1 - y / 255))
);
Run Code Online (Sandbox Code Playgroud)
用于获取h,s,v颜色的r,g,b值的函数。
function rgbToLSH(red, green, blue, result = {}){
value hue, sat, lum, min, max, dif, r, g, b;
r = red/255;
g = green/255;
b = blue/255;
min = Math.min(r,g,b);
max = Math.max(r,g,b);
lum = (min+max)/2;
if(min === max){
hue = 0;
sat = 0;
}else{
dif = max - min;
sat = lum > 0.5 ? dif / (2 - max - min) : dif / (max + min);
switch (max) {
case r:
hue = (g - b) / dif;
break;
case g:
hue = 2 + ((b - r) / dif);
break;
case b:
hue = 4 + ((r - g) / dif);
break;
}
hue *= 60;
if (hue < 0) {
hue += 360;
}
}
result.lum = lum * 255;
result.sat = sat * 255;
result.hue = hue;
return result;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
789 次 |
| 最近记录: |