跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

数值动画

这三个动画器随时间对一个数值进行插值。它们不绘制任何内容:在 onUpdate 中你读取 getValue() 并将其应用到需要的地方(alpha、位置、颜色…)。由于渲染是按需的,请在回调中调用 Component.repaint()。

对比

类 取值范围 曲线 是否重复? 用途
AlphaAnimation [0,1] 三次 ease-in-out 否(有 onComplete) 淡入淡出、不透明度、高亮
PositionAnimation 自由 线性 否(有 onComplete) 按像素移动、滑动
LoopAnimation [0,1] 线性或缓动 是,无限循环 脉动、光晕、加载

完整示例(复制、粘贴并运行)

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.animation.*;   // AlphaAnimation, PositionAnimation, LoopAnimation
import dev.crossfly.util.*;           // Debug

/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // AlphaAnimation — 标签淡入(0.3 秒内 0→1)
      Label card = new Label("Olá");
      add(LAY_AUTO, card);
      AlphaAnimation fade = new AlphaAnimation(0f, 1f, 0.3f);
      fade.onUpdate(() -> { card.alpha(fade.getValue()); Component.repaint(); })
          .onComplete(() -> Debug.log("fade concluído"))
          .start();

      // PositionAnimation — 面板从右侧滑入(以像素计,自由)
      Label painel = new Label("Painel");
      add(LAY_AUTO, painel);
      int y0 = painel.y, w = painel.width, h = painel.height;
      PositionAnimation slide = new PositionAnimation(Screen.width, 0, 0.4f);
      slide.onUpdate(() -> { painel.setBounds((int) slide.getValue(), y0, w, h); Component.repaint(); })
           .start();

      // LoopAnimation — 持续的不透明度脉动(1 秒周期,平滑,无限)
      Label ponto = new Label("●");
      add(LAY_AUTO, ponto);
      LoopAnimation pulse = new LoopAnimation(1.0f, 60f, true);
      pulse.onUpdate(() -> { ponto.alpha(0.4f + 0.6f * pulse.getValue()); Component.repaint(); })
           .start();
   }
}

下面的片段只展示了核心部分(放入 onShow() 内部的内容)。要运行它们,请将其放入上面的 MainWindow 骨架中。

AlphaAnimation — 淡入

Label card = new Label("Olá");
AlphaAnimation fade = new AlphaAnimation(0f, 1f, 0.3f);   // 0.3 秒内 0→1
fade.onUpdate(() -> { card.alpha(fade.getValue()); Component.repaint(); })
    .onComplete(() -> Debug.log("fade concluído"))
    .start();

构造函数:AlphaAnimation(start, end, duration)(60 FPS)或 (start, end, duration, fps)。

PositionAnimation — 滑动一个面板(按像素)

int y0 = painel.y, w = painel.width, h = painel.height;
PositionAnimation slide = new PositionAnimation(Screen.width, 0, 0.4f);  // 从右侧进入
slide.onUpdate(() -> { painel.setBounds((int) slide.getValue(), y0, w, h); Component.repaint(); })
     .start();

它不限于 [0,1],且是线性的 — 非常适合坐标。

LoopAnimation — 持续脉动

LoopAnimation pulse = new LoopAnimation(1.0f, 60f, true);   // 1 秒周期,60 FPS,平滑
pulse.onUpdate(() -> { float v = 0.4f + 0.6f * pulse.getValue(); ponto.alpha(v); Component.repaint(); })
     .start();
// pulse.stop();   // 离开屏幕时停止

构造函数:LoopAnimation(duration)(线性,60 FPS)或 (duration, fps, easeInOut)。它没有 onComplete(会一直运行直到 stop())。

通用控制

start() · stop()(在 Alpha/Position 上触发 onComplete)· cancel()(不触发)· isRunning() · getValue()。

最佳实践

  • 始终在 onUpdate 中调用 Component.repaint() — 渲染是按需的。
  • 停止循环(stop()),在离开界面时(在 onRemove() 中),否则 Timer 会继续运行。
  • 将动画保存到变量/字段中,以便之后能够 stop()/cancel()。

常见错误

  • 使用 PositionAnimation 却期望取值范围为 [0,1] — 它是自由的;进行钳制的是 AlphaAnimation。
  • 忘记 repaint() 而导致“动画不显示”。
  • 调用 setAlpha(...)(来自旧的 Javadoc)— 真正的方法是 alpha(float)。

另请参阅

这个页面有帮助吗?