Arranging RGB values in Javascript

I am interested in using javascript/jquery to organize an array of rgba values based on the colors of the visible spectrum. My goal is to have similar shades grouped together. Is there a specific plugin that can assist with this task, or what would be the best approach to achieve this?

Here is the spectrum image for reference:

Answer №1

Full disclosure: The library recommended below was created by yours truly.

For those who are open to using a library, here's a more streamlined version of Oriol's comprehensive response. This solution leverages the sc-color library:

const sortedColors = colorArray.sort((colorA, colorB) => {
    return sc_color(colorA).hue() - sc_color(colorB).hue();
});

Answer №2

If you have an array of colors structured like this:

var rgbArr = [c1, c2, c3, ...]

where each color ci consists of three numbers between 0 and 255

ci = [red, green, blue]

you can utilize the following function to convert these colors to HSL format

function rgbToHsl(c) {
  var r = c[0]/255, g = c[1]/255, b = c[2]/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 new Array(h * 360, s * 100, l * 100);
}

and arrange them based on hue

var sortedRgbArr = rgbArr.map(function(c, i) {
  // Convert to HSL and store original indices
  return {color: rgbToHsl(c), index: i};
}).sort(function(c1, c2) {
  // Sort by hue
  return c1.color[0] - c2.color[0];
}).map(function(data) {
  // Retrieve original RGB color
  return rgbArr[data.index];
});

Here is a practical example (credits to Ionică Bizău):

function display(container, arr) {
  container = document.querySelector(container);
  arr.forEach(function(c) {
    var el = document.createElement("div");
    el.style.backgroundColor = "rgb(" + c.join(", ") + ")";
    container.appendChild(el);
  })
}
function rgbToHsl(c) {
  var r = c[0] / 255,
      g = c[1] / 255,
      b = c[2] / 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 new Array(h * 360, s * 100, l * 100);
}

var rgbArr = [];
for (var i = 0; i < 100; ++i) {
  rgbArr.push([
    Math.floor(Math.random() * 256),
    Math.floor(Math.random() * 256),
    Math.floor(Math.random() * 256)
  ]);
}
display("#before", rgbArr);

var sortedRgbArr = rgbArr.map(function(c, i) {
  // Convert to HSL and store original indices
  return {color: rgbToHsl(c), index: i};
}).sort(function(c1, c2) {
  // Sort by hue
  return c1.color[0] - c2.color[0];
}).map(function(data) {
  // Retrieve original RGB color
  return rgbArr[data.index];
});
display("#after", sortedRgbArr);
#before > div,
#after > div {
  width: 1%;
  height: 20px;
  display: inline-block;
}
Random colors: <div id="before"></div>
Same colors, sorted by hue: <div id="after"></div>

sortedRgbArr will store the rgb colors from rgbArr arranged in a manner similar to the visible spectrum.

The issue arises when comparing your created spectrum with the HSL spectrum which does not consist of all colors, such as pink.

This lack of certain colors might be due to the fact that pink is not naturally occurring and is derived from blending opposite ends of the light's spectrum in RGB. Hence, a decision needs to be made regarding its placement.

Furthermore, it appears that your spectrum progresses from lower to higher wavelength but not frequency, making it a reverse of the HSL spectrum.

To align with your spectrum, replace c1.color[0] - c2.color[0] with c2.color[0] - c1.color[0].

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The useNavigate function fails to override the dynamic parameter

We recently updated our project from using version 4 of react-router to version 6. However, we are facing an issue after switching from the useLocation API to useNavigate and I am having trouble identifying the cause. Here is a snippet of my function: im ...

Looking up array elements in Mongoose: A step-by-step guide

