P5 colorMode doesn't work properly in observablehq

Hello everyone,
It’s my first topic here so do not hesitate to tell me if i transgress forum rules.

I’m currently trying to use p5 in observablehq (after trying three and d3 :D)
I made some meta bubbles with loadPixels method (it’s lag a lot i know but anyway)
I succeed i think but when i tried to color my meta balls with colorMode(hsb) it’s not working…
I tried to investigate in the p5 object … the colorMode attribute changed to hsb but visually it’s not doing anything it’s keep display the rgb colors …

Here is my note

Hi Emilie,

Sure - so this is pretty similar to the previous issue about the pixels[] array not being an array of colors. The p5.js colorMode function changes the colorMode that affects the color(), fill(), stroke(), and background() methods - but this sketch doesn’t use those methods - it writes directly to the canvas. The canvas is still RGBA, regardless of what colorMode is - and regardless of environment, this won’t work with p5.js on a page or in any other situation.

To fix this ‘the p5.js way’, you’d create a p5.Color object and then read the (translated) rgb values out of it:

        let color = sketch.color(sumOfBubbleColors, 255, 255);
        sketch.pixels[index] =  sketch.red(color)
        sketch.pixels[index + 1] =  sketch.blue(color)
        sketch.pixels[index + 2] =  sketch.green(color)

I don’t recommend you do this: it’s incredibly, extremely slow. p5.js is not very efficient in cases like this, where you’re setting lots of individual pixels, and is really designed more for the case where you’re using its geometry methods, like ellipse() and rect().

What I do recommend is using the simpler, faster hsv2rgb module for this color conversion:

        let [r, g, b] = hsv2rgb(sumOfBubbleColors, 255, 255);
        sketch.pixels[index] =  r
        sketch.pixels[index + 1] =  g
        sketch.pixels[index + 2] =  b

and in a separate cell,

hsv2rgb = require('https://bundle.run/hsv2rgb')

That’ll be at least fast enough to draw the desired rainbow-color visualization, without slowing down the page too much.

1 Like

hello @tom,

Thanks a lot to help me.
And you’re not the first to make the mistake
but it’s emile without pronouncing the e at the end :smile:

I’ll try what you suggest today.

Do you have any advice about the speed of load pixel ?
If there is no way to speed it I think i’ll try another technology to make these metaballs …

Ah, sorry about that Emile - American typing habits :dizzy_face:

So - in terms of what to do - well, you’re barely using p5.js at all, you’ve already learned how to use the HTML5 Canvas API, so why not run this in Canvas? Here’s a fork that does just that - runs the sketch without p5.js involved at all, and it runs pretty fast with a larger canvas: https://beta.observablehq.com/@tmcw/meta-bubbles

2 Likes