Good day dear. Faced with a misunderstanding of why JS returns the values ​​of RGB channels, although in CSS I set it under HSL. In general, the problem is such that every two seconds it is necessary to change the color values ​​of the squares. The first and second blocks (columns) of squares should receive +10 to the hue channel every two seconds (That is, after the second second, the classes .first_st * should have the values ​​h = 11 and the classes .second_st * = 21). If the values ​​of h reach 360 then it is added as much as possible and then everything starts from scratch. (That is, at 36 iterations, the classes .first_st * should have the values ​​h = 1 and the classes .second_st * = 11) I'll give the code:

var allFirstColors = $("[class^='first_st']"), firstColorsLength = allFirstColors.length, allSecondColors = $("[class^='second_st']"), secondColorsLength = allFirstColors.length; var h,s,l; console.log(" st1 = " + $(".first_st1").css("fill") ); // Почему возвращает RGB каналы? allFirstColors.each(function(indx, el){ let color = $(el).css("fill"), [h,s,l] = color.match(/\d+/g); console.log("[h,s,l] = " + [h,s,l]); }); 
 .first_st1{ fill: hsl(1, 50%, 50%); } .first_st2{ fill: hsl(1, 70%, 40%); } .first_st3{ fill: hsl(1, 90%, 30%); } .second_st1{ fill: hsl(11, 50%, 50%); } .second_st2{ fill: hsl(11, 70%, 40%); } .second_st3{ fill: hsl(11, 90%, 30%); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg width="600" height="240"> <rect class="first_st1" width="80" height="80" x="0" y="0"></rect> <rect class="first_st2" width="80" height="80" x="0" y="80"></rect> <rect class="first_st3" width="80" height="80" x="0" y="160"></rect> <rect class="second_st1" width="80" height="80" x="160" y="0"></rect> <rect class="second_st2" width="80" height="80" x="160" y="80"></rect> <rect class="second_st3" width="80" height="80" x="160" y="160"></rect> </svg> 

  • This is api, you have to convert. - vp_arth

3 answers 3

After your question, I became interested and began to strenuously google.

$(el).css() essentially returns you the properties from getComputedStyle(el) , and getComputedStyle(el) returns the calculated (resolved) properties, i.e. Browsers themselves convert your color to rgb (a) and return it and work with the fact that you wrote it does not work out, so you have to manually convert it to the format you need.
For example, if you set the width:100%; , getComputedStyle will give you the length of the block in px, not 100%.

Below I found a function that converts rgba to hsl using a wiki formula.

 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]; } console.log(rgbToHsl(191, 66, 63)); 