In my Mongoose model, I have an array defined as a subdocument with the structure below: var mongoose = require('mongoose'); var Schema = mongoose.Schema; var schema = Schema({ author: { type: Schema.Types.ObjectId, ref: 'Author' ...

The error message "Uncaught ReferenceError: e is not defined" is popping up in my code when

As a beginner with React and Material-UI, I am encountering an error that I cannot seem to resolve. When I load a component using material-ui/data-grid, the data grid simply displays "An error occurred" in the app. However, when I load the component withou ...

Verify whether the array containing objects includes a specific object

I'm currently attempting to determine whether an array of objects contains a specific object. I would like the function to return true if there is an object in the array that has identical values, regardless of the object id. Here's how I initial ...

Creating a mandatory 'Select' dropdown field in Vue.js

Hello, I am a beginner in VueJS and I am trying to make a select element from a drop-down list required. I attempted to add the required attribute as shown in the code below. Any suggestions on how to achieve this? Thanks. <v-select ...

What's the best way to signal to an Observable that my array has reached its end?

Quick Summary: Can someone help me figure out how to get an Observed array to complete? Check out this jsBin example for reference. I'm a beginner with Observables so I might be approaching this problem the wrong way. With the code provided below, or ...

A function similar to setCell for modifying form fields in JqGrid

After searching through numerous answers from @Oleg, I couldn't find the solution I was looking for. I am dealing with a grid where I can edit inline in certain fields. Specifically, I am working with autocomplete functionality and when I select an it ...

Connect-Domain fails to detect errors in the scenario described below:

I have chosen to implement the connect-domain module (https://github.com/baryshev/connect-domain) in order to streamline error handling within my Express application. Although it generally functions as expected, there is a peculiar issue that arises when ...

Tips for combining values from a 1D NumPy array with corresponding elements in other NumPy subarrays

If there is a NumPy array called a with dimensions (3, 5, 7) and a 1D NumPy array called l with dimensions (3, 1), the goal is to add the first element of array l to the first subarray in array a, the second element of array l to the second subarray of arr ...

It seems that although both axios.put methods are identical, only one is functioning properly

Could someone clarify the distinction between these two syntaxes and why the first one is not functioning correctly? Attempting to use the first code block results in a 401 error: const handleSubmit = () => { axios.put(`url`, { headers: { Aut ...

Performing a count query with MongoDB Mongoose by grouping data based on multiple fields

I've developed an analytics API using MongoDB. Here is the model for my sessions: const sessionSchema = new Schema( { user: { id: Number, name: String, email: String }, }, { timestamps: true }, ); My goal is to calculate the number of uni ...

Problem resolved: Assign the nearest *multiple of ten* to a number if it surpasses the last *multiple of ten*

Consider this scenario: You have a number, let's say 12.5, and you want to round it up to the next multiple of ten (20). Or if you have a number between 20 and 30, it should be rounded up to 30. How can this be achieved using JavaScript? I have ...

How to retrieve a value from a getter in a different file using Node.js

Recently, during the creation of a node project, I defined a model as follows: export default class Tokens { constructor() { this.accessToken = ''; this.refreshToken = ''; } getAccessToken() { return ...

Are $(function() { }) and $(document).ready(function() { }) the same function under the hood?

Similar Question: What sets apart these jQuery ready functions? Do $(function(){}); and $(“document”).ready(function(){}); have the same meaning? Beginning javascript code with $(function, etc. This day, as I was examining some jav ...

using an array as a parameter in an axios request

For the request I'm working on using Axios, I'm aiming to send an array like this [1,2,3,4]. This array will be used for a selection query in my backend. My question is whether it's better to use a GET or POST request for this purpose, and w ...

Why is it that when a boolean value is logged as a checkbox, it shows up as undefined?

In my code, I'm attempting to log the value of a variable named check, which corresponds to column 11 in a spreadsheet. This variable is meant to represent the state of a checkbox (true or false) based on whether it's been ticked or not. However, ...

Encountering a NoSuchElementException when transitioning from frame[0] to window[1] in Firefox GeckoDriver using Selenium with Python

Encountered an issue with the Firefox GeckoDriver browser where I receive an error stating `element not found`. The problem arises when I navigate from window[1] to frame[0], back to window[1], and then attempt to click the close frame button. I prefer u ...

Delving into the World of ReactJS Routing Components and Rendering

I recently developed a basic booking app consisting of 3 essential files - App.js, Booked.js (1st child), and Details.js (2nd child). My current dilemma involves attempting to access App.js for the purpose of deleting data using the 2nd child (Detail.js). ...

The improper utilization or replacement of Jest mock in an Angular standalone component's unit test is causing issues

Presented here is a streamlined Ionic/Angular component with unnecessary code removed. import { IonicModule, ModalController } from '@ionic/angular'; @Component({ selector: 'my-component', templateUrl: 'my-component.html' ...

Implementing React Table selected rows from the parent component

I am currently facing an issue with my React Table component that has selectable rows. Although row selection is functioning properly and the parent component has access to information about the selected rows, I am struggling to set the selected rows from ...