- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我有一个 raindow HSV 渐变 Canvas ,当您单击它时,会在该位置添加一个元素,其背景为单击像素的颜色。
我想要的是让它也反向工作。例如,如果您有十六进制颜色,我想在 Canvas 上找到该像素并在该位置创建一个元素。
我的第一个想法是以某种方式使用矩阵/象限系统。我的下一个想法是,因为我使用的是 HSV,所以我可以使用我的 HSV 梯度定位点来找出位置。问题是我的观点彼此不等距,这使得它变得更难。最重要的是,我有一个白色渐变和黑色渐变覆盖主颜色渐变,我需要考虑到这一点。
所以我的问题是,如何仅使用十六进制代码找到颜色像素的位置或至少它最接近的匹配?
到目前为止,这是我的代码: http://codepen.io/shelbywhite/pen/EyqPWY?editors=1000
HTML:
<div class="container">
<canvas class="colorSpectrum"></canvas>
<div class="circle"></div>
</div>
CSS:
.container {
background: grey;
height: 350px;
width: 400px;
}
.circle {
background: transparent;
box-shadow: 0 0 8px rgba(0,0,0,0.2);
border-radius: 50%;
border: 2px solid #fff;
height: 20px;
margin: -12px;
width: 20px;
position: absolute;
}
.colorSpectrum {
display: block;
height: 100%;
transform: translateZ(0);
width: 100%;
}
Javascript:
$(function() {
var closest = function(num, arr) {
var curr = arr[0];
var diff = Math.abs(num - curr);
for (var val = 0; val < arr.length; val++) {
var newdiff = Math.abs(num - arr[val]);
if (newdiff < diff) {
diff = newdiff;
curr = arr[val];
}
}
return curr;
};
var container = $('.container');
var containerWidth = container.width();
var containerHeight = container.height();
var verticalGradientsHeight = Math.round(containerHeight * .34);
console.log('verticalGradientsHeight', verticalGradientsHeight);
var round = function(value, decimals) {
return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
};
// Draws the color spectrum onto the canvas
var drawColorSpectrum = function() {
// Cache canvas element
var canvasElement = $('.colorSpectrum');
// Cache javascript element
var canvas = canvasElement[0];
// Get canvas context
var ctx = canvas.getContext('2d');
// Cache page height
var canvasWidth = containerWidth;
// Cache page height
var canvasHeight = containerHeight - 72;
// Bottom gradient start position
var blackStartYPos = canvasHeight - verticalGradientsHeight;
// Bottom gradient end position
var blackEndYPos = canvasHeight;
// Create white gradient element
var white = ctx.createLinearGradient(0, 0, 0, verticalGradientsHeight);
// Create black gradient element
var black = ctx.createLinearGradient(0, blackStartYPos, 0, blackEndYPos);
// Create new instance of image
var img = new Image();
// Cache container
_colorSpectrumContainer = canvasElement.parent();
// Set global var
spectrumCanvas = canvasElement;
// Set width of canvas
canvas.width = canvasWidth;
// Set height of canvas
canvas.height = canvasHeight;
// Image load listener
img.onload = function() {
// Draw intial image
ctx.drawImage(this, 0, 0, canvasWidth, canvasHeight);
// Draw white to transparent gradient
white.addColorStop(0, "hsla(0,0%,100%,1)");
white.addColorStop(0.05, "hsla(0,0%,100%,1)");
white.addColorStop(0.20, "hsla(0,0%,100%,0.89)");
white.addColorStop(0.38, "hsla(0,0%,100%,0.69)");
white.addColorStop(0.63, "hsla(0,0%,100%,0.35)");
white.addColorStop(0.78, "hsla(0,0%,100%,0.18)");
white.addColorStop(0.91, "hsla(0,0%,100%,0.06)");
white.addColorStop(1, "hsla(0,0%,100%,0)");
ctx.fillStyle = white;
ctx.fillRect(0, 0, canvasWidth, verticalGradientsHeight);
// Draw black to transparent gradient
black.addColorStop(0, "hsla(0,0%,0%,0)");
black.addColorStop(0.20, "hsla(0,0%,0%,0.01)");
black.addColorStop(0.28, "hsla(0,0%,0%,0.04)");
black.addColorStop(0.35, "hsla(0,0%,0%,0.09)");
black.addColorStop(0.51, "hsla(0,0%,0%,0.26)");
black.addColorStop(0.83, "hsla(0,0%,0%,0.69)");
black.addColorStop(1, "hsla(0,0%,0%,1)");
ctx.fillStyle = black;
ctx.fillRect(0, blackStartYPos, canvasWidth, verticalGradientsHeight);
}
// Set image source
img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAABCAYAAACbv+HiAAAA0ElEQVR4AYWSh2oDMAwFz6u7//+d2YmXalGBIBM47nnPIIEtmd8FGBTgDbPxDmbn49pX+cZX+Nz4mkZ2SECEAXTCAprlalntBC5whdUJnOfKEy5DjZYtB+o0D3XUMk0tkaZZEn2VuyiJQQQywS/P4c25ucTrfF3ndsoVdjmy3NMiuptR1eHfNcBFM2orW1ZXru00JZiBDrIII5AG5AlloX5TcG6/ywuuv0zAbyL4TWRZmIvU5TNBTjCPIIu5N3YgO7Wxtbot3q4+2LgTyFnZ/QHzBZD1KDpyqQAAAABJRU5ErkJggg==";
};
//
var hexToRgb = function(hex) {
hex = hex.replace('#','');
r = parseInt(hex.substring(0, 2), 16);
g = parseInt(hex.substring(2, 4), 16);
b = parseInt(hex.substring(4, 6), 16);
return [r, g, b];
};
//
var rgbToHsb = function(r, g, b) {
var rr, gg, bb,
r = r / 255,
g = g / 255,
b = b / 255,
h, s,
v = Math.max(r, g, b),
diff = v - Math.min(r, g, b),
diffc = function(c){
return (v - c) / 6 / diff + 1 / 2;
};
if (diff == 0) {
h = s = 0;
} else {
s = diff / v;
rr = diffc(r);
gg = diffc(g);
bb = diffc(b);
if (r === v) {
h = bb - gg;
}else if (g === v) {
h = (1 / 3) + rr - bb;
}else if (b === v) {
h = (2 / 3) + gg - rr;
}
if (h < 0) {
h += 1;
}else if (h > 1) {
h -= 1;
}
}
return {
h: Math.round(h * 360),
s: Math.round(s * 100),
b: Math.round(v * 100)
};
};
// Find hue in stop range
var findHueInStopRange = function(hue) {
// Array of hue stops with HSV, RGB, and HEX info
var stops = [{
h: 0,
l: 0,
s: 100,
b: 100
}, {
h: 60,
l: 21,
s: 100,
b: 100
}, {
h: 120,
l: 40,
s: 85,
b: 85
}, {
h: 180,
l: 56,
s: 85,
b: 85
}, {
h: 237,
l: 72,
s: 86,
b: 96
}, {
h: 300,
l: 89,
s: 86,
b: 96
}, {
h: 359,
l: 100,
s: 100,
b: 100
}];
// Total number of stops
var stopsLength = stops.length;
// Loop through stops
for (var i = 0; i < stopsLength; i += 1) {
// Temp set
var currentStop = stops[i];
// Temp set
// var nextStop = stops[i + 1];
var nextStop = (i + 1 > stopsLength - 1) ? currentStop : stops[i + 1];
// Location is a percentage
var huePos;
// Temp set
var xPos = false;
console.log('hue', currentStop.h, '>>', hue, '<<', nextStop.h);
// Find which range of hue stops the current color is
// Hue is between current and next hue stop
if (hue >= currentStop.h && hue <= nextStop.h) {
// hue is current stop
if (hue === currentStop.h) {
// Set as location
huePos = currentStop.l;
// hue is next stop
} else if (hue === nextStop.h) {
// Set as location
huePos = nextStop.l;
// Hue is somewhere between stops
} else {
// Get percentage location between hue stops
var relativeHuePos = (hue - currentStop.h) / (nextStop.h - currentStop.h);
// Normalized to fit custom gradient stop locations
huePos = relativeHuePos * (nextStop.l - currentStop.l) + currentStop.l;
}
// A location was found
if (huePos) {
// Convert from percentage to pixel position
xPos = Math.round(containerWidth * (huePos / 100));
return xPos;
} else {
continue;
}
}
}
};
// Find saturation in stop range
var findSaturationInStopRange = function (saturation) {
// Array of hue stops with HSV, RGB, and HEX info
var stops = [{
l: 0,
s: 0
}, {
l: 0.05,
s: 6
}, {
l: 0.20,
s: 18
}, {
l: 0.38,
s: 35
}, {
l: 0.63,
s: 69
}, {
l: 0.78,
s: 89,
}, {
l: 0.91,
s: 100,
}, {
l: 1,
s: 100,
}];
// Total number of stops
var stopsLength = stops.length;
// Loop through stops
for (var i = 0; i < stopsLength; i += 1) {
// Temp set
var currentStop = stops[i];
// Temp set
var nextStop = (i + 1 > stopsLength - 1) ? currentStop : stops[i + 1];
// Location is a percentage
var satPos;
// Temp set
var yPos = false;
// Convert location to percentage
var currentStopLocation = currentStop.l * 100;
// Convert location to percentage
var nextStopLocation = nextStop.l * 100;
// Find which range of hue stops the current color is
// Hue is between current and next hue stop
if (saturation >= currentStop.s && saturation <= nextStop.s) {
// hue is current stop
if (saturation === currentStop.s) {
// Set as location
satPos = currentStopLocation;
// hue is next stop
} else if (saturation === nextStop.s) {
// Set as location
satPos = nextStopLocation;
// Hue is somewhere between stops
} else {
// Get percentage location between gradient stops
var ratioBetweenSaturation = (saturation - currentStop.s) / (nextStop.s - currentStop.s);
// Normalized to fit custom gradient stop locations
satPos = ratioBetweenSaturation * (nextStopLocation - currentStopLocation) + currentStopLocation;
}
console.log('ratioBetweenSaturation', ratioBetweenSaturation);
console.log('satPos', satPos);
console.log('saturation', saturation, '>=', currentStop.s, saturation, '<=', nextStop.s);
// A location was found
if (satPos !== false) {
// Convert from percentage to pixel position
yPos = Math.round(verticalGradientsHeight * (satPos / 100));
return yPos;
} else {
continue;
}
}
}
};
// Find brightness in stop range
var findBrightnessInStopRange = function (brightness) {
// Array of hue stops with HSV, RGB, and HEX info
var stops = [{
l: 0,
b: 100
}, {
l: 0.20,
b: 88
}, {
l: 0.28,
b: 69
}, {
l: 0.35,
b: 26
}, {
l: 0.51,
b: 9
}, {
l: 0.83,
b: 4,
}, {
l: 1,
b: 0,
}];
// Total number of stops
var stopsLength = stops.length;
// Loop through stops
for (var i = 0; i < stopsLength; i += 1) {
// Temp set
var currentStop = stops[i];
// Temp set
var nextStop = (i + 1 > stopsLength - 1) ? currentStop : stops[i + 1];
// Location is a percentage
var brightPos;
// Temp set
var yPos = false;
// Convert location to percentage
var currentStopLocation = currentStop.l * 100;
// Convert location to percentage
var nextStopLocation = nextStop.l * 100;
console.log('brightness', brightness, '>=', currentStop.b, brightness, '<=', nextStop.b);
// Find which range of hue stops the current color is
// Hue is between current and next hue stop
if (brightness <= currentStop.b && brightness >= nextStop.b) {
// hue is current stop
if (brightness === currentStop.b) {
// Set as location
brightPos = currentStopLocation;
// hue is next stop
} else if (brightness === nextStop.b) {
// Set as location
brightPos = nextStopLocation;
// Hue is somewhere between stops
} else {
// Get percentage location between gradient stops
var ratioBetweenBrightness = (brightness - currentStop.b) / (nextStop.b - currentStop.b);
// Normalized to fit custom gradient stop locations
brightPos = ratioBetweenBrightness * (nextStopLocation - currentStopLocation) + currentStopLocation;
}
console.log('ratioBetweenBrightness', ratioBetweenBrightness);
console.log('brightPos', brightPos);
console.log('brightness', brightness, '>=', currentStop.b, brightness, '<=', nextStop.b);
// A location was found
if (brightPos !== false) {
// Convert from percentage to pixel position
yPos = Math.round(verticalGradientsHeight * (brightPos / 100));
return yPos;
} else {
continue;
}
}
}
};
// Get coordinates from hue, brightness, saturation
var getColorCoordinates = function (hex) {
// Convert hex to rgb
var rgb = hexToRgb(hex);
console.log('rgb', rgb);
// Convert rgb to hsb
var hsb = rgbToHsb(rgb[0], rgb[1], rgb[2]);
console.log('hsb', hsb);
// Set x position to position of hue
var xPos = findHueInStopRange(hsb.h);
var yPos = 0;
// if 100, get (containerHeight - verticalGradientHeight) + whatever position is set with bottom gradient
//
// Saturation and brightness are both maxed
if (hsb.s === 100 && hsb.b === 100) {
// Set y position at center of container
yPos = containerHeight * 0.5;
} else {
console.log('using nothing', hsb.s, hsb.b);
//
if (hsb.s < 100) {
// Saturation y position (upper quadrant)
yPos = findSaturationInStopRange(hsb.s);
console.log('using saturation', yPos);
} else if (hsb.b < 100) {
// Brightness y position (lower quadrant)
yPos = findBrightnessInStopRange(hsb.b);
console.log('using brightness', yPos);
}
}
return { x: xPos, y: yPos };
}
// Get hue location
var position = false;
// Temp set
var hex = '42ad40';
// Draw gradient
drawColorSpectrum();
// Find x position
position = getColorCoordinates(hex); //91ff26
console.log('location', position);
// Draw line
$('.circle').css({
top: position.y + 'px',
left: position.x + 'px',
background: '#' + hex
});
});
**更新**
我实际上是在 HSV 而不是 HSL 中尝试这样做。除了使用 photoshop 生成平滑渐变外,我没有其他偏好。
此外,我还添加了一个新示例,其中包含我创建的内容。下面的一个投票赞成的答案暗示了如何完成我正在尝试做的事情,但到目前为止我还没有能够成功地做到这一点。
更新的代码会在这个链接,我也更新了上面的代码: http://codepen.io/shelbywhite/pen/EyqPWY?editors=1000
最佳答案
要获取位置,您需要 HSL 值
// global
var RGB = [0,0,0]; // holds the RGB values 0-255
var LSH = [0,0,0]; // holds the LSH values (note H is normalised to 0-255)
var rgbToLSH = function(){
var r = RGB[0]/255;
var g = RGB[1]/255;
var b = RGB[2]/255;
var min = Math.min(r,g,b);
var max = Math.max(r,g,b);
var lum = (min+max)/2;
if(lum > 0.5){
var sat = (max-min)/(max+min);
}else{
var sat = (max-min)/(2-max-min);
}
if(r >= b && r >= g){
var hue = (g-b)/(max-min);
}else
if(b >= b && b >= g){
var hue = 4.0 + (r-g)/(max-min);
}else{
var hue = 2.0 + (b-r)/(max-min);
}
hue *= 60;
if(hue < 0) hue += 360;
hue = (hue/360);
lum = Math.min(1,Math.max(0,lum));
sat = Math.min(1,Math.max(0,sat));
hue = Math.min(1,Math.max(0,hue));
LSH[0] = lum*255;
LSH[1] = sat*255;
LSH[2] = hue*255;
}
Hue 会给出 x 轴上的位置,Saturation 会给出从顶部到中间的 y 轴,Lightness 会给出从中间到底部的 y 轴位置(以你的例子为例);
关于javascript - 使用 Javascript 基于十六进制颜色计算渐变上的 X、Y 像素位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39171824/
我正在阅读 java swing,但在理解它时遇到问题。 Color 是一个类吗? Color[] col= {Color.RED,Color.BLUE}; 这在java中是什么意思? 最佳答案 Is
我正在研究用 python 编写的 pacman 程序。其中一个模块是处理吃 bean 游戏的图形表示。这当然是一些主机颜色。列表如下: GHOST_COLORS = [] ## establishe
本网站:http://pamplonaenglishteacher.com 源代码在这里:https://github.com/Yorkshireman/pamplona_english_teache
我最近将我的手机更新为 Android Marshmallow 并在其上运行了我现有的应用程序,但注意到颜色行为有所不同:将更改应用到 View (可绘制)的背景时,共享相同背景的所有 View (引
所有 X11/w3c 颜色代码在 Android XML 资源文件格式中是什么样的? I know this looks a tad ridiculous as a question, but giv
试图让 ffmpeg 创建音频波形,同时能够控制图像大小、颜色和幅度。我已经尝试过这个(以及许多变体),但它只是返回无与伦比的 "。 ffmpeg -i input -filter_complex "
我很好奇你是否有一些关于 R 中颜色酿造的技巧,对于许多独特的颜色,以某种方式使图表仍然好看。 我需要大量独特的颜色(至少 24 种,可能需要更多,~50 种)用于堆叠区域图(所以不是热图,渐变色不起
我看到的许多 WPF 示例和示例似乎都有硬编码的颜色。这些指南 - http://msdn.microsoft.com/en-us/library/aa350483.aspx建议不要硬编码颜色。在构建
我想更改文件夹的默认蓝色 如何设置? 最佳答案 :hi Directory guifg=#FF0000 ctermfg=red 关于Vim NERDTree 颜色,我们在Stack Overflow上
是否有关于如何将任意字符串哈希为 RGB 颜色值的最佳实践?或者更一般地说:3 个字节。 你问:我什么时候需要这个?这对我来说并不重要,但想象一下任何 GitHub 上的那些管图 network pa
我正在尝试将默认颜色设置为自定义窗口小部件。 这是有问题的代码。 class ReusableCard extends StatelessWidget { ReusableCard({this.
import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.Ta
我有一个 less 文件来定义一堆颜色/颜色。每个类名都包含相关颜色的名称,例如 .colourOrange{..} 或 .colourBorderOrange{..} 或 navLeftButtOr
我有一个RelativeLayout,我需要一个黑色背景和一个位于其中间的小图像。我使用了这段代码: 其中@drawable/bottom_box_back是: 这样我就可以将图像居中了。但背
我需要设置 浅色 的 JPanel 背景,只是为了不覆盖文本(粗体黑色)。 此刻我有这个: import java.util.Random; .... private Random random =
我正在尝试制作一个自定义文本编辑器,可以更改特定键入单词的字体和颜色。如何更改使用光标突出显示的文本的字体和/或颜色? 我还没有尝试过突出显示部分。我尝试获取整个 hEdit(HWND) 区域并更改字
我想改变我整个应用程序的颜色。 在我的 AndroidManfiest.xml 中,我有正确的代码: 在 values 文件夹中,我有 app_theme.xml: @style/MyAc
是否可以使用 android 数据绑定(bind)从 xml 中引用颜色? 这很好用: android:textColor="@{inputValue == null ? 0xFFFBC02D : 0
有没有办法在 Android 应用程序中设置“空心”颜色? 我的意思是我想要一个带有某种背景的框,而文本实际上会导致背景透明。换句话说,如果整个 View 在蓝色背景上,文本将是蓝色的,如果它是红色的
我用CGContextStrokePath画在白色背景图片中的一条直线上,描边颜色为红色,alpha为1.0画线后,为什么点不是(255, 0, 0),而是(255, 96, 96)为什么不是纯红色?
我是一名优秀的程序员,十分优秀!