2017-08-10 13 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

これはかなりうまくいく、どのように私はそれをすべての色を通してサイクリングを避けるために適応させるだろうか?フルスペクトルの代わりに2つのベースカラー。 –

+0

@サンティアゴ・ローサレス:私は上記の1つのアプローチを提案しました。 – trashgod

関連する問題