gusbemacbe / color-mixer-telinkrin

Mix three colours of Telinkrin to get Telinkrin-coloured hex
https://gusbemacbe.github.io/color-mixer-telinkrin/
GNU Affero General Public License v3.0
1 stars 1 forks source link

Wanted help #1

Open gusbemacbe opened 5 years ago

gusbemacbe commented 5 years ago

Hola @daniruiz!

He visitado al tu sitio y he visto que has desarrollado el Color Fixer. Apuesto que tengas conocimiento de sistema de colores. ¿Puedes ayudarme sólo un poco?

¡Discúlpame por tenerte etiquetado!

daniruiz commented 5 years ago

¡Claro! Realmente no sé mucho de colores 🤣 pero intentaré ayudarte en todo lo que pueda

gusbemacbe commented 5 years ago

Bien, vamos intentar un poco, @daniruiz .

Por favor, descarga mi repositorio, abre el index.html, no necesitas copiar los códigos hexadecimales, ellos ya vienen listos, pero pone 1 en todas las alfas. Sólo clica en "mix!", verás que el resultado será el negro (#000000 or rgb(0, 0 , 0)), pero el resultado estaba incorrecto. El resultado debería ser #5a8d9e.

Puedes ver el convert-to-telinkrin.html, pero él no convierte para el hexadecimal, porque es un filtro de SVG, por eso, tengo de picar cada una de los colores para copiar el código hexadecimal para el archivo. Por eso, decido utilizar el JavaScript.

Me gustaría mixturar como el filtro de SVG hace - todas las colores, como ves en el index.html, para obtener #5a8d9e.

Se no puedes, no hay problemas, pero ¿conoces alguien que pueda hacer aquello?

daniruiz commented 5 years ago

He estado viendo como funciona CSS filter mediante SVG y creo que ya se cómo convertirlo a JS. Estos días no tengo mucho tiempo pero hoy puedo dedicarle un rato e intentar corregirlo porque me parece muy interesante :ok_hand:

gusbemacbe commented 5 years ago

Hola @daniruiz !

Sí, es muy interesante. Todo el mundo estaba interesado también, pero ningún sabe hacerlo, ellos han dicho que eso requiere matemáticas.

He postado la cuestión en el Hashnode, pero ningún contesta y sabe hacerlo, y sólo un tipo (@Hipkiss) me dado una respuesta, indicando dos referencias, e de una de ellas he tomado este repositorio y readaptado para llegar al exacto color.

No olvides de acreditarte. Pone tu nombre, tu usuario y tu e-mail en el archivo CREDITS, en el README.

daniruiz commented 5 years ago

¡Ya lo he conseguido! La solución está en usar colores hsl (tono/hue, saturación, luz). Los colores que telinkrin usan son hsl(195, 34%, X_light%), por lo que solo hace falta calcular el nivel de luz del color e introducirlo en X_light.

Además hay que crear un límite de luz para que negro = #356170 y blanco = #b2ced6

Pruebalo aquí: https://codepen.io/anon/pen/rPKpwp?editors=1010

function telinkrinizeColor (hexColor) {
  const [minLight, maxLight] = [32, 77]

  let [, red, green, blue] = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexColor)
      .map(hex => parseInt(hex, 16) * 100 / 255)
  let maxColor = Math.max(red, green, blue)
  let minColor = Math.min(red, green, blue)
  let light = (minColor + maxColor) / 2

  light = Math.max(Math.min(light, maxLight), minLight)

  return `hsl(195, 34%, ${light}%)`
}

Si necesitas el color en RGB:

function telinkrinizeColor (hexColor) {
  const [minLight, maxLight] = [32, 77]

  let [, red, green, blue] = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexColor)
      .map(hex => parseInt(hex, 16) * 100 / 255)
  let maxColor = Math.max(red, green, blue)
  let minColor = Math.min(red, green, blue)
  let light = (minColor + maxColor) / 2

  light = Math.max(Math.min(light, maxLight), minLight)

  return hslToHex([195, 34, light])
}

function hslToHex([h, s, l]) {
  const toHex = x => {
    const hex = Math.round(x * 255).toString(16)
    return hex.length === 1 ? '0' + hex : hex
  }

  h /= 360
  s /= 100
  l /= 100

  let r, g, b

  if (s === 0) r = g = b = l
  else {
    const 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
    }
    const q = l < 0.5 ? l * (1 + s) : l + s - l * s
    const p = 2 * l - q
    r = hue2rgb(p, q, h + 1 / 3)
    g = hue2rgb(p, q, h)
    b = hue2rgb(p, q, h - 1 / 3)
  }

  return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}

¡Espero que esto resuelva tu problema! :smile:

