首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在JavaFX中将反射应用于DropShadow效果

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

Stack Overflow用户
提问于 2016-08-04 23:04:30
回答 1查看 785关注 0票数 1

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

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

代码语言:javascript
复制
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代码行,如下所示:

代码语言:javascript
复制
reflect.setInput(shadow);
context.setEffect(reflect);

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

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

我如何重写这段代码才能达到预期的效果(如果可能的话,只使用效果组合)?

EN

回答 1

Stack Overflow用户

发布于 2016-08-05 03:23:05

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

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

代码语言:javascript
复制
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();
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38771027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档