The only thing to say again: You are simply genious. Thank you so much. This is something I can work with. Thanks!!
Thank you hugobox. Will have a closer look at that. Actually I need HSV, but as far as I know, there are conversion tools in terms of a third party contrib-node. But I think this can be managed.
Dear hugobox,
I am now focusing on your solution. Actually your code lines are more comprehensible for me than hotNipis (Please don't get me wrong hotNipi, your approaches motivated me to continue at all).
However, I have still some smaller issues (see example at the bottom of this post):
When moving the slider via dashoboard using the browser on my home pc the message payload is generated as expected. However, when using the slider on my android smartphone (chrome) than no payload is produced. What is the reason for that ?
As you can see in my example below, the slider produces a message payload containing the rgb values but also the hsl values. But if i manually inject an rgb value (with the inject node) than the payload contains only the rgb value. How can I make that the hsl value is also considered ?
Lastly, a cosmetic issue: When moving the slider to the most right edge (red) it automatically jumps to the most left edge (red), how can I prevent this ? This of course doesn't disturb the functionality, but feels a bit unnatural.
Thank you all so far for the very kind support.
[{"id":"4ea00932.2f9ba8","type":"inject","z":"51235c6b.bd5bb4","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"1","topic":"","payload":"","payloadType":"date","x":145,"y":980,"wires":[["feb57ae1.b1ba88"]],"l":false},{"id":"feb57ae1.b1ba88","type":"function","z":"51235c6b.bd5bb4","name":"inject","func":"// create a random rgb colour\n\n/*msg.payload = { \"title\":\"Demo\",\n \"red\": Math.floor(Math.random() * (255) ),\n \"green\": Math.floor(Math.random() * (255) ),\n \"blue\": Math.floor(Math.random() * (255) )\n}*/\n\nmsg.payload = { \"title\":\"Demo\",\n \"red\": 0 ,\n \"green\": 255 ,\n \"blue\": 255 \n}\n\n\nreturn msg;\n\n\n/*\n// Random Hex color\nmsg.payload = { \"title\":\"Demo\",\n \"hexcolor\": \"#\" + Math.floor(Math.random()*16777215).toString(16)\n}\n*/\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":980,"wires":[["b2c1b38.7e5b55"]]},{"id":"b2c1b38.7e5b55","type":"ui_template","z":"51235c6b.bd5bb4","group":"fa62adc1.37cf8","name":"alternativ","order":1,"width":0,"height":0,"format":"<style>\n.slidecontainer {\n\t/* font-size: 80%; */\n\twidth: 100%;\n}\n\n.slidecontainer input {\n\tmargin-bottom:11px;\n}\n/* slider bar */\n\n.slider {\n -webkit-appearance: none;\n width: 98%;\n height: 14px;\n border-radius: 18px;\n outline: none;\n padding: 0px 2px;\n}\n\n.spectrum {\n border-radius:10px;\n background: linear-gradient(\n to right,\n rgb(255 0 0),\n rgb(255 255 0),\n rgb(0 255 0),\n rgb(0 255 255),\n rgb(0 0 255),\n rgb(255 0 255),\n rgb(255 0 0)\n );\n}\n\n/* slider knopf */\n.slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: rgba({{msg.payload.red}},{{msg.payload.green}},{{msg.payload.blue}},1);\n border: 2px solid white;\n cursor: pointer;\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n}\n\n</style>\n\n<div class=\"slidecontainer\">\n\tRGB ({{msg.payload.red}},{{msg.payload.green}},{{msg.payload.blue}})\n\t<input type=\"range\" min=\"0\" max=\"255\" class=\"slider spectrum\" ng-model=\"sliderValue\" ng-change=\"test()\" ng-mouseup=\"send(msg)\">\n</div>\n\n<script>\n \n(function($scope) {\n\nfunction rgbToHsl(r, g, b){\n r /= 255, g /= 255, b /= 255;\n var max = Math.max(r, g, b), min = Math.min(r, g, b);\n var h, s, l = (max + min) / 2;\n\n if(max == min){\n h = s = 0; // achromatic\n }else{\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch(max){\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n\n return [h, s, l];\n \n}\n \nfunction hslToRgb(h, s, l){\n var r, g, b;\n if(s == 0){\n r = g = b = l; // achromatic\n }else{\n var hue2rgb = function hue2rgb(p, q, t){\n if(t < 0) t += 1;\n if(t > 1) t -= 1;\n if(t < 1/6) return p + (q - p) * 6 * t;\n if(t < 1/2) return q;\n if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n }\n\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = hue2rgb(p, q, h + 1/3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1/3);\n }\n \n return {\"red\":Math.round(r * 255), \"green\": Math.round(g * 255), \"blue\": Math.round(b * 255),\"h\":Math.round(h * 360),\"s\":s,\"l\":l};\n}\n\n$scope.test = function(){\n $scope.msg.payload = hslToRgb($scope.sliderValue/255,1,0.5)\n}\n scope.$watch('msg', function(msg) {\n if (msg) {\n $scope.sliderValue = rgbToHsl($scope.msg.payload.red,$scope.msg.payload.green,$scope.msg.payload.blue)[0]*255\n }\n });\n \n})(scope);\n\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":530,"y":980,"wires":[["441d3c35.f0b1e4"]]},{"id":"441d3c35.f0b1e4","type":"debug","z":"51235c6b.bd5bb4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":680,"y":980,"wires":[]},{"id":"fa62adc1.37cf8","type":"ui_group","name":"alternativ","tab":"6b520bda.e997a4","order":4,"disp":true,"width":8,"collapse":false},{"id":"6b520bda.e997a4","type":"ui_tab","name":"Experimentieren","icon":"dashboard","order":7,"disabled":false,"hidden":false}]
As to the first issue (compared to mouse action moving slider on touchscreen doesn't produce payload) I found that I should use ng-touchend="send(msg)"
However, for some reason it doesn't work, when I replace 'ng-mouseup' with ng-touchend in the following line.
<input type="range" min="0" max="255" class="slider spectrum" ng-model="sliderValue" ng-change="test()" ng-mouseup="send(msg)" >
Any help is really appreciated.
Please, I really worry about that all the efforts made here will becoming worthless.
There is one remaining issue which I am not able to solve.
The slider (see code below) doesn't produce any payload when used on a touch screen (android phone, chrome. I don't have this issue on my desktop PC.
[{"id":"4ea00932.2f9ba8","type":"inject","z":"51235c6b.bd5bb4","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"1","topic":"","payload":"","payloadType":"date","x":145,"y":980,"wires":[["feb57ae1.b1ba88"]],"l":false},{"id":"feb57ae1.b1ba88","type":"function","z":"51235c6b.bd5bb4","name":"inject","func":"// create a random rgb colour\n\n/*msg.payload = { \"title\":\"Demo\",\n \"red\": Math.floor(Math.random() * (255) ),\n \"green\": Math.floor(Math.random() * (255) ),\n \"blue\": Math.floor(Math.random() * (255) )\n}*/\n\nmsg.payload = { \"title\":\"Demo\",\n \"red\": 0 ,\n \"green\": 255 ,\n \"blue\": 255 \n}\n\n\nreturn msg;\n\n\n/*\n// Random Hex color\nmsg.payload = { \"title\":\"Demo\",\n \"hexcolor\": \"#\" + Math.floor(Math.random()*16777215).toString(16)\n}\n*/\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":980,"wires":[["b2c1b38.7e5b55"]]},{"id":"b2c1b38.7e5b55","type":"ui_template","z":"51235c6b.bd5bb4","group":"fa62adc1.37cf8","name":"alternativ","order":1,"width":0,"height":0,"format":"<style>\n.slidecontainer {\n\t/* font-size: 80%; */\n\twidth: 100%;\n}\n\n.slidecontainer input {\n\tmargin-bottom:11px;\n}\n/* slider bar */\n\n.slider {\n -webkit-appearance: none;\n width: 98%;\n height: 14px;\n border-radius: 18px;\n outline: none;\n padding: 0px 2px;\n}\n\n.spectrum {\n border-radius:10px;\n background: linear-gradient(\n to right,\n rgb(255 0 0),\n rgb(255 255 0),\n rgb(0 255 0),\n rgb(0 255 255),\n rgb(0 0 255),\n rgb(255 0 255),\n rgb(255 0 0)\n );\n}\n\n/* slider knopf */\n.slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: rgba({{msg.payload.red}},{{msg.payload.green}},{{msg.payload.blue}},1);\n border: 2px solid white;\n cursor: pointer;\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n}\n\n</style>\n\n<div class=\"slidecontainer\">\n\tRGB ({{msg.payload.red}},{{msg.payload.green}},{{msg.payload.blue}})\n\t<input type=\"range\" min=\"0\" max=\"255\" class=\"slider spectrum\" ng-model=\"sliderValue\" ng-change=\"test()\" ng-mouseup=\"send(msg)\">\n</div>\n\n<script>\n \n(function($scope) {\n\nfunction rgbToHsl(r, g, b){\n r /= 255, g /= 255, b /= 255;\n var max = Math.max(r, g, b), min = Math.min(r, g, b);\n var h, s, l = (max + min) / 2;\n\n if(max == min){\n h = s = 0; // achromatic\n }else{\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch(max){\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n\n return [h, s, l];\n \n}\n \nfunction hslToRgb(h, s, l){\n var r, g, b;\n if(s == 0){\n r = g = b = l; // achromatic\n }else{\n var hue2rgb = function hue2rgb(p, q, t){\n if(t < 0) t += 1;\n if(t > 1) t -= 1;\n if(t < 1/6) return p + (q - p) * 6 * t;\n if(t < 1/2) return q;\n if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n }\n\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = hue2rgb(p, q, h + 1/3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1/3);\n }\n \n return {\"red\":Math.round(r * 255), \"green\": Math.round(g * 255), \"blue\": Math.round(b * 255),\"h\":Math.round(h * 360),\"s\":s,\"l\":l};\n}\n\n$scope.test = function(){\n $scope.msg.payload = hslToRgb($scope.sliderValue/255,1,0.5)\n}\n scope.$watch('msg', function(msg) {\n if (msg) {\n $scope.sliderValue = rgbToHsl($scope.msg.payload.red,$scope.msg.payload.green,$scope.msg.payload.blue)[0]*255\n }\n });\n \n})(scope);\n\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":530,"y":980,"wires":[["441d3c35.f0b1e4"]]},{"id":"441d3c35.f0b1e4","type":"debug","z":"51235c6b.bd5bb4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":680,"y":980,"wires":[]},{"id":"fa62adc1.37cf8","type":"ui_group","name":"alternativ","tab":"6b520bda.e997a4","order":4,"disp":true,"width":8,"collapse":false},{"id":"6b520bda.e997a4","type":"ui_tab","name":"Experimentieren","icon":"dashboard","order":7,"disabled":false,"hidden":false}]
Any help would be really appreciated.
So the comprehensible code lines didn't help too much.
I tried my example - it works on android. It actually slides the slider, It can take input, it produces output. It has rgb and hex values. All you'll need to do is to add function to convert hex or rgb to HSL or make current function to calculate HSL directly. There is tons of examples in web. Try to add or use them.
No mater the color type, the code must be understood before you can make changes.
[{"id":"bdc44b29.79d388","type":"ui_template","z":"9f4fbba4.68ceb8","group":"20ae1040.3cf58","name":"color slider based on md-slider","order":1,"width":"6","height":"1","format":"<div class=\"slider-rgb\" id=\"{{'value_'+$id}}\"></div>\n<div id=\"{{'slider_'+$id}}\" class=\"color-sider-container\">\n <md-slider ng-model=\"slidervalue\" step=\"0.01\" min=\"0\" max=\"1\" aria-label=\"color slider\"></md-slider>\n</div>\n<style>\n.slider-rgb{\n position: absolute;\n font-size: 12px;\n left: 30px;\n line-height: 6px;\n}\n.color-sider-container{\n\n}\n.color-sider-container > md-slider{\n height:40px;\n margin-left: 10px;\n margin-right: 12px;\n top:-1px;\n}\n.color-sider-container > md-slider .md-track-container {\n width: 100%;\n position: absolute;\n top: 16px;\n height: 16px;\n \n}\n.color-sider-container > md-slider .md-track.md-track{\n border-radius:10px;\n background: linear-gradient(\n to right,\n rgb(255 0 0),\n rgb(255 255 0),\n rgb(0 255 0),\n rgb(0 255 255),\n rgb(0 0 255),\n rgb(255 0 255),\n rgb(255 0 0)\n );\n}\n.color-sider-container > md-slider .md-track.md-track-fill{\n visibility:hidden;\n}\n.color-sider-container > md-slider .md-thumb:after {\n visibility:hidden;\n \n}\n.color-sider-container > md-slider .md-thumb {\n transform: scale(1.2) !important;\n border:2px solid white;\n pointer-events: none;\n\n}\n</style>\n\n<script>\n(function(scope) {\nconst spectrumRanges = [\n { from: [255, 0, 0], to: [255, 255, 0] },\n { from: [255, 255, 0], to: [0, 255, 0] },\n { from: [0, 255, 0], to: [0, 255, 255] },\n { from: [0, 255, 255], to: [0, 0, 255] },\n { from: [0, 0, 255], to: [255, 0, 255] },\n { from: [255, 0, 255], to: [255, 0, 0] }\n];\n\nconst findColorValue = (from, to, leftRatio) => {\n return Math.round(from + (to - from) * leftRatio);\n};\n\nconst findRgbFromSliderValue = (sliderpos) => {\n sliderpos = validateInput(sliderpos)\n const wrapper = document.querySelector(\".color-sider-container\");\n const {width } = wrapper.getBoundingClientRect();\n const leftDistance = width * sliderpos\n const totalRanges = spectrumRanges.length;\n const rangeWidth = width / totalRanges;\n const includedRange = Math.floor(leftDistance / rangeWidth);\n const leftRatio = ((leftDistance % rangeWidth) / rangeWidth).toFixed(2);\n const { from, to } = spectrumRanges[includedRange];\n return {\n r: findColorValue(from[0], to[0], leftRatio),\n g: findColorValue(from[1], to[1], leftRatio),\n b: findColorValue(from[2], to[2], leftRatio)\n };\n};\n\nconst rgbToHex = (r, g, b) => {\n const toHex = (rgb) => {\n let hex = Number(rgb).toString(16);\n if (hex.length < 2) {\n hex = `0${hex}`;\n }\n return hex;\n };\n const red = toHex(r);\n const green = toHex(g);\n const blue = toHex(b);\n return `#${red}${green}${blue}`;\n};\n \nconst validateInput = (inp) => {\n if(isNaN(inp)){\n return 0.00001\n }\n if(inp <= 0 ) {\n return 0.00001\n }\n if(inp >=1){\n return 0.9999\n }\n return inp\n} \nscope.$watch('slidervalue', function(slidervalue) {\n if (slidervalue !== undefined) {\n let { r, g, b } = findRgbFromSliderValue(slidervalue);\n let hexValue = rgbToHex(r, g, b);\n $(\"#slider_\"+scope.$id).find('.md-thumb').css(\"background-color\",hexValue);\n $(\"#value_\"+scope.$id).text('RGB:('+r+','+g+','+b +') HEX:'+hexValue)\n if(scope.incoming == true){\n scope.incoming = false\n return\n }\n scope.send({payload:slidervalue,colors:{hex:hexValue,rgb:{r,g,b}}})\n }\n})\n \n scope.$watch('msg', function(msg) {\n if (msg) {\n if(!(\"#slider_\"+scope.$id)){\n return\n }\n scope.incoming = true\n scope.slidervalue = msg.payload\n }\n });\n})(scope);\n</script>","storeOutMessages":true,"fwdInMessages":false,"resendOnRefresh":true,"templateScope":"local","x":410,"y":1640,"wires":[["41bcf137.06a9e"]]},{"id":"41bcf137.06a9e","type":"debug","z":"9f4fbba4.68ceb8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":650,"y":1640,"wires":[]},{"id":"b90f245f.f2f078","type":"inject","z":"9f4fbba4.68ceb8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0.5","payloadType":"num","x":190,"y":1600,"wires":[["bdc44b29.79d388"]]},{"id":"152c7cb7.8c8b73","type":"ui_numeric","z":"9f4fbba4.68ceb8","name":"","label":"slider val","tooltip":"","group":"20ae1040.3cf58","order":3,"width":0,"height":0,"wrap":false,"passthru":true,"topic":"topic","topicType":"msg","format":"{{value}}","min":0,"max":"1","step":"0.1","x":180,"y":1640,"wires":[["bdc44b29.79d388"]]},{"id":"20ae1040.3cf58","type":"ui_group","name":"Group 1","tab":"6b520bda.e997a4","order":1,"disp":true,"width":"6","collapse":false},{"id":"6b520bda.e997a4","type":"ui_tab","name":"Experimentieren","icon":"dashboard","order":3,"disabled":false,"hidden":false}]
Unfortunatly you are so right On the one hand of course node red offers 1001 ways to solve a problem, however, this can also be frustrating for a newcomer as myself. I think this will never come to an end, so I accept that for me it's better to focus only on what the dashboard has to offer.
Nevertheless, I will use your final solution as is. At the end it is the most complete solution. Just one last point (promised):
If I move the slider it gives a nice payload (hex +rgb). However, how can I achieve that this payload is also generated when using the numeric node as input (or inject a value as an your example).
Thank you so much!
As Angular doesn't have a good native way of handling mobile touch inputs, you can use Jquery. Also to prevent the slider from going from left to right, you need to change the input's range from 0-255 to 0-254.
<style>
.slidecontainer {
/* font-size: 80%; */
width: 100%;
}
.slidecontainer input {
margin-bottom:9px;
}
/* slider bar */
.slider {
-webkit-appearance: none;
width: 98%;
height: 18px;
border-radius: 18px;
outline: none;
padding: 0px 2px;
}
.spectrum {
border-radius:10px;
background: linear-gradient(
to right,
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)
);
}
/* slider knopf */
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 24px;
height: 24px;
border-radius: 50%;
background: rgba({{msg.payload.red}},{{msg.payload.green}},{{msg.payload.blue}},1);
border: 2px solid white;
cursor: pointer;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
</style>
<div class="slidecontainer">
RGB ({{msg.payload.red}},{{msg.payload.green}},{{msg.payload.blue}})
<input type="range" min="0" max="254" class="slider spectrum" ng-model="sliderValue" ng-change="test()">
</div>
<script>
(function($scope) {
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
var hue2rgb = function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return {"red":Math.round(r * 255), "green": Math.round(g * 255), "blue": Math.round(b * 255)};
}
$scope.test = function(){
$scope.msg.payload = hslToRgb($scope.sliderValue/255,1,0.5)
}
scope.$watch('msg', function(msg) {
if (msg) {
$scope.sliderValue = rgbToHsl($scope.msg.payload.red,$scope.msg.payload.green,$scope.msg.payload.blue)[0]*255
}
});
$('.spectrum').on('touchend mouseup', function(e) {
e.preventDefault(); //prevent default behavior
$scope.send($scope.msg);
});
})(scope);
</script>
And here's an updated version using "md-slider" instead of "input" and it now properly handles multiple instances in same page:
<div class="color-sider-container">
<md-slider id="{{'slider_'+$id}}" ng-model="sliderValue" step="1" min="0" max="254" ng-model-options='{ debounce: 100 }' ng-change="test();send(msg)"></md-slider>
</div>
<style>
.color-sider-container{
padding:0px 5px;
}
.color-sider-container > md-slider{
height:40px
}
.color-sider-container > md-slider .md-track-container {
width: 100%;
position: absolute;
top: 16px;
height: 16px;
}
.color-sider-container > md-slider .md-track.md-track{
border-radius:10px;
background: linear-gradient(
to right,
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)
);
}
.color-sider-container > md-slider .md-track.md-track-fill{
visibility:hidden;
}
.color-sider-container > md-slider .md-thumb:after {
background: inherit;
}
.color-sider-container > md-slider .md-thumb {
transform: scale(1.2) !important;
pointer-events: none;
}
</style>
<script>
(function($scope) {
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
var hue2rgb = function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return {"red":Math.round(r * 255), "green": Math.round(g * 255), "blue": Math.round(b * 255)};
}
scope.test = function(){
//var r = document.querySelector(':root');
$scope.msg.payload = hslToRgb($scope.sliderValue/255,1,0.5)
//r.style.setProperty('--color',"rgb("+$scope.msg.payload.red+","+$scope.msg.payload.green+","+$scope.msg.payload.blue+")" );
$("#slider_"+$scope.$id+" > div > div > div.md-thumb-container > div.md-thumb").css("background", "rgb("+$scope.msg.payload.red+","+$scope.msg.payload.green+","+$scope.msg.payload.blue+")" );
//console.log($("#slider_"+$scope.$id))
}
scope.$watch('msg', function(msg) {
if (msg) {
$scope.sliderValue = rgbToHsl($scope.msg.payload.red,$scope.msg.payload.green,$scope.msg.payload.blue)[0]*255
}
});
})(scope);
</script>
Hi,
I just had a play with this and it looks neat, the slider works more smoothly than @hugobox version which is unfortunately too laggy on my pc, however there doesn't seem to be any input / output ?
Is there a more complete example that can display received a colour value and also output a selected value?
Itās a shame you have no plans to develop further, as this along with brightness and colour temperature would be an excellent addition for those wishing to control smart bulbs etc.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.