mardi 27 avril 2021

React js material ui generate n random colors

I am writing a method which should generate n random colors without repetition, passing the following properties.

random({
      number: 150,
      colors: ["blue", "lightBlue", "cyan"],
      shades: ["200", "500"]
      //excludeColors: ["blue", "lightBlue", "cyan"],
      //excludeShades: ["200", "500", "700", "A700"]
});

The colors are the ones used using @material-ui/core/colors, but I would like to improve the function to make it more performant.

Can you give me a hand?

Link: codesandbox

import "./styles.css";
import React, { useState, useEffect } from "react";
import {
  red,
  pink,
  purple,
  deepPurple,
  indigo,
  blue,
  lightBlue,
  cyan,
  teal,
  green,
  lightGreen,
  lime,
  yellow,
  amber,
  orange,
  deepOrange,
  brown,
  grey,
  blueGrey
} from "@material-ui/core/colors";

export default function App() {
  const [state, setState] = useState({
    colors: []
  });

  const { colors } = state;

  const random = ({
    number,
    colors = [],
    shades = [],
    excludeColors = [],
    excludeShades = []
  }) => {
    const hueArray = [
      red,
      pink,
      purple,
      deepPurple,
      indigo,
      blue,
      lightBlue,
      cyan,
      teal,
      green,
      lightGreen,
      lime,
      yellow,
      amber,
      orange,
      deepOrange,
      brown,
      grey,
      blueGrey
    ];
    const hueNameArray = [
      "red",
      "pink",
      "purple",
      "deepPurple",
      "indigo",
      "blue",
      "lightBlue",
      "cyan",
      "teal",
      "green",
      "lightGreen",
      "lime",
      "yellow",
      "amber",
      "orange",
      "deepOrange",
      "brown",
      "grey",
      "blueGrey"
    ];
    const shadeArray = [
      "50",
      "100",
      "200",
      "300",
      "400",
      "500",
      "600",
      "700",
      "800",
      "900",
      "A100",
      "A200",
      "A400",
      "A700"
    ];

    const random = (items) => Math.floor(Math.random() * items.length);

    return [...Array(number).keys()].reduce((acc, el) => {
      let check = true;
      while (check) {
        let checkHue = true,
          checkShade = true;
        let hueR, shadeR;

        while (checkHue) {
          hueR = random(hueArray);
          if (
            (colors.length === 0 && excludeColors.length === 0) ||
            (colors.length !== 0 && colors.includes(hueNameArray[hueR])) ||
            (excludeColors.length !== 0 &&
              !excludeColors.includes(hueNameArray[hueR]))
          )
            checkHue = false;
        }

        while (checkShade) {
          shadeR = shadeArray[random(shadeArray)];
          if (
            (shades.length === 0 && excludeShades.length === 0) ||
            (shades.length !== 0 && shades.includes(shadeR)) ||
            (excludeShades.length !== 0 && !excludeShades.includes(shadeR))
          )
            checkShade = false;
        }

        const color = hueArray[hueR][shadeR];

        console.log(
          hueNameArray[hueR],
          shadeR,
          color,
          acc,
          !acc.includes(color)
        );

        if (!acc.includes(color)) {
          acc[el] = color;
          check = false;
        }
      }
      return acc;
    }, []);
  };

  useEffect(() => {
    let u = (a) => [...new Set(a)];
    let a, b;

    /*a = random({
      number: 257
    }); //<-- [258,...,266] problem codesanbox
    b = u(a);
    console.log("a", a, a.length);
    console.log("b", b, b.length);
    //19(hue)*14(shade)=266 possible colors

    a = random({
      number: 28, <- certainly can not be a higher value to 28
      colors: ["red", "blue"]
    });
    b = u(a);
    console.log("a", a, a.length);
    console.log("b", b, b.length);
    //2(hue)*14(shade)=28 possible colors

    a = random({
      number: 38, <- certainly can not be a higher value to 38
      shades: ["200", "500"]
    });
    b = u(a);
    console.log("a", a, a.length);
    console.log("b", b, b.length);
    //19(hue)*2(shade)=38 possible colors

    a = random({
      number: 4, <- certainly can not be a higher value to 4
      colors: ["red", "blue"],
      shades: ["200", "500"]
    });
    b = u(a);
    console.log("a", a, a.length);
    console.log("b", b, b.length);
    */
    //2(hue)*2(shade)=4 possible colors

    a = random({
      number: 150,
      excludeColors: ["blue", "lightBlue", "cyan"],
      excludeShades: ["200", "500", "700", "A700"]
    });
    b = u(a);
    console.log("a", a, a.length);
    console.log("b", b, b.length);
    //16(hue)*10(shade)=160 possible colors

    setState((prev) => ({
      ...prev,
      colors: a
    }));
  }, []);

  return (
    <div className="App">
      {colors.map((backgroundColor, key) => (
        <div key={key} style=>
          {key + 1}) {backgroundColor}
        </div>
      ))}
    </div>
  );
}



Aucun commentaire:

Enregistrer un commentaire