计算';间隔和增量';用于Java Swing中的滑入动画
我正在构建一个应用程序,它的主页中有一个幻灯片,目前我使用Thread.sleep(10)并添加/分到我想要滑动的面板的x位置计算';间隔和增量';用于Java Swing中的滑入动画,java,swing,Java,Swing,我正在构建一个应用程序,它的主页中有一个幻灯片,目前我使用Thread.sleep(10)并添加/分到我想要滑动的面板的x位置 例如:slideIn(30,panel_1,10)
例如:
slideIn(30,panel_1,10)
<这将导致panel_1以30毫秒的间隔滑入,并以10倍的时间减去x,直到panel位于中间/占据幻灯片显示面板。但这种方法的缺点是滑动动画不会平滑,我希望滑动动画/过渡像引导旋转木马一样平滑。有没有办法计算滑动过渡速度的速度和增量/减量值?事实上,我有一个几乎完美的方法。我想你可以为你的动画路径创建一个Path2D,对吗?而且你似乎也想要一个恒定的速度。例如,在计算距离和显示JPanel时,有一些对我的项目()的引用,但是要删除它们并用标准java替换它们应该不难。试试看
public abstract class PathAnimation {
private Path2D mPath;
private double totalLength;
/**
* Be careful to call path.closePath before invoking this constructor
* @param path
*/
public PathAnimation(Path2D path) {
mPath = path;
totalLength = 0;
PathIterator iterator = mPath.getPathIterator(null);
//Point2D currentLocation;// = path.getCurrentPoint();
double[] location = new double[6];
iterator.currentSegment(location);
while (!iterator.isDone()) {
double[] loc = new double[6];
iterator.next();
iterator.currentSegment(loc);
if (loc[0] == 0 && loc[1] == 0) continue;
double distance = MathUtils.distance(location[0], location[1], loc[0], loc[1]);
totalLength += distance;
location = loc;
}
}
@Override
public Point2D getLocationAtTime(int time) {
return getLocationAtTime(time / (double) getTotalAnimationTime());
}
public Point2D getLocationAtTime(double pctTime) {
double len = totalLength * pctTime;
PathIterator iterator = mPath.getPathIterator(null);
double[] location = new double[6];
iterator.currentSegment(location);
while (!iterator.isDone()) {
double[] loc = new double[6];
iterator.next();
iterator.currentSegment(loc);
double distance= MathUtils.distance(location[0], location[1], loc[0], loc[1]);
if (distance > len) {
double pctThere = len / distance;
double xSpot = location[0] * (1 - pctThere) + loc[0] * pctThere;
double ySpot = location[1] * (1 - pctThere) + loc[1] * pctThere;
return new Point2D.Double(xSpot, ySpot);
}
len -= distance;
location = loc;
}
throw new ArrayIndexOutOfBoundsException("Path is too short or time is too long!");
}
/**
* Number of milliseconds that this animation spans
* @return
*/
public abstract int getTotalAnimationTime();
public static void main(String args[]) {
Rectangle rect = new Rectangle(10,10,20,20);
final Path2D.Double myPath = new Path2D.Double((Shape)rect);
myPath.closePath();
final PathAnimation myAnimation = new PathAnimation(myPath) {
Area star = new Area(PaintUtils.createStandardStar(15, 15, 5, .5, 0));
@Override
public Dimension getSizeAtTime(int time) {
return new Dimension(15,15);
}
@Override
public void paintAtTime(Graphics2D g, int time) {
Area toPaint = star;
if ((time / 150) % 2 == 1) {
Dimension size = getSizeAtTime(0);
toPaint = new Area(toPaint);
PaintUtils.rotateArea(toPaint, Math.PI / 6);
}
g.setColor(Color.YELLOW);
g.fill(toPaint);
g.setColor(Color.RED);
g.draw(toPaint);
}
@Override
public int getTotalAnimationTime() {
return 10000;
}
};
System.out.println(myAnimation.getLocationAtTime(0));
System.out.println(myAnimation.getLocationAtTime(2500));
System.out.println(myAnimation.getLocationAtTime(4000));
System.out.println(myAnimation.getLocationAtTime(5000));
System.out.println(myAnimation.getLocationAtTime(7000));
System.out.println(myAnimation.getLocationAtTime(7500));
System.out.println(myAnimation.getLocationAtTime(9000));
System.out.println(myAnimation.getLocationAtTime(10000));
final JPanel jp = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int time = ((int) System.currentTimeMillis()) % myAnimation.getTotalAnimationTime();
int time2 = (time + myAnimation.getTotalAnimationTime() / 2) % myAnimation.getTotalAnimationTime();
Point2D pt = myAnimation.getLocationAtTime(time);
Point2D pt2 = myAnimation.getLocationAtTime(time2);
Dimension size = myAnimation.getSizeAtTime(time);
g2.translate(pt.getX() - size.width / 2, pt.getY() - size.height / 2);
myAnimation.paintAtTime(g2, time);
g2.translate(- (pt.getX() - size.width / 2), - (pt.getY() - size.height / 2));
g2.translate(pt2.getX() - size.width / 2, pt2.getY() - size.height / 2);
myAnimation.paintAtTime(g2, time2);
g2.translate(- (pt2.getX() - size.width / 2), - (pt2.getY() - size.height / 2));
g2.setColor(Color.BLACK);
g2.draw(myPath);
}
};
WindowUtilities.visualize(jp);
AbstractAction action = new AbstractAction() {
public void actionPerformed(ActionEvent ae) {
jp.repaint();
}
};
javax.swing.Timer t = new javax.swing.Timer(30, action);
t.start();
}
}
改变你的想法。与其按固定的增量移动,不如在给定的时间段内从起点移动到目标点,加入慢进/慢出概念意味着增量可以是可变的。我会看看计时框架、通用Tween引擎或Trident,它们都是提供基于时间的动画的动画框架