2017-08-10 185 views
0

我想爲JPanel設置一個動畫漸變背景。效果起作用,但我希望在重新開始時順利過渡。以下是我目前的實施。當xvalue2達到極限集時,我交換顏色並重新開始。平滑漸變背景動畫java

public class GradientAnimation { 
static class GradientPanel extends JPanel { 
    private static final long serialVersionUID = -4185583782901846967L; 
    private Timer timer; 
    private float Xend; 
    private final float MAXVALUE = 800f; 
    private Color color1 = new Color(128,62,153,255); 
    private Color color2 = new Color(192,201,200,255); 

    GradientPanel() { 
     Xend = 0f; 
     setOpaque(true); 
     ActionListener action = new ActionListener(){ 

      @Override 
      public void actionPerformed(ActionEvent evt){ 
       if (Xend < MAXVALUE) Xend+=2f; 
       else{ 
        Color aux = color1; 
        color1 = color2; 
        color2 = aux; 
        Xend = 0f; 
       } 

       revalidate(); 
       repaint(); 
      } 
     }; 
     timer = new Timer(5, action); 
     timer.start(); 
    } 
    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 
     final BufferedImage image = new BufferedImage(
       getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); 
     g2d = image.createGraphics(); 
     GradientPaint prim = new GradientPaint(0f, 0f, color1, 
       Xend, 0f, color2); 

     g2d.setPaint(prim); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 

     g.drawImage(image, 0, 0, null); 
    } 
} 

private static void createAndShowUI() { 
    try { 
     JFrame frame = new JFrame("Gradient Animation"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.setResizable(false); 

     GradientPanel imagePanel = new GradientPanel(); 

     frame.add(imagePanel); 
     frame.setSize(400, 400); 
     frame.setVisible(true); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public static void main(String[] args) { 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowUI(); 
     } 
    }); 
    } 
} 

再一次,我想隱藏一段時間,我交換顏色有一個完美的梯度動畫循環。如果代碼看起來正確,請告訴我,我如何提高質量。

+0

請不要爲填料張貼廢話作爲擊敗限制的目的,而不是玩公平與我們的志願者誰還會幫你。相反,請告訴你的問題的細節,代碼的作用,它應該做什麼。 –

+0

是的,我明白了。但是與代碼相比,我的解釋太短了,我想發佈一個工作代碼而不是代碼片段,因此可以對其進行測試。抱歉。 –

+0

因此,添加更多的解釋,而不是廢話。幫助我們理解你寫的代碼,描述它。再一次,你的幫助我們只會幫助你。 –

回答

4

在下面的變型中,

  • 使用Color.getHSBColor()循環通過可用色調;因爲色調值環繞,所以通過光譜的轉變是平滑的。或者,在終點處更改delta的符號。

  • 重寫getPreferredSize()以建立初始面板幾何。

  • 不要緩衝不必要的渲染。

  • 不要重新驗證組件不必要的。

image

我將如何適應它通過所有的顏色,以避免騎自行車嗎?

無盡的變化是可能的;關鍵問題是避免突然的變化。在這裏,HUE_MINHUE_MAX被縮小到頻譜的一部分,delta的符號在端點處發生變化,其他HSB組件得到更新。

private static final float HUE_MIN = 4f/6; 
private static final float HUE_MAX = 5f/6; 
… 
    @Override 
    public void actionPerformed(ActionEvent evt) { 
     hue += delta; 
     if (hue > HUE_MAX) { 
      hue = HUE_MAX; 
      delta = -delta; 
     } 
     if (hue < HUE_MIN) { 
      hue = HUE_MIN; 
      delta = -delta; 
     } 
     color1 = Color.getHSBColor(hue, 1, 1); 
     color2 = Color.getHSBColor(hue, 3f/4 + delta, 3f/4 + delta); 
     repaint(); 
    } 

image

代碼:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

/** @see https://stackoverflow.com/q/45603312/230513 */ 
public class GradientAnimation { 

    static class GradientPanel extends JPanel { 

     private static final int WIDE = 640; 
     private static final int HIGH = 240; 
     private static final float HUE_MIN = 0; 
     private static final float HUE_MAX = 1; 
     private final Timer timer; 
     private float hue = HUE_MIN; 
     private Color color1 = Color.white; 
     private Color color2 = Color.black; 
     private float delta = 0.01f; 

     GradientPanel() { 
      ActionListener action = new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent evt) { 
        hue += delta; 
        if (hue > HUE_MAX) { 
         hue = HUE_MIN; 
        } 
        color1 = Color.getHSBColor(hue, 1, 1); 
        color2 = Color.getHSBColor(hue + 16 * delta, 1, 1); 
        repaint(); 
       } 
      }; 
      timer = new Timer(10, action); 
      timer.start(); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      GradientPaint p = new GradientPaint(
       0, 0, color1, getWidth(), 0, color2); 
      g2d.setPaint(p); 
      g2d.fillRect(0, 0, getWidth(), getHeight()); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(WIDE, HIGH); 
     } 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("Gradient Animation"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     GradientPanel imagePanel = new GradientPanel(); 
     frame.add(imagePanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
+0

這工作得很好,我將如何適應它以避免騎自行車穿越所有顏色?兩種基本顏色,而不是全光譜。 –

+0

@SantiagoRosales:我提出了上面的一種方法。 – trashgod