1

我正在对一个Canvas对象执行以下操作。

graphics.setColor(BLUE);
graphics.fill(new Rectangle2D.Double(x, y, width, height));

我想淡入填充颜色以创建从画布背景颜色到新颜色的平滑过渡(并且可能淡出原来存在的任何颜色)。

我玩过这种东西(将图形对象的合成设置为 AlphaComposite,每 n 毫秒Timer更新alpha一次值),但我得到了闪烁。

我想知道我缺少什么一般概念。

感谢您的任何指示。

4

2 回答 2

1

首先,您如何使用 AWT?它已经过时了。我建议你切换到swing,主要是因为swing有双重缓冲,可以消除你的闪烁。

于 2013-07-30T08:08:02.407 回答
0

您的应用程序完全按照您的要求执行。如果要制作淡入效果,则必须确定要进行哪种颜色更改,创建一个执行此操作的函数,并实现淡入淡出本身。

我会这样处理它:

class FadeEffect{

  int totalDurationMs;

  int elapsedDurationMs;

  Color initialColor;

  Color finalColor;

  Color getColor(int durationDelta) {
    elapsedDurationMs += durationDelta;
    if (elapsedDurationMs > totalDurationMs) {
      return finalColor;
    }
    double progress = 1.0d*elapsedDurationMs/totalDurationMs;
    return new Color( (int)(finalColor.getRed()-initialColor.getRed())*progress,
                      (int)(finalColor.getGreen()-initialColor.getGreen())*progress,
                      (int)(finalColor.getBlue()-initialColor.getBlue())*progress);
  }

  //getters, setters, etc
}

至于闪烁问题:确保您使用双缓冲 - 无论是在您的组件中,还是通过在屏幕外缓冲区(图像)上手动绘制,并且仅在绘制完成后才将图像发布到屏幕上。

这是我的 Graphic2D 应用程序中执行双缓冲的示例代码:

private VolatileImage vImg;

@Override
public void paint(Graphics g) {
    if (gc==null) gc = this.getGraphicsConfiguration();
    do {
        boolean sizeChanged = false;
        sizeChanged = (vImg!=null&&(vImg.getWidth()!=getWidth()|| vImg.getHeight()!=getHeight()));
        if (vImg == null || vImg.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE
                || sizeChanged) {
            vImg = gc.createCompatibleVolatileImage(getWidth(), getHeight());
            vImg.setAccelerationPriority(1);
        }
        final Graphics gimg =  vImg.getGraphics();
        if (gimg instanceof Graphics2D) {
            renderContents((Graphics2D) gimg);
            gimg.dispose();
            g.drawImage(vImg, 0, 0, null);
        } else {
            throw new UnsupportedOperationException("Rendering impossible, graphics are not of Graphics2D class");
        }
    } while (vImg.contentsLost());
    updateAnimationNo();
}
于 2013-07-30T08:20:19.300 回答