3

基本的に、ペイントしたイメージで春の動作をシミュレートしたいと思います。スケールアップとスケールダウンを数回繰り返して実行したいと思います(スプリングに固定されているように)。

私がネット上で見つけたすべての例は、このクラスにつながります-FloatSpring.java

さまざまなFloatSpringクラス設定に依存するバネのような効果を適用して、ポイントAをポイントBに移動するために必要な計算を提供する必要があります。問題は、それを適切に使用する方法の明確な例が1つも見つからなかったことです。

テストするために、この小さな例を作成しFloatSpringました。

public static void main ( String[] args )
{
    // Some image to bounce
    final ImageIcon icon =
            new ImageIcon ( WebProgressOverlayExample.class.getResource ( "icons/ava1.jpg" ) );

    // Component to paint image on
    JComponent spring = new JComponent ()
    {
        // Zoom value (1f = 100% = normal size)
        float zoom = 1f;

        {
            // Basic spring settings
            final FloatSpring fs = new FloatSpring ( 100 );
            fs.setPosition ( zoom );

            // Animation delay
            final int delay = 1000 / 24;

            // Animator
            new Timer ( delay, new ActionListener ()
            {
                private float elapsed = 0f;

                public void actionPerformed ( ActionEvent e )
                {
                    // Increasing elapsed time and updating spring
                    elapsed += delay;
                    fs.update ( 3f, elapsed );

                    // Updating zoom value and component
                    zoom = fs.getPosition ();
                    repaint ();
                }
            } ).start ();
        }

        protected void paintComponent ( Graphics g )
        {
            super.paintComponent ( g );

            // Scaled image
            int width = Math.round ( icon.getIconWidth () * zoom );
            int height = Math.round ( icon.getIconHeight () * zoom );
            g.drawImage ( icon.getImage (), getWidth () / 2 - width / 2,
                    getHeight () / 2 - height / 2, this );
        }

        public Dimension getPreferredSize ()
        {
            return new Dimension ( 500, 500 );
        }
    };

    JFrame frame = new JFrame ();
    frame.add ( spring );
    frame.pack ();
    frame.setLocationRelativeTo ( null );
    frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
    frame.setVisible ( true );
}

この例では、プロパティはタイマーサイクル内で1fから3fzoomにバウンスし、最後にコンポーネント画像に表示されるものを3倍ズームに導く必要があります。単純なアニメーショントランジションのようなもの。

FloatSpringクラスは問題ないはずです-私はそれを正しく使用する方法を理解していません。springK正確には、とのdampingK値として何を指定する必要があり、timeプロパティの目的も明確ではありません...

そこで助けていただければ幸いです。

4

1 に答える 1

6

これは、を使用した動作中のsscceFloatSpringです。

バンジー

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;

/**
* @see http://stackoverflow.com/a/11233735/230513
*/
public class Test {

    private static Spring spring = new Spring();

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(spring);
                frame.add(new JButton(new AbstractAction("Start") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        spring.start();
                    }
                }), BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                spring.start();
            }
        });
    }

    private static class Spring extends JComponent {

        private static final int SIZE = 500;
        private static final int DELAY = 1000 / 20; // ~20Hz
        private final Icon icon = UIManager.getIcon("OptionPane.informationIcon");
        private final FloatSpring fs = new FloatSpring(42);
        private final int target = 0;
        private final float delta = 1f / SIZE;
        private float elapsed = 0f;
        private Timer timer = new Timer(DELAY, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if ((int) fs.getPosition() < (target + 1)) {
                    timer.stop();
                    return;
                }
                elapsed += delta;
                fs.update(target, elapsed);
                repaint();
            }
        });

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int x = (getWidth() - icon.getIconWidth()) / 2;
            int y = (int) fs.getPosition();
            icon.paintIcon(this, g, x, y);
            int xc = x + icon.getIconWidth() / 2;
            g.drawLine(xc, 0, xc, y);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(SIZE / 2, SIZE);
        }

        public void start() {
            timer.stop();
            elapsed = 0;
            fs.setPosition(SIZE - icon.getIconHeight());
            fs.setVelocity(0);
            timer.start();
        }
    }
}
于 2012-06-27T19:39:30.643 に答える