gusbemacbe commented 5 years ago

¡Exactamente! Sabía que eran tono/hue, saturación, luz, pero he pensado siempre en los colores del feColorMatrix. ¡Muchas gracias!

¿Este snippet funciona con sólo un color de Telinkrin? Se sí, entonces tengo de escoge un de tres colores de Telinkrin para utilizarlo en vez de tres colores.

daniruiz commented 5 years ago

No he entendido eso último

gusbemacbe commented 5 years ago

Yo quería aplicar tres colores de Telinkrin (quiero decir tres hsls), en vez de un color para convertir el color original.

Pero como has conseguido y el snippet (codepen) funciona sólo con un color, decido escoger un color de Telinkrin. Muchas gracias! ¿Puedo acreditar tu nombre y apellido, tu usuario y tu e-mail?

daniruiz commented 5 years ago

Si, funciona con un solo color porque los demás eran iguales en hls solo cambia light, así es mucho más sencillo.

¡Gracias por acreditarme! Daniel Ruiz de Alegría @daniruiz daniel@drasite.com

gusbemacbe commented 5 years ago

Hola @daniruiz !

!Muchas gracias!

gusbemacbe commented 5 years ago

Discúlpame, @daniruiz, pero ¿puedo substituir 'input[type=color]' por colors (array) y return hsl(195, 34%, ${light}%) por return attachNewNode = hsl(195, 34%, ${light}%)?

Por ejemplo:

      let titlenames = ["original", "telinkrin"];
      let colours = ["#000", "#000009", "#0064A2", "#006575", "#ff99cc", "#DE6161", "#F0CA2A", "#FE4401", "#DFDFDF", "#00FF00"];
      function attachNewNode(target, colours, titlenames)
      {
        let length = colours.length;
        for (let i = 0; i < length; i++)
        {
          let node = document.createElement('div');
          node.className = 'palette';
          node.title = parseInt(i+1) + " – " + titlenames;
          node.style = `background-color: ${colours[i]}`;
          node.textContent = parseInt(i+1);
          target.appendChild(node);
        }
      }
      attachNewNode(document.getElementById("demo1"), colours, titlenames[0]);
      attachNewNode(document.getElementById("demo2"), colours, titlenames[1]);
gusbemacbe commented 5 years ago

Hola @daniruiz !

He probado, pero sin succeso:

function getColours()
{
   for (let i = 0; i < length; i++)
   {
      const hexColor = colours[i];
      colours = telinkrinizeColor(hexColor);
   }
   return getColours();
}

attachNewNode(document.getElementById("demo1"), colours, titlenames[0]);
attachNewNode(document.getElementById("demo2"), getColours[colours], titlenames[1]);
daniruiz commented 5 years ago

I think you want something like this https://codepen.io/anon/pen/qgJpMV?editors=1000 You can add as many colors as you want to colors array and the script will convert and add them

<html>
    <head>
         <meta charset="UTF-8"> 
        <script>
          const colors = ['#000000', '#000009', '#0064A2', '#006575', '#ff99cc', '#DE6161', '#F0CA2A', '#FE4401', '#DFDFDF', '#00FF00']
          const telinkrinColors = colors.map(color => telinkrinizeColor(color))

          function telinkrinizeColor (hexColor) {
            const [minLight, maxLight] = [32, 77]

            let [, red, green, blue] = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexColor)
                .map(hex => parseInt(hex, 16) * 100 / 255)
            let maxColor = Math.max(red, green, blue)
            let minColor = Math.min(red, green, blue)
            let light = (minColor + maxColor) / 2

            light = Math.max(Math.min(light, maxLight), minLight)

            return hslToHex([195, 34, light])
          }

          function hslToHex([h, s, l]) {
            const toHex = x => {
              const hex = Math.round(x * 255).toString(16)
              return hex.length === 1 ? '0' + hex : hex
            }

            h /= 360
            s /= 100
            l /= 100

            let r, g, b

            if (s === 0) r = g = b = l
            else {
              const 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
              }
              const q = l < 0.5 ? l * (1 + s) : l + s - l * s
              const p = 2 * l - q
              r = hue2rgb(p, q, h + 1 / 3)
              g = hue2rgb(p, q, h)
              b = hue2rgb(p, q, h - 1 / 3)
            }

            return `#${toHex(r)}${toHex(g)}${toHex(b)}`
          }

          function createColorElement (color) {
            return Object.assign(document.createElement('INPUT'),
                    {type: 'color', value: color})
          }

          window.onload = () => {
            colors.forEach(color => {
              document.querySelector('#oldColors')
                      .appendChild(createColorElement(color))
            })
            telinkrinColors.forEach(color => {
              document.querySelector('#newColors')
                      .appendChild(createColorElement(color))
            })
          }
        </script>
    </head>
    <body>
        <div id="oldColors">
            <h1>Old colors</h1>
        </div>
        <div id="newColors">
            <h1>New colors</h1>
        </div>
    </body>
