Skip to content

悬停效果改为在 JFXRippler 中实现#5757

Open
CiiLu wants to merge 4 commits intoHMCL-dev:mainfrom
CiiLu:bg
Open

悬停效果改为在 JFXRippler 中实现#5757
CiiLu wants to merge 4 commits intoHMCL-dev:mainfrom
CiiLu:bg

Conversation

@CiiLu
Copy link
Copy Markdown
Contributor

@CiiLu CiiLu commented Mar 8, 2026

放在 JFXRippler 中实现 JFXButton 等 JFoenix 控件也能有悬停效果

@Glavo
Copy link
Copy Markdown
Member

Glavo commented Mar 8, 2026

感觉改之后很多地方没有足够的空间显示阴影,看着很奇怪。

@Glavo
Copy link
Copy Markdown
Member

Glavo commented Apr 6, 2026

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the hover animation logic by moving it from RipplerContainer to JFXRippler, introducing a hoverOverlay rectangle and implementing mouse event handlers for background interpolation. The review feedback recommends using Animation or Timeline instead of Transition to prevent visual jumps during rapid mouse movements and suggests simplifying the interpolateBackground method for better efficiency.

protected RippleGenerator rippler;
protected Pane ripplerPane;
protected Node control;
private Transition coverAnimation;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

建议将 coverAnimation 的类型从 Transition 改为 Animation。这样可以支持使用 Timeline 来实现更平滑的动画效果,因为 Timeline 能够更好地处理从当前状态开始的过渡。

Suggested change
private Transition coverAnimation;
private Animation coverAnimation;

Comment on lines +140 to +173
mouseEventHandler = event -> {
if (coverAnimation != null) {
coverAnimation.stop();
coverAnimation = null;
}

if (event.getEventType() == MouseEvent.MOUSE_ENTERED) {
coverAnimation = new Transition() {
{
setCycleDuration(Motion.SHORT4);
setInterpolator(Motion.EASE_IN);
}

@Override
protected void interpolate(double frac) {
interpolateBackground(frac);
}
};
} else {
coverAnimation = new Transition() {
{
setCycleDuration(Motion.SHORT4);
setInterpolator(Motion.EASE_OUT);
}

@Override
protected void interpolate(double frac) {
interpolateBackground(1 - frac);
}
};
}

coverAnimation.play();
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

目前的动画实现方式在鼠标快速移入移出时会产生明显的跳变。这是因为每次事件都会创建一个新的 Transition,并且动画总是从固定的起始值(0 或 1)开始,而没有考虑当前的透明度状态。建议改用 Timeline 并直接对 hoverOverlayopacityProperty 进行动画处理,这样 JavaFX 会自动从当前值开始平滑过渡,同时也能减少对象的频繁创建。

            mouseEventHandler = event -> {
                if (coverAnimation != null) {
                    coverAnimation.stop();
                }

                boolean isEntered = event.getEventType() == MouseEvent.MOUSE_ENTERED;
                Color onSurface = Themes.getColorScheme().getOnSurface();
                hoverOverlay.setFill(Color.color(onSurface.getRed(), onSurface.getGreen(), onSurface.getBlue(), 0.04));

                coverAnimation = new Timeline(new KeyFrame(Motion.SHORT4,
                    new KeyValue(hoverOverlay.opacityProperty(), isEntered ? 1 : 0, isEntered ? Motion.EASE_IN : Motion.EASE_OUT)));
                coverAnimation.play();
            };

Comment on lines +183 to 193
private void interpolateBackground(double frac) {
if (hoverOverlay == null) return;
if (frac < 0.01) {
hoverOverlay.setOpacity(0);
return;
}
Color onSurface = Themes.getColorScheme().getOnSurface();
Color fillColor = Color.color(onSurface.getRed(), onSurface.getGreen(), onSurface.getBlue(), frac * 0.04);
hoverOverlay.setFill(fillColor);
hoverOverlay.setOpacity(1);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

简化 interpolateBackground 方法。如果采用动画化 opacityProperty 的方案,此方法只需负责设置填充颜色和最终的透明度即可。这不仅使代码更简洁,也提高了渲染效率。

    private void interpolateBackground(double frac) {
        if (hoverOverlay == null) return;
        Color onSurface = Themes.getColorScheme().getOnSurface();
        hoverOverlay.setFill(Color.color(onSurface.getRed(), onSurface.getGreen(), onSurface.getBlue(), 0.04));
        hoverOverlay.setOpacity(frac);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants