【问题标题】:Spring behavior simulation弹簧行为模拟
【发布时间】:2012-06-29 00:33:53
【问题描述】:

基本上,我想在绘制的图像上模拟弹簧行为。我想让它通过几次迭代来放大和缩小(就像它固定在弹簧上一样)。

我在网上找到的所有例子都指向这个类 - FloatSpring.java

它应该提供将 A 点移动到 B 点所需的计算,应用取决于各种 FloatSpring 类设置的类似弹簧的效果。问题是我没有找到一个如何正确使用它的清晰示例。

我做了这个小例子来测试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 );
}

在此示例中,zoom 属性应在计时器周期内从 1f 反弹到 3f,最终将显示在组件上的图像进行 3 倍缩放。类似于简单的动画过渡。

FloatSpring 类应该没问题 - 我只是不明白如何正确使用它。确切地说 - 我应该指定什么作为 springKdampingK 值以及 time 属性的用途还不清楚......

我非常感谢那里的任何帮助。

【问题讨论】:

    标签: java swing timer paintcomponent imageicon


    【解决方案1】:

    这是一个使用 FloatSpring 的工作 sscce

    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();
            }
        }
    }
    

    【讨论】:

    • 谢谢,这正是我想要的!
    猜你喜欢
    • 1970-01-01
    • 2017-06-22
    • 2018-11-22
    • 2012-03-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    相关资源
    最近更新 更多