Loading...
Logo
Processing Forum
Hi guys,
Is there a way to get a vertical gradient fill on a rounded rectangle?
Something like that :




Thanks

Replies(7)

There are actually several ways.
One is to drawn the gradient in a simple rectangle, then to chop off the shape you need with a mask.
Another is to draw it in SVG, to load this file and to display it.
The first solution is more flexible...
Thanks for the reply.

Yeah, like you just said, I need flexibility. The shape will have to be flexible horizontally. My goal is to make a sliders for a GUI. It needs to be kinda clean so I'll sure need a smooth on my sketch. If I do the first solution, I won't be able to smooth the rounded corners.

Have any other idea? Maybe in jogl?
PImage img = createImage(100, 100, ARGB);
PGraphic pg = createGraphics(100,100, P2D);

//create your gradient in a PImage
img.loadPixels();
for (int i = 0; i < img.pixels.length; i++) {
  img.pixels[i] = color(0, 90, i % img.height* 2); 
}
img.updatePixels();

//create your mask in a PGraphics
pg.beginDraw();
pg.background(0);
pg.smooth();
pg.noStroke();
pg.fill(255);
pg.rect(0,0,pg.width,pg.height,20,20); //unreferenced rounded rect
pg.endDraw();

img.mask(pg); // apply your mask

image(img,0,0);


this should do the trick

http://makio135.com/
Thanks Makio135, but it's impossible to get smooth borders this way.
This is pretty much the #1 solution from PhiLho's post,

thank again for helping me out :)
any other solution for this tricky post ?
Proof-of-concept of another route...

I think this type of code would work quite well in a GLSL shader.

Code Example
Copy code
  1. color bgColor = color(0);

  2. void setup() {
  3.   size(500, 500);
  4. }
  5.  
  6. void draw() {
  7.   background(bgColor);
  8.   loadPixels();
  9.   for (int y=0; y<height; y++) {
  10.     for (int x=0; x<width; x++) {
  11.       float in = inSquircle(x, y, width/2, height/2, width/2-20);
  12.       color c = color((x/2) % 255, (y/2) % 255, 255-(y/2) % 255);
  13.       if (in<1) pixels[x+y*width] = lerpColor(c, bgColor, (in<0.95)?0:map(in,0.95,1,0,1));
  14.     }
  15.   }
  16.   updatePixels();
  17. }
  18.  
  19. float inSquircle(int x, int y, int cx, int cy, float r) {
  20.   return (pow(x-cx, 4) + pow(y-cy, 4)) / pow(r, 4);
  21. }
I tried Makio135's code, tweaked a bit to work well in Processing 2.0b, and the result is smooth (anti-aliased):
Copy code
  1. size(200, 200);
  2. PImage img = createImage(100, 100, RGB);
  3. PGraphics pg = createGraphics(100,100, JAVA2D);
  4.  
  5. //create your gradient in a PImage
  6. img.loadPixels();
  7. for (int i = 0; i < img.pixels.length; i++)
  8. {
  9.   img.pixels[i] = color(0, 90, i % img.height* 2);
  10. }
  11. img.updatePixels();
  12.  
  13. //create your mask in a PGraphics
  14. pg.beginDraw();
  15. pg.background(0);
  16. pg.smooth();
  17. pg.noStroke();
  18. pg.fill(255);
  19. pg.rect(0, 0, pg.width, pg.height, 30); //unreferenced rounded rect; use 30, 30 in 1.5.1
  20. pg.endDraw();
  21.  
  22. img.mask(pg); // apply your mask
  23.  
  24. background(#BBBB88);
  25. image(img, 50, 50);

Thanks a lot, thats exactly it :)
You guys are RAD!

-- Edit

Here's the piece of code i needed to do :

Copy code
  1. PImage img;
  2. PGraphics pg;
  3. color c1;
  4. color c2;
  5. void setup() {
  6.   size(500, 200);
  7.   c1 = color(108, 122, 139);
  8.   c2 = color(68, 82, 99);
  9. }
  10. void draw() { 
  11.  
  12.   background(171, 208, 57);
  13.   if (mouseX != 0) {
  14.     img = generateGradient(c1, c2, mouseX, 100);
  15.     pg = createGraphics(mouseX, 100, JAVA2D);
  16.     //create your mask in a PGraphics
  17.     pg.beginDraw();
  18.     pg.background(0);
  19.     pg.smooth();
  20.     pg.noStroke();
  21.     pg.fill(255);
  22.     pg.rect(0, 0, pg.width, pg.height, 5); //unreferenced rounded rect; use 30, 30 in 1.5.1
  23.     pg.endDraw();
  24.     img.mask(pg); // apply your mask
  25.    
  26.     image(img, 50, 50);
  27.   }
  28.   
  29. }
  30. // Generate a vertical gradient image
  31. PImage generateGradient(color top, color bottom, int w, int h) {
  32.   int tR = (top >> 16) & 0xFF;
  33.   int tG = (top >> 8) & 0xFF;
  34.   int tB = top & 0xFF;
  35.   int bR = (bottom >> 16) & 0xFF;
  36.   int bG = (bottom >> 8) & 0xFF;
  37.   int bB = bottom & 0xFF;
  38.   PImage bg = createImage(w, h, RGB);
  39.   bg.loadPixels();
  40.   for (int i=0; i < bg.pixels.length; i++) {
  41.     int y = i/bg.width;
  42.     float n = y/(float)bg.height;
  43.     // for a horizontal gradient:
  44.     // float n = x/(float)bg.width;
  45.     bg.pixels[i] = color(
  46.     lerp(tR, bR, n),
  47.     lerp(tG, bG, n),
  48.     lerp(tB, bB, n),
  49.     255);
  50.   }
  51.   bg.updatePixels();
  52.   return bg;
  53. }