1

I made a java paint application and I made a rainbow brush function; however, I want to make the randomized colors into a smooth gradient. It is currently just printing ovals of differently colors and you can notice each distinct oval. Is there a way to make it a gradient?

Paint Project - CLICK HERE TO SEE PROGRAM

My Rainbow Fuction:

public void rainbow() {
    Random generator = new Random();
    int r = generator.nextInt(256);
    int g = generator.nextInt(256);
    int b = generator.nextInt(256);
    Color color = new Color(r, g, b);
    g2.setPaint(color);
}

My Mouse Listeners:

public DrawArea() {

    addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            // save coord x,y when mouse is pressed
            oldX = e.getX();
            oldY = e.getY();
        }
    });

    addMouseMotionListener(new MouseMotionAdapter() {
        public void mouseDragged(MouseEvent e) {
            // coord x,y when drag mouse
            currentX = e.getX();
            currentY = e.getY();

            if (g2 != null) {
            // draw oval if g2 context not null
            g2.drawOval(oldX, oldY, 40, 40);
            g2.fillOval(oldX, oldY, 40, 40);

            // refresh draw area to repaint
            repaint();

            // store current coords x,y as olds x,y
            oldX = currentX;
            oldY = currentY;
            }
        }
    });
}

Paint Component:

public void paintComponent(Graphics g) {
    if (image == null) {
        image = createImage(getSize().width, getSize().height);
        g2 = (Graphics2D) image.getGraphics();
        clear();
    }
    // enable antialiasing
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,      RenderingHints.VALUE_ANTIALIAS_ON);
    g.drawImage(image, 0, 0, null); 
}
flowinwind
  • 69
  • 1
  • 11

1 Answers1

0

I presume you're calling your rainbow function every ticks, which is why you get the effect as such.

To create the illusion of having a gradient, the r,g,b values must be changing slow enough to have the desired effect.

One way you can do that is by storing the value you want to LERP (see: https://en.wikipedia.org/wiki/Linear_interpolation) to.

//declare a variable to store the destinated Color;
public Color colorToBeLerped = null;
public Color currentColor = null;
public Color originalColor = null;

public final float deltaFactor = 0.2;

public void rainbow() {

    if(currentColor==null||currentColor.equals(colorToBeLerped)){
        Random generator = new Random();
        int r = generator.nextInt(256);
        int g = generator.nextInt(256);
        int b = generator.nextInt(256);
        colorToBeLerped = new Color(r, g, b);
        originalColor = colorToBeLerped;
    }
    if(currentColor==null){
        currentColor=colorToBeLerped;
    }else{
    //using the Color constructor that accepts float arguments, divide 255
        currentColor= new Color((colorToBeLerped.getRed()-originalColor.getRed()*deltaFactor)/255,
                                (colorToBeLerped.getGreen()-originalColor.getGreen()*deltaFactor)/255,
                                (colorToBeLerped.getBlue()-originalColor.getBlue()*deltaFactor)/255);
    }


    g2.setPaint(currentColor);
}

Explaination:

1.Keep track of the color you want to lerp to, the current color you are in and the original color when the randomize function is called.

2.When we the first time rainbow function is called, current color will be set to the randomized color.

3.For every tick, if the current Color is not the destination color, we will increment by 1/5 of how much the difference is between original Color and destination Color.

4.A constant delta factor of 0.2 means that we will need 5 ticks to get from one color to another color, the lesser this variable is, the longer it will get from your original color to the destination color.

5.If we have reached the color, we will elect another new destination color.

*Not tested but I think you can figure out the rest

Mc Kevin
  • 962
  • 10
  • 31