gpt4 book ai didi

JavaFX Canvas -绘图

转载 作者:行者123 更新时间:2023-12-01 14:17:39 26 4
gpt4 key购买 nike

我目前正在使用 Canvas 处理 JavaFX-Drawing-Application。在 GraphicsContext 的帮助下,我使用 beginPath() 和 lineTo() 方法绘制线条,但我无法找到实现橡皮擦的正确方法。

现在我只是使用 clearRect() 方法,但是当像在图像中一样快速拖动鼠标时,这会导致问题。
黑色 = 绘图和白色 = 橡皮擦
Preview

看看我的实现:)

package GUI;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Main extends Application {

private final int mouseOffset = 60;

private Stage window;
private Canvas canvas;
private GraphicsContext gc;

@Override
public void start(Stage primaryStage) {
window = primaryStage;
window.setTitle("Drawing Board ~ by Michael Holley");
window.setX(100);
window.setY(100);
window.setResizable(false);
window.setOnCloseRequest(e -> {
Platform.exit();
System.exit(0);
});
BorderPane layout = new BorderPane();

/* OPTION PANE */
HBox optionPane = new HBox();
optionPane.setPrefHeight(60);
optionPane.setSpacing(10);
optionPane.setPadding(new Insets(10, 10, 10, 10));
optionPane.setAlignment(Pos.CENTER);
ColorPicker colorSelection = new ColorPicker();
colorSelection.setValue(Color.CORNFLOWERBLUE);
colorSelection.setOnAction(actionEvent -> {
gc.setFill(colorSelection.getValue());
gc.setStroke(colorSelection.getValue());
});
optionPane.getChildren().add(colorSelection);

Slider sizeSlider = new Slider();
sizeSlider.setMin(1);
sizeSlider.setMax(50);
sizeSlider.setValue(18);
optionPane.getChildren().add(sizeSlider);

TextField sizeSliderTF = new TextField();
sizeSliderTF.setEditable(false);
sizeSliderTF.setText(String.format("%.0f", sizeSlider.getValue()));
sizeSliderTF.setPrefWidth(30);
sizeSliderTF.setAlignment(Pos.CENTER);
sizeSlider.valueProperty().addListener((observableValue, oldNumber, newNumber) -> {
sizeSlider.setValue(newNumber.intValue());
sizeSliderTF.setText(String.format("%.0f", sizeSlider.getValue()));
gc.setLineWidth(sizeSlider.getValue());
});
optionPane.getChildren().add(sizeSliderTF);

Separator optionPaneSeparator_1 = new Separator();
optionPaneSeparator_1.setOrientation(Orientation.VERTICAL);
optionPane.getChildren().add(optionPaneSeparator_1);

final ToggleGroup group = new ToggleGroup();
RadioButton drawButton = new RadioButton("Draw");
drawButton.setToggleGroup(group);
drawButton.setSelected(true);
RadioButton eraseButton = new RadioButton("Erase");
eraseButton.setToggleGroup(group);
optionPane.getChildren().addAll(drawButton, eraseButton);

Separator optionPaneSeparator_2 = new Separator();
optionPaneSeparator_2.setOrientation(Orientation.VERTICAL);
optionPane.getChildren().add(optionPaneSeparator_2);

Button clearButton = new Button("Clear");
clearButton.setOnAction(actionEvent -> gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()));
optionPane.getChildren().add(clearButton);

Button fillButton = new Button("Fill");
fillButton.setOnAction(actionEvent -> gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()));
optionPane.getChildren().add(fillButton);
layout.setTop(optionPane);


/* CANVAS */
canvas = new Canvas(800, 740);
gc = canvas.getGraphicsContext2D();
gc.setStroke(colorSelection.getValue());
gc.setFill(colorSelection.getValue());
gc.setLineWidth(sizeSlider.getValue());

canvas.setOnMousePressed(mouseEvent -> {
if (drawButton.isSelected() && !eraseButton.isSelected()) {
gc.beginPath();
gc.lineTo(mouseEvent.getSceneX(), mouseEvent.getSceneY() - mouseOffset);
gc.stroke();
} else if (!drawButton.isSelected() && eraseButton.isSelected()) {
double currentSize = sizeSlider.getValue();
gc.clearRect(mouseEvent.getSceneX() - currentSize / 2, mouseEvent.getSceneY() - currentSize / 2 - mouseOffset, currentSize, currentSize);
}
});

canvas.setOnMouseDragged(mouseEvent -> {
if (drawButton.isSelected() && !eraseButton.isSelected()) {
gc.lineTo(mouseEvent.getSceneX(), mouseEvent.getSceneY() - mouseOffset);
gc.stroke();
} else if (!drawButton.isSelected() && eraseButton.isSelected()) {
double currentSize = sizeSlider.getValue();
gc.clearRect(mouseEvent.getSceneX() - currentSize / 2, mouseEvent.getSceneY() - currentSize / 2 - mouseOffset, currentSize, currentSize);
}
});

layout.setCenter(canvas);


Scene scene = new Scene(layout, 800, 800);
scene.getStylesheets().add("GUI/OptionsStyling.css");
window.setScene(scene);
window.show();
}


public static void main(String[] args) {
launch(args);
}
}



附加评论:
是的,我已经想过只用底色/底色在它上面作画,但这不是我想要的 的目标。橡皮擦 .

最佳答案

这是一个棘手的问题。除了 clearRect 方法外,似乎没有其他方法可以清除图形。 (即使我尝试过的一些混合模式和基于剪辑的技巧也不起作用。)

如果您先临时旋转图形上下文,则可以使用 clearRect 绘制每个线段:

import javafx.geometry.Point2D;
import javafx.scene.transform.Affine;
import javafx.scene.transform.Rotate;

// ...

private Point2D lastErasePoint;

// ...

canvas.setOnMousePressed(mouseEvent -> {
if (drawButton.isSelected() && !eraseButton.isSelected()) {
gc.beginPath();
gc.lineTo(mouseEvent.getSceneX(), mouseEvent.getSceneY() - mouseOffset);
gc.stroke();
} else if (!drawButton.isSelected() && eraseButton.isSelected()) {
lastErasePoint = new Point2D(
mouseEvent.getSceneX(), mouseEvent.getSceneY() - mouseOffset);
}
});

canvas.setOnMouseDragged(mouseEvent -> {
if (drawButton.isSelected() && !eraseButton.isSelected()) {
gc.lineTo(mouseEvent.getSceneX(), mouseEvent.getSceneY() - mouseOffset);
gc.stroke();
} else if (!drawButton.isSelected() && eraseButton.isSelected()) {
Point2D location = new Point2D(
mouseEvent.getSceneX(), mouseEvent.getSceneY() - mouseOffset);

Point2D diff = location.subtract(lastErasePoint);
double angle = Math.toDegrees(
Math.atan2(diff.getY(), diff.getX()));
double width = gc.getLineWidth();

gc.save();
gc.setTransform(new Affine(new Rotate(
angle, lastErasePoint.getX(), lastErasePoint.getY())));
gc.clearRect(
lastErasePoint.getX() - width / 2,
lastErasePoint.getY() - width / 2,
lastErasePoint.distance(location) + width, width);
gc.restore();

lastErasePoint = location;
}
});

关于JavaFX Canvas -绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60096821/

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