gpt4 book ai didi

java - 在 JavaFX 中将反射应用于 DropShadow 效果

转载 作者:行者123 更新时间:2023-11-30 07:13:42 24 4
gpt4 key购买 nike

使用 JavaFX,我尝试将文本绘制到 Canvas 上,并将投影和反射效果链接在一起。

以下代码将显示反射的红色文本,然后将投影应用于原始文本和反射文本。

Canvas canvas = new Canvas(400,400);
GraphicsContext context = canvas.getGraphicsContext2D();
context.setFont( new Font("Arial Bold", 48) );
context.setFill(Color.RED);
DropShadow shadow = new DropShadow(6, 2, 2, Color.BLACK);
Reflection reflect = new Reflection(10, 1.0, 1.0, 0.0);
shadow.setInput(reflect);
context.setEffect(shadow);
context.fillText("Hello, world!", 100,100);

但是,投影在反射中出现“向后”,因为需要首先应用阴影才能获得逼真的效果。我尝试通过颠倒应用效果的顺序来实现此目的,方法是更改​​上面的 setInputsetEffect 代码行,如下所示:

reflect.setInput(shadow);
context.setEffect(reflect);

但是,结果是只应用了反射;我根本看不到任何阴影。

为什么没有应用阴影/不可见?

如何重写此代码以达到所需的效果(如果可能,仅使用效果组合)?

最佳答案

我不知道你所说的是否可以通过使用带有标准API的GraphicsContext来实现,所以欢迎其他答案。但是,这可能是一个临时解决方法,前提是它确实是您所需要的。首先应用阴影,然后逐像素复制图像以模仿反射效果。请参阅下面的屏幕截图:(原始 - 左侧,新 - 右侧)。

Reflection

下面附有完整的工作示例。它需要一些调整才能获得通用解决方案,但应该有足够的开始。

import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Effect;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class FXApp extends Application {

private Parent createContent() {
Canvas canvas = new Canvas(400,400);

Font font = new Font("Arial Bold", 48);
Color fill = Color.RED;
DropShadow shadow = new DropShadow(6, 2, 2, Color.BLACK);

fillTextWithReflection(canvas.getGraphicsContext2D(), "Hello, world!", 100, 100, font, fill, shadow);

return new Pane(canvas);
}

private void fillTextWithReflection(GraphicsContext g, String text, double textX, double textY, Font font, Color fill, Effect effect) {
Text t = new Text(text);
t.setFont(font);

// 5 px margin
Canvas tmpCanvas = new Canvas(t.getLayoutBounds().getWidth() + 5, t.getLayoutBounds().getHeight() + 5);

// set configuration
GraphicsContext tmpContext = tmpCanvas.getGraphicsContext2D();
tmpContext.setFont(font);
tmpContext.setFill(fill);
tmpContext.setEffect(effect);

// draw on temporary context
tmpContext.fillText(text, 0, font.getSize());

// take a snapshot of the text
WritableImage snapshot = tmpCanvas.snapshot(null, null);

int w = (int)snapshot.getWidth();
int h = (int)snapshot.getHeight();

WritableImage reflected = new WritableImage(w, h);

// make an 'inverted' copy
for (int y = 0; y < h; y++) {
// imitate fading out of reflection
double alpha = y / (h - 1.0);

for (int x = 0; x < w; x++) {
Color oldColor = snapshot.getPixelReader().getColor(x, y);
Color newColor = Color.color(oldColor.getRed(), oldColor.getGreen(), oldColor.getBlue(), alpha);

reflected.getPixelWriter().setColor(x, h - 1 - y, newColor);
}
}

// draw on the actual context
// images are drawn from x, y top-left but text is filled from x, y + h
// hence corrections
// this can be replaced with actual fillText() call if required
g.drawImage(snapshot, textX, textY - font.getSize());
g.drawImage(reflected, textX, textY + h - font.getSize());
}

@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.show();
}
}

关于java - 在 JavaFX 中将反射应用于 DropShadow 效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38771027/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com