简体   繁体   English

在 Java Swing 中计算动画幻灯片的“间隔和增量”

[英]Calculate 'interval and increment' for slide in animation in Java Swing

I'm building an application which has a slideshow in its homepage, currently I use Thread.sleep(10) and add/sub the x position of panel I want to slide.我正在构建一个在其主页上有幻灯片的应用程序,目前我使用 Thread.sleep(10) 并添加/子我想要滑动的面板的 x 位置。

For example: slideIn(30, panel_1, 10) < this will cause panel_1 to slide in with interval of 30ms and subtracts its x by 10 overtime until the panel is in center/occupy the slideshow_panel.例如: slideIn(30, panel_1, 10) < 这将导致 panel_1 以slideIn(30, panel_1, 10)毫秒的间隔滑入并减去其 x 10 加班,直到面板居中/占据幻灯片面板。 But the con of this method is that the sliding animation won't smooth, I want the sliding animation/transition as smooth as Bootstrap Carousel.但是这种方法的缺点是滑动动画不会平滑,我希望滑动动画/过渡像 Bootstrap Carousel 一样平滑。 Is there a way to calculate the speed and increment/decrement value for slide transition speed?有没有办法计算滑动过渡速度的速度和增量/减量值?

Actually, I've something that's almost perfect for this.实际上,我有一些几乎完美的东西。 I assume you can create a Path2D for your animation path, right?我假设您可以为您的动画路径创建一个 Path2D,对吗? And it also seems like you want a constant speed.而且看起来你想要一个恒定的速度。 There are a couple of references to my project ( http://sourceforge.net/p/tus/code/HEAD/tree/ ) for calculating distance and showing the JPanel for instance, but it shouldn't be hard to remove them and replace with standard java.有几个对我的项目( http://sourceforge.net/p/tus/code/HEAD/tree/ )的引用,用于计算距离和显示 JPanel 例如,但删除它们应该不难替换为标准的java。 Try it out试试看

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM