使用JavaFX,我试图将文本绘制到画布上,并将投影和反射效果链接在一起。
下面的代码将显示反射的红色文本,然后将投影应用于原始文本和反射文本。
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);但是,投影在反射中显示为“向后”,因为需要首先应用阴影才能获得逼真的效果。我试图通过颠倒应用效果的顺序来实现这一点,方法是更改上面的setInput和setEffect代码行,如下所示:
reflect.setInput(shadow);
context.setEffect(reflect);然而,结果是只应用了反射;我根本看不到任何投影。
为什么投射阴影没有被应用/不可见?
我如何重写这段代码才能达到预期的效果(如果可能的话,只使用效果组合)?
发布于 2016-08-05 03:23:05
我不知道你所说的是否可以通过使用标准接口的GraphicsContext来实现,所以欢迎其他答案。但是,这可能是一种临时的解决方法,前提是它确实是您所需要的。首先应用阴影,然后逐个像素复制图像以模拟反射效果。请看下面的截图:(原来的-在左边,新的-在右边)。

完整的工作示例附在下面。它需要一些调整,以获得一个通用的解决方案,但应该有足够的开始。
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();
}
}https://stackoverflow.com/questions/38771027
复制相似问题