基本上,我想在绘制的图像上模拟弹簧行为。我想让它通过几次迭代来上下缩放(就像在弹簧上修复一样)。
我在网上找到的所有示例都会导致此类 - 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类应该没问题 - 我只是不明白如何正确使用它。确切地说 - 我应该指定什么springK
和dampingK
值以及time
属性目的不明确......
我真的很感激那里的任何帮助。
答案 0 :(得分:6)
这是一个使用sscce的工作FloatSpring
。
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();
}
}
}