jaames / iro.js

🎨 Modular color picker widget for JavaScript, with support for a bunch of color formats
https://iro.js.org
Mozilla Public License 2.0
1.32k stars 83 forks source link

iro.js 5.0 discussion #83

Closed jaames closed 4 years ago

jaames commented 5 years ago

What a wild year! iro.js hit 500 stars on Github, over 1000 NPM installs per week, and was featured on a number of web publications such as Creative Bloq, Codrops and JS Weekly!

I've been thinking a lot about what the next steps for this project might look like now that it's finally stable and fitting most people's requirements pretty well. I figured it would be worth sharing my ideas for discussion:

I think this would take iro.js to the next level and make it one of the best damn color picker libraries out there. I welcome everybody's opinions though!

rjsachse commented 5 years ago

i would really like the kelvin scale to be implemented. i am designing a app now to control led lights and this would be a added bonus. also might b able to add it to the esp8266 milight hub

jaames commented 5 years ago

Svelte has matured a lot recently, and it seems like a good time to investigate whether it's worth using it for the standalone version instead of Preact.

Small update: I've made a semi-working Svelte port of the standalone version of iro.js. I'm not convinced that it's worth going forward with this idea:

I'm going to investigate updating the codebase to make use of new Preact X features and see how that works out instead :)

jaames commented 5 years ago

An option to choose a vertical layout has been requested for a long time, it's probably time to make an effort to implement that

Pull request #85 adds the groundwork for this via a global layoutDirection prop. This will be merged into iro.js after the move Typescript and Preact X is done :)

jaames commented 5 years ago

The typescript port was making good progress, and I think it could perhaps be used as a base for the new iro-core package.

I made some pretty good progress with this today! The Typescript port is complete, although it needs a bit of polish, and I think I may eventually move the build process over to microbundle to simplify that a bit.

I've also been thinking a lot about how the "split-core" idea could work. My initial plan was to separate all of the code that wasn't directly related to the UI (e.g. color conversion) into an "iro-core" package and leave the UI implementation ambiguous, although on second thought I think it's also sensible to expose some generic UI utilities (like some methods to get the handle position for a slider given a specific color, or getting the orientation of a hue wheel when given specific options, etc). This would make it a lot easier for different UI implementations to remain consistent, and a nice added benefit is that all these methods could be easily tested with the current automated test setup!

jaames commented 5 years ago

I made some significant progress with the split core milestone! You can see the new iro-core package at https://github.com/jaames/iro-core

This will act as a base set of functionality thats shared across multiple UI implementations, including the current standalone version of iro.js and any future components for specific frameworks like React or Vue :)

DanielPeinhopf commented 5 years ago

Would be great to also support multiple thumbs with numbers for choosing multiple colors on one picker. This could be usefull for animations of LED lighting. :)

jaames commented 5 years ago

@DanielPeinhopf Thanks for the input! I can see how picking multiple colors at once might be useful, I'll have to think about how to implement that though :)

jaames commented 5 years ago

A lot of people like iro.js for its color wheel, but what if other colorpicker types (such as the common hue-saturation square) were available, with the same frictionless API?

Also, I just implemented an optional hue-saturation square to see how it would fit with the rest of the picker. This means iro.js could be made into the same type of color picker you see elsewhere.

Screenshot 2019-10-21 at 00 52 24

It doesn't add too much extra code (<1kb), but I'm not sure if anyone is desperate to have this as an option.

Would it be useful?

jcesarmobile commented 5 years ago

Have you looked at stencil? It uses jsx too and it’s supposed to make it easy to export a component for angular and react

jaames commented 5 years ago

@jcesarmobile Stencil is neat, I've used it before for an unrelated project

My only real complaint is that it lazy-loads extra polyfill scripts, since my motivation for creating iro.js came from wanting a colorpicker library that could be dropped into a project as a single script without any extra jQuery / images / css / etc, I feel like it wouldn't be suitable

I might consider it again in the future, their fall 2019 roadmap looks promising :)

jaames commented 5 years ago

Taking a short break from code to mock up a new design for the iro.js.org landing page. The current one is pretty minimal and doesn't really show what iro.js can do very well. I decided I want to put more focus on being a bit more flashy and visually demonstrating what sets iro.js apart from other javascript color pickers.

I also think it's important to have a basic setup guide on the initial landing page now, especially when there's going to be three separate packages (iro.js, iro-react and iro-vue). Users will be able to toggle between packages to show setup information for the one that's most relevant to their needs.