Only you have to add. round off

    Even if you refer directly to the styles (which in some cases works well ), it is impossible to get either hex or hsl values ​​in any way. Only special designation of the type " red ":

     function getStyle(className) { var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules; for (var x = 0; x < classes.length; x++) { if (classes[x].selectorText == className) { (classes[x].style.cssText) ? console.log(classes[x].style.cssText) : console.log(classes[x].cssText); } } } getStyle('.first_st1'); getStyle('.first_st2'); getStyle('.first_st3'); 
     .first_st1 { fill: red; } .first_st2 { fill: #ff5555; } .first_st3 { fill: hsl(1, 90%, 30%); } .second_st1 { fill: hsl(11, 50%, 50%); } .second_st2 { fill: hsl(11, 70%, 40%); } .second_st3 { fill: hsl(11, 90%, 30%); } 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg width="600" height="240"> <rect class="first_st1" width="80" height="80" x="0" y="0"></rect> <rect class="first_st2" width="80" height="80" x="0" y="80"></rect> <rect class="first_st3" width="80" height="80" x="0" y="160"></rect> <rect class="second_st1" width="80" height="80" x="160" y="0"></rect> <rect class="second_st2" width="80" height="80" x="160" y="80"></rect> <rect class="second_st3" width="80" height="80" x="160" y="160"></rect> </svg> 

    Therefore, a good way to solve the problem is to use data-* tags:

     var allFirstColors = $("[class^='first_st']"), firstColorsLength = allFirstColors.length; var h, s, l; console.log(" st1 = " + $(".first_st1").css("fill")); allFirstColors.each(function(indx, el) { let color = $(el).data("hsl"), [h, s, l] = color.match(/\d+/g); console.log("[h,s,l] = " + [h, s, l]); }); 
     .first_st1 { fill: hsl(1, 50%, 50%); } .first_st2 { fill: hsl(1, 70%, 40%); } .first_st3 { fill: hsl(1, 90%, 30%); } 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg width="600" height="240"> <rect class="first_st1" data-hsl="1, 50, 50" width="80" height="80" x="0" y="0"></rect> <rect class="first_st2" data-hsl="1, 70, 40" width="80" height="80" x="0" y="80"></rect> <rect class="first_st3" data-hsl="1, 90, 30" width="80" height="80" x="0" y="160"></rect> </svg> 

    Use $(el).data("hsl") get the hsl data, then write down the modified ones using $(el).data("hsl", h+', '+s+', '+l)

    • Something fails to get the data window.onload = function () {var allFirstColors = $ ("[class ^ = 'first_st']"), firstColorsLength = allFirstColors.length, allSecondColors = $ ("[class ^ = 'second_st'] "), secondColorsLength = allFirstColors.length; var h, s, l; allFirstColors.each (function (indx, el) {let color = $ (el) .data ("fill"); $ (el) .data ("hsl", h + ',' + s + ',' + l); console.log ("color =" + color);}); } Yes, and in the documentation it is prescribed that the .data (key) and .data () methods, you will get the value of variables only on the first element from all selected. -
    • @ BlackStar1991 $(el).data("hsl"); hsl, not fill. hsl corresponds to the name of the attribute data-hsl="1, 90, 30" you can choose any name data-color data-fill - Crantisz
    • No, writing to html is not an option at all. Here is a simple example of 6 squares. In reality, I need to work with polygons and their> 100 - BlackStar1991
    • @ BlackStar1991 data- * attributes scale well. Therefore, I recommended them. - Crantisz

    They advised to implement my idea through brute force.

     window.onload = function(){ var initialH1 = 1 initialH2 = 11, allFirstColors = $("[class^='first_st']"), firstColorsLength = allFirstColors.length, allSecondColors = $("[class^='second_st']"), secondColorsLength = allFirstColors.length; window.setInterval(function(){ initialH1 = initialH1 === 360 ? 1 : initialH1 + 10 < 360 ? initialH1 + 10 : 360; initialH2 = initialH2 === 360 ? 11 : initialH2 + 10 < 360 ? initialH2 + 10 : 360; allFirstColors.each(function(i){ $(this).css("fill", `hsl(${initialH1}, ${50 + i * 10}%, ${50 - i * 10}%)`); console.log( $(this).css("fill") + " = first block" ) }) allSecondColors.each(function(i){ $(this).css("fill", `hsl(${initialH2}, ${50 + i * 10}%, ${50 - i * 10}%)`); console.log( $(this).css("fill") + " = second block" ) }) }, 2000) } 
      .first_st1{ fill: hsl(1, 50%, 50%); } .first_st2{ fill: hsl(1, 70%, 40%); } .first_st3{ fill: hsl(1, 90%, 30%); } .second_st1{ fill: hsl(11, 50%, 50%); } .second_st2{ fill: hsl(11, 70%, 40%); } .second_st3{ fill: hsl(11, 90%, 30%); } 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg width="600" height="240"> <rect class="first_st1" width="80" height="80" x="0" y="0"></rect> <rect class="first_st2" width="80" height="80" x="0" y="80"></rect> <rect class="first_st3" width="80" height="80" x="0" y="160"></rect> <rect class="second_st1" width="80" height="80" x="160" y="0"></rect> <rect class="second_st2" width="80" height="80" x="160" y="80"></rect> <rect class="second_st3" width="80" height="80" x="160" y="160"></rect> </svg> 

    In principle, it works, but I'm not very happy. What if the values ​​in the blocks are completely different, how to prescribe the algorithm? Suppose for such values?

     .first_st1{ fill: hsl(1, 84%, 61%); } .first_st2{ fill: hsl(358, 83%, 54%); } .first_st3{ fill: hsl(350, 65%, 40%); } .second_st1{ fill: hsl(11, 84%, 61%); } .second_st2{ fill: hsl(8, 83%, 54%); } .second_st3{ fill: hsl(0, 65%, 40%); } 
     <svg width="600" height="240"> <rect class="first_st1" width="80" height="80" x="0" y="0"></rect> <rect class="first_st2" width="80" height="80" x="0" y="80"></rect> <rect class="first_st3" width="80" height="80" x="0" y="160"></rect> <rect class="second_st1" width="80" height="80" x="160" y="0"></rect> <rect class="second_st2" width="80" height="80" x="160" y="80"></rect> <rect class="second_st3" width="80" height="80" x="160" y="160"></rect> </svg> 

    • Do you answer your question or give clarification? If you give a clarification, then you have to edit the question, and not write the answer - Crantisz