gpt4 book ai didi

java - 在 JavaFX Canvas 上应用 DropShadow 作为单独的层

转载 作者:行者123 更新时间:2023-12-02 11:50:10 24 4
gpt4 key购买 nike

我正在制作一个绘画程序,但用户制作的绘图周围有一个 DropShadow 。当它们删除时,它也会删除 DropShadow。如果我尝试重新应用 DropShadow (使其围绕绘图的新边界),它会起作用,但它会使已应用的 DropShadow 的其余部分变暗,而我不这样做不想。

我能想到的解决方案有两个:

  1. 删除 DropShadow 效果并在每次删除时重新应用它。据我所知,使用 GraphicsContext.applyEffect()
  2. 时这是不可能的
  3. 在单独的 Canvas 上应用 DropShadow 并清除它并在每次删除时重新绘制。下面的代码实现了我对这个解决方案的尴尬尝试。

这是当前发生的情况的图片: enter image description here

这是我的代码

FXMLDocument.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>

<AnchorPane id="AnchorPane" prefHeight="399.0" prefWidth="465.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cartographerfx.FXMLDocumentController">
<children>
<Pane fx:id="canvasPane" layoutX="26.0" layoutY="20.0" prefHeight="362.0" prefWidth="417.0" style="-fx-border-style: solid;">
<children>
<Canvas fx:id="canvas" height="362.0" onMouseDragged="#CanvasMouseDragged" onMousePressed="#CanvasMouseDown" onMouseReleased="#CanvasMouseUp" width="417.0" />
</children>
</Pane>
</children>
</AnchorPane>

FXMLDocumentController.java

package cartographerfx;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;

/**
*
* @author Dan
*/
public class FXMLDocumentController implements Initializable {

@FXML
Canvas canvas;
Canvas shadowLayer;

@FXML
Pane canvasPane;

private GraphicsContext gc;
private GraphicsContext sgc;
private boolean isDragging;
private double lastX;
private double lastY;

@FXML
public void CanvasMouseDragged(MouseEvent event) {

if (isDragging) {
if (event.getButton() == MouseButton.PRIMARY) {

gc.setStroke(Color.BLUE);

gc.setLineWidth(10);
gc.strokeLine(lastX, lastY, event.getX(), event.getY());
} else if (event.getButton() == MouseButton.SECONDARY) {
gc.clearRect(event.getX(), event.getY(), 10, 10);
}

lastX = event.getX();
lastY = event.getY();
}


}

@FXML
public void CanvasMouseDown(MouseEvent event) {
isDragging = true;

lastX = event.getX();
lastY = event.getY();

if (event.getButton() == MouseButton.MIDDLE)
{
sgc = gc;
sgc.applyEffect(new DropShadow());

}
}

@FXML
public void CanvasMouseUp(MouseEvent event) {
isDragging = false;
}

@Override
public void initialize(URL url, ResourceBundle rb) {

gc = canvas.getGraphicsContext2D();
isDragging = false;

shadowLayer = new Canvas(canvas.getWidth(), canvas.getHeight());

sgc = shadowLayer.getGraphicsContext2D();
canvasPane.getChildren().add(shadowLayer);
shadowLayer.toBack();
}

}

CartographerFX.java

package cartographerfx;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
*
* @author Dan
*/
public class CartographerFX extends Application {

@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

Scene scene = new Scene(root);

stage.setScene(scene);
stage.show();
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}

}

最佳答案

我不明白为什么每个人似乎都在使用 Canvas ,而场景图更适合该任务。为什么不只使用普通的 Pane 和路径。然后,您可以将投影效果直接应用到路径。场景图的优点是您可以根据需要单独编辑每个元素,而 Canvas 从概念上来说基本上只是一个图像,一旦绘制就无法编辑。

关于java - 在 JavaFX Canvas 上应用 DropShadow 作为单独的层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47934981/

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