I welcome any feedback on this preview! Just note that it's definitely not 100% finished yet :)

Desktop HD

DanielPeinhopf commented 5 years ago

I love it. Cant wait to see it in action 😍

bakman2 commented 5 years ago

I'd like to make a plugin for some lighting-specific utilities and UI components for working with kelvin scale colors, since no other javascript color pickers seem to be targeting that.

Would a brightness slider fit in there as well ? And to top it off - a slider without a wheel (as some lights only support brightness and no color). Or is that like the last example on the mockup ? Would be nice.

jaames commented 5 years ago

@bakman2 Removing components (and adding extra ones) can already be done with Custom Layouts, although granted, redoing this documentation is on the to-do list since it's not particularly obvious right now :)

I'm unsure if a brightness slider (referring to the intensity of a light source rather than the color of it?) is really within iro.js' area of expertise, I'd prefer for it to focus on manipulating and choosing a color and let devs build extra controls around it if they need anything else.

bakman2 commented 5 years ago

Thanks for your response

I'm unsure if a brightness slider (referring to the intensity of a light source rather than the color of it?) is really within iro.js' area of expertise, I'd prefer for it to focus on manipulating and choosing a color and let devs build extra controls around it if they need anything else.

I am referring to the L/V in HSL/V, but I guess that is already covered

Do you perhaps have a little hint how I can use this library in vue ? When I include it in my main index.html, somehow I cannot initialize a new picker (using the mount option referred somewhere else in the issues, and using the vue mount() method) - sorry it is offtopic

jaames commented 5 years ago

@bakman2 for now there's a wrapper; https://github.com/irojs/vue-iro-color-picker. This was written by a third party and I'm yet to do any work on it myself, so I can't guarantee that it's totally complete, but it might be useful to reference at least.

In the next week or so I intend to write React and Vue implementations of iro.js as part of the 5.0 milestone.

jaames commented 5 years ago

Speaking of which, it's probably time for a progress report!

iro.js 5.0 is mostly complete and on feature-lock, the current changelog looks something like this:

Additions

Breaking changes

Bundle size

From this point I'm going to focus on code cleanup and new documentation so I can get a 5.0 beta out, after that I plan to work on the React and Vue components and the new landing page.

The first beta should be ready to try in a couple of days, and hopefully 5.0 will be complete in the next week or two depending on how my schedule goes -- I'm also currently working on applying to a job at the same time so I might get a little busy :)

jaames commented 5 years ago

A 5.0.0 beta is now available if anybody would like to try it! This is a beta so obviously I don't recommend using it in production, and documentation is still in progress.

From NPM:

$ npm install @jaames/iro@beta

Manual download:

https://raw.githubusercontent.com/jaames/iro.js/v5-dev/dist/iro.min.js

jaames commented 5 years ago

Hey, sorry for the lack of progress. TBH I've been really struggling with burnout recently and I'm finding it difficult to find motivation to keep going with this project. The job hunt I mentioned also hasn't been going very well -- I live in a very tech-illiterate area and moving isn't possible, so there aren't a lot of options to begin with, and those who are hiring don't seem to be interested in anybody under the age of 30. Overall I feel like I'm stuck in a bit of a rut ¯\_(ツ)_/¯

I'm not, like, starving or anything, so please don't feel obligated, but I would greatly appreciate it if people would consider donating to help support my work on this. I still think open-source is cool but throwing endless hours into something just so that other people can make ungodly amounts of money from your work while you literally get nothing in return... kinda honestly sucks

Thanks :)

RobbieTheWagner commented 4 years ago

@jaames I would be happy to sponsor some work on selecting multiple colors in a single color wheel. I'm trying to replicate the functionality of something like https://color.adobe.com/

I don't have a ton of extra cash, but definitely interested in helping further this along 😃

jaames commented 4 years ago

Sorry for the slow response @rwwagner90, I really appreciate the offer!

Multiple colors should be totally possible, although in order to fit in with other features of iro.js I might have to depart from the way Adobe Color does things a tiny bit.

Can I ask how closely you're hoping to replicate the functionality of Adobe Color? Are you just looking to have multiple colors on one picker or do you also need color harmonies etc?

RobbieTheWagner commented 4 years ago

@jaames I am implementing the harmonies myself, I would just need the color wheel to accept multiple values and I would supply the values.

jaames commented 4 years ago

@rwwagner90 Alright, that shouldn't be too complicated then! I'm going to be a little busy until the new year, but I'll start working on multicolor and wrap up iro 5.0 as soon as I can after that :)

RobbieTheWagner commented 4 years ago