</html>
gusbemacbe commented 5 years ago

Exactly, @daniruiz! Thank you a lot.

But you could continue to write in Spanish. I have studied Spanish since 9 years old and today I know 15 languages. If you prefer English, no problems.

I will update the README.

daniruiz commented 5 years ago

Jajajajaja perdona, es la costumbre de escribir en ingles en github. No me había dado ni cuenta :P

gusbemacbe commented 5 years ago

@daniruiz

He actualizado el README. Lee el README entero. El ejemplo de telinkrizador, utilizando JavaScript, de acuerdo con la luz, tiene una pequeña desventaja. El filtro de SVG es más preciso, pero también tiene dos desventajas.

Te he acreditado en el README.

gusbemacbe commented 5 years ago

Observa que en el demo anterior que me has dado, el hexadecimal es impreso, pero en el demo actual que has dado, los hexadecimales no son impresos.

daniruiz commented 5 years ago

Bueno es solo un ejemplo para que despues lo modificaras a tu gusto, además son inputs de color asi que si haces click sobre ellos te muestra el color en hex. Si no puedes reemplazar la función createColorElement por la siguiente:

          function createColorElement (color) {
            return Object.assign(document.createElement('SPAN'),
                    {style: `background: ${color}; color: #FFF; padding: 5px`, innerText: color})
          }
gusbemacbe commented 5 years ago

Hola @daniruiz

He substituído por return Object.assign(document.createElement('P'). Ahora mejor:

imagem

gusbemacbe commented 5 years ago

Hola @daniruiz !

Me gustaría saber se el README está todo bien.

gusbemacbe commented 5 years ago

Hola @daniruiz !

Me gustaría saber tus opiniones.

A pesar de que el demo 2 sea muy útil para copiar todos os códigos hexadecimales de una vez por todas, pero es una mala idea convertir con uno color de Telinkrin dos diferentes colores negros, un color azul y un color verde oscuro para el mismo color de Telinkrin como ves arriba.

Por eso, voy a utilizar el SVG para utilizar el selector de color para seleccionar color por color para copiar código hexadecimal por código hexadecimal. Sí, tendré paciencia para copiar cada un de 850 colores.

O tal vez voy a utilizar el filtro de SVG en todos los archivos SVG, pero sé que KDE no soporta ese filtro, por eso, pensaré en convertir todos los iconos de las carpetas 64/scalable con el filtro para PNG para KDE. No sé se piensas que eso es una mala idea.

daniruiz commented 5 years ago

No entiendo cual es la diferencia entre mi código y el filtro svg, deberían hacer lo mismo

gusbemacbe commented 5 years ago

Hola @daniruiz !

Aquí esta el imagen fácil de entender (hace un clic para ampliarlo):

ejemplo

daniruiz commented 5 years ago

Aaaah!!! vale, ya se por que es. Cuando saque un tiempo lo soluciono :)

daniruiz commented 5 years ago

Vale! creo que esto está. Confirmame si funciona bien. Lo entendí mál y asigne un valor mínimo y máximo para la luz, por eso hay colores que dan el mismo resultado al convertirlos a la paleta telinkrin. Solo tenía que añadir esto:

light = light * (maxLight - minLight) / 100 + minLight

He actualizado el test de codepen con los cambios https://codepen.io/anon/pen/qgJpMV?editors=1000

gusbemacbe commented 5 years ago

Hola @daniruiz !

¡Excelente!

¡Podré convertir todos 850 colores en Telinkrin y copar todos los códigos hexadecimales e una vez por todas para el archivo!

Se hay todo bien o algo problema, contactaré a ti.

gusbemacbe commented 5 years ago

Hola @daniruiz

Se cambiar de return hslToHex([195, 34, light]) (azul desaturado) para return hslToHex([24, 207, light]) (naranja desaturado), los colores convertidos no son exhibidos, creo que es por causa del 207.

gusbemacbe commented 5 years ago

He entendido ahora, este JavaScript limita el máximo 100. He cambiado de 207 para 100.

daniruiz commented 5 years ago

Sí, es en formato 0-100% de saturación y de luz. El tono/hue es de 0 a 360

gusbemacbe commented 5 years ago

@daniruiz , ¿saturación por porcentaje? ¡Hace sentido!

He convertido hsv(24, 207, 212) para hsl(24, 68%, 49%). He puesto [24, 68, light]. :-)