为啥我的动画圈子的位置会闪烁?
Posted
技术标签:
【中文标题】为啥我的动画圈子的位置会闪烁?【英文标题】:Why does the locaton of my animated circles flicker?为什么我的动画圈子的位置会闪烁? 【发布时间】:2020-09-29 21:40:30 【问题描述】:通过trident,我创建了一个(看似)简单的动画。一些圆圈正在从底部移动到顶部,然后通过正弦插值再次返回:
动画本身似乎可以正常工作,但是有一两帧我的所有球体都闪烁到最高位置。
为什么会闪烁?谁在用看似错误的值调用setY
方法?
我制作了一个测试类来重现该行为。您需要radiance-trident 3.0 才能使其工作:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JDialog;
import javax.swing.JPanel;
import org.pushingpixels.trident.api.Timeline;
import org.pushingpixels.trident.api.Timeline.RepeatBehavior;
import org.pushingpixels.trident.api.ease.TimelineEase;
import org.pushingpixels.trident.api.swing.SwingRepaintTimeline;
public class MovingSpheresTest extends JDialog
private final double sphereRadius = 3d;
private final double sphereCount = 12d;
private final double helixHeight = 100d;
private final double size = 200d;
private final double animationSpeed = 0.5d;
private List<CenteredSphere> spheres;
private SwingRepaintTimeline repaintTimeline;
private final JPanel contentPanel = new JPanel()
protected void paintComponent(Graphics g)
super.paintComponent(g);
paintFrame((Graphics2D) g);
private void paintFrame(Graphics2D g)
Graphics2D create = (Graphics2D) g.create();
try
create.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
create.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
create.setColor(Color.BLACK);
for (CenteredSphere centeredSphere : spheres)
create.fill(centeredSphere);
finally
create.dispose();
;
/**
* Launch the application.
*/
public static void main(String[] args)
try
MovingSpheresTest dialog = new MovingSpheresTest();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
catch (Exception e)
e.printStackTrace();
/**
* Create the dialog.
*/
public MovingSpheresTest()
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setLayout(new FlowLayout());
getContentPane().add(contentPanel, BorderLayout.CENTER);
installSpheres();
installRepaintTimeline();
private void installSpheres()
double helixRadius = helixHeight / 2;
double effectiveWidth = size - (2 * sphereRadius);
double sphereDistance = effectiveWidth / (sphereCount - 1);
double sphereCenterX = sphereRadius;
double sphereCenterY = size / 2d;
double sphereCenterYInitial = sphereCenterY - helixRadius;
spheres = new ArrayList<>();
for (int sphereIndex = 0; sphereIndex < sphereCount; sphereIndex++)
CenteredSphere sphere = new CenteredSphere(sphereCenterX, sphereRadius);
spheres.add(sphere);
sphereCenterX += sphereDistance;
Timeline.builder()
.addPropertyToInterpolate(Timeline.<Double>property("y").on(sphere).from(sphereCenterYInitial)
.to(sphereCenterY + helixRadius))
.setEase(new FullSine((float) (sphereIndex * 2 * Math.PI / sphereCount)))
.setDuration((long) (animationSpeed * 3000d)).playLoop(RepeatBehavior.LOOP);
private class FullSine implements TimelineEase
private float horizontalOffset;
private FullSine(float horizontalOffset)
this.horizontalOffset = horizontalOffset;
@Override
public float map(float durationFraction)
return ((float) Math.sin(durationFraction * Math.PI * 2f + horizontalOffset) + 1f) / 2f;
private void installRepaintTimeline()
repaintTimeline = SwingRepaintTimeline.repaintBuilder(contentPanel).build();
repaintTimeline.playLoop(RepeatBehavior.LOOP);
public class CenteredSphere extends Ellipse2D.Double
private double sphereCenterX;
private double sphereRadius;
public CenteredSphere(double sphereCenterX, double sphereRadius)
this.sphereCenterX = sphereCenterX;
this.sphereRadius = sphereRadius;
public void setY(double y)
setFrameFromCenter(sphereCenterX, y, sphereCenterX + sphereRadius, y + sphereRadius);
【问题讨论】:
【参考方案1】:如上所述here 和固定here,
这很有趣。这是因为基本假设
TimelineEase
始终映射 [0.0-1.0] 区间而不“扭曲”端点。在这种特殊情况下,在每个动画循环期间,自定义FullSine
用于根据球体偏移重新映射该间隔,但在循环重置期间,“结束”点不会被映射。
【讨论】:
以上是关于为啥我的动画圈子的位置会闪烁?的主要内容,如果未能解决你的问题,请参考以下文章