@jaames what's the best way to donate to the cause?

jaames commented 4 years ago

@rwwagner90 I usually take donations for iro.js via PayPal if that works for you, otherwise I could try getting set up with GitHub Sponsors or something

RobbieTheWagner commented 4 years ago

@jaames GitHub sponsors should have matching I think, unless that is over now. Maybe try setting it up?

jaames commented 4 years ago

@rwwagner90 Great, thanks for the tip! I applied to GitHub sponsors over the holidays and got accepted earlier today. Looks like I was just in time to be eligible for donation matching :)


I've also put a plan together for multicolor support. I think it should be fairly straightforward if I implemented it like this, although of course I welcome feedback from anyone that's interested!

New config options

var colorPicker = new iro.ColorPicker({
  ...
  colors: [
    '#fff',
    'rgb(255, 0, 0)',
    {h: 300, s: 20, v: 50}
  ],
})

New iro.ColorPicker properties


// Set color 0 to rgb(255, 0, 0) 
colorPicker.colors[0].rgb = { r: 255, g: 0, b: 0 };

// Get color 3 as a hex string
const hex = colorPicker.colors[3].hexString;

Additionally, colorPicker.color will also always map to colorPicker.colors[0].

New iro.ColorPicker methods

iro.ColorPicker events

I think events can remain mostly unchanged, but the color objects passed to events like color:change, input:change, etc will have a new index prop that indicates which color the event is referring to:

colorPicker.on('color:change', function(color) {
  if (color.index === 0) {
    // color 0 changed
  }
  else if (color.index === 3) {
    // color 3 changed
  }
});

UI changes

iro.Wheel and iro.Box (introduced in 5.0) will be updated to support multiple color handles, much like Adobe Color. Simpler components like iro.Slider will only show one handle at a time, but will be linked to whichever color is 'active'. The active color will usually be the color the user most recently interacted with, unless this is changed with setActiveColor().

I think I may also add a compact swatch UI component for the user to select the active color in layouts where the wheel/box aren't present.

RobbieTheWagner commented 4 years ago

@jaames just sponsored you! All of your proposed changes sound great to me 😃

jaames commented 4 years ago

@rwwagner90 Thank you so much, it's really appreciated! I'll start working on multicolor right away, in the meantime please let me know if you'd like me to add you/your company to the 'Supporters' section on the iro.js readme and website :)

RobbieTheWagner commented 4 years ago

@jaames you are so welcome! Yes, if you could please list my company, Ship Shape, that would be great. Do you need a logo from me?

jaames commented 4 years ago

@rwwagner90 Sure thing! Yeah a logo would be great -- preferably in a vector format if you have that handy. I'm guessing the link should be https://shipshape.io?

RobbieTheWagner commented 4 years ago

@jaames Yeah, that's the url. It will not let me upload the svg here. Are you on discord?

jaames commented 4 years ago

@rwwagner90 I'm jaames#9860 on Discord, or you can email me at mail@jamesdaniel.dev if that's any easier :)

luckyTamme commented 4 years ago

Just wanted to thank you for you great work! I implement your Color Picker at the moment for my smart light build with WS2812 LED strips and a yeelight and it's very easy to use but at the same time helped me to get really into colors (HSV etc...). Keep it up!

jaames commented 4 years ago

Thank you @zecjy, that's really great to hear! :)


Also @rwwagner90 I have a basic multicolor implementation working, it still needs some polish (as well as tests, documentation, etc) but it should be ready to start using by next week. :)

Screen Recording 2020-01-06 at 20 59 48

luckyTamme commented 4 years ago

Maybe a small suggestion, since I needed it for my project: Brightness slider based on a logarithmic function. My LED strips have way visible difference from 0-30 then from 30-100 and thus I needed more area on the slider for the lower brightness values.

Also, I couldn't find anything about dynamic sizing of the Picker?

RobbieTheWagner commented 4 years ago

@jaames that is looking amazing! Really looking forward to trying it out 👍

jaames commented 4 years ago

@zecjy Logarithmic sliders probably aren’t something that I would add to iro.js directly; I can’t really see a lot of people needing them and I would prefer to keep iro.js free of feature-bloat. With that said, in #94 I mentioned I might consider adding some options for customised sliders, which should make it possible to build a slider like you're asking for, at least if you bring your own math. Do you think that would work for you?

iro.ColorPicker has a resize method you can use to change the size at any point, although granted it's a bit hard to find the documentation for it. I'm gonna be working on that :)

DanielPeinhopf commented 4 years ago

LEDs are very different in its behavior so this should be handled as close as possible to the hardware. So i think your LED controller should handle this. This is also known as gamma correction.

jaames commented 4 years ago

@rwwagner90 I put together a beta build with multicolor support! Everything works as detailed in the feature proposal, except colorPicker.color is always mapped to the currently active color. It needs a little bit more polish, but it should work well enough for testing. Let me know if you need anything!

From NPM:

$ npm install @jaames/iro@beta

Manual download:

https://raw.githubusercontent.com/jaames/iro.js/v5-dev/dist/iro.min.js


I have to focus on freelance work next week, but after that I'll get everything polished for release and return to work on writing v5 documentation and updating the iro.js.org website. :)

RobbieTheWagner commented 4 years ago

Awesome, thanks @jaames! I will play with the beta in the next day or two.

RobbieTheWagner commented 4 years ago

@jaames is there a way to set the selected colors programmatically? I'm able to get it to render with the list of colors, but then I do not know how to overwrite the list with a new set of colors.

jaames commented 4 years ago

@rwwagner90 Yep! Once the color picker is set up you can access the selected colors with colorPicker.colors, which will be an array of color objects. Each of those color objects has several different properties that you can get and set, like with colorPicker.color (docs: https://iro.js.org/guide.html#selected-color-api). When any of these are set to a new value, the color picker will automatically update to match.

Here's some example code to make it a bit clearer:

// Create a color picker with multiple colors
const colorPicker = new iro.ColorPicker({
  ...
  colors: [
    'rgb(255, 0, 0)',
    'rgb(0, 255, 0)',
    'rgb(0, 0, 255)',
  ]
});

// Log the first color value as hsl
console.log(colorPicker.colors[0].hsl) // logs {h: 0, s: 100, l: 50}

// Set the first color to green
colorPicker.colors[0].rgbString = 'rgb(0, 255, 0)';

// Set the second color to white
colorPicker.colors[1].hsv = { h: 0, s: 100, v: 100 };

// Copy the hsv value of the second color to the third color
colorPicker.colors[2].hsv = colorPicker.colors[1].hsv;

Also, while they're not documented yet, there's lots of new iro.Color properties in v5 if you'd like to give them a whirl! They're listed here under "New iro.Color properties": https://github.com/jaames/iro.js/issues/83#issuecomment-547203463

RobbieTheWagner commented 4 years ago

@jaames I need a way to change the entire array of colors, insert and remove colors etc. I'm thinking like

colorPicker.addColor('#ffffff');

colorPicker.removeColor('#ffffff');

colorPicker.setColors([
    'rgb(255, 0, 0)',
    'rgb(0, 255, 0)',
    'rgb(0, 0, 255)',
  ]);

The use case is for selecting a color palette and changing out all the colors to match the palette. An alternative would be to create a new iro instance each time, but I wasn't sure the correct way to destroy the existing one before creating a new one.

jaames commented 4 years ago

@rwwagner90 colorPicker.addColor() and colorPicker.removeColor() are implemented, although removeColor() expects the color's index to be passed as an argument rather than the color's value.

I'll look at adding something like setColors() when I get the chance, but here's what a basic implementation that matches your suggestion would look like:

iro.ColorPicker.prototype.setColors = function(newColorValues) {
  // Unbind color events
  this.colors.forEach(color => color.unbind());
  // Destroy old colors
  this.colors = [];
  // Add new colors
  newColorValues.forEach(colorValue => this.addColor(colorValue));
  // Reset active color
  this.setActiveColor(0);
}
DanielPeinhopf commented 4 years ago

The new multi color picker is great 👍 Many many thanks. Would it be possible to add an option to display index numbers around the thumbs? And another great thing would be to add new thumbs by clicking somewhere inside the wheel, instead of moving the thumb which has been selected last.

RobbieTheWagner commented 4 years ago

@jaames ah, thanks! I did not see addColor or removeColor in the docs. Are they new for 5.0?

jaames commented 4 years ago

@rwwagner90 no problem! yeah, theyre new, they were added as part of the multicolor proposal above :)

@DanielPeinhopf I like those ideas! I think I'll save them for a future version though, I really need to focus on updating documentation for now

RobbieTheWagner commented 4 years ago

@jaames how are things going?

RobbieTheWagner commented 4 years ago

I need a way to know which handle is associated with which color, so I can "select" the handle and style it differently, move it above all other handles, etc. Is this something that is currently supported? Like how on color.adobe.com when you click other colors it moves the handle above all the other handles.