gpt4 book ai didi

java - 如何在JavaFX(逐像素) Canvas 中创建填充动画?

转载 作者:行者123 更新时间:2023-12-01 10:36:03 25 4
gpt4 key购买 nike

我正在努力完成我的学校项目“数字图像拓扑”。目标是编写一个具有矩形的应用程序,其中有一条线穿过它,并且应用程序需要填充该线下方的字段。它需要使用某种类型的像素邻域逐像素地填充它。

我设法编写了一些应用程序来填充该行下方的字段,但它在一秒钟内就填充了所有内容。我无法逐个像素地完成它。我尝试停止线程,但是您无法停止应用程序线程,也无法从应用程序以外的线程更新 UI。 Platform.runLater 或 Task 也不起作用。我希望每次添加新像素时 Canvas 都会刷新,因此我用这个动画展示了该算法的工作原理。

我希望我的解释足够了。您不必专注于我的项目,有人可以向我解释如何在 Canvas 中逐像素填充吗?

这是 Controller 的代码:

@FXML
private Canvas canvas;

@FXML
private ComboBox<String> optionsType;

@FXML
private Button drawBtn;

@FXML
private ComboBox<String> optionsNeighbourhood;

WritableImage wi;
PixelReader pr;
GraphicsContext gc;

(...)

public void drawLine() {
gc.strokeLine(0, 0, canvas.getWidth(), canvas.getHeight());
}

private void fillShape(Neighbourhood type, int startX, int startY) {

int width = (int) canvas.getWidth();
int height = (int) canvas.getHeight();

LinkedList<Point> list = new LinkedList<>();
list.addFirst(new Point(startX, startY));
while (!list.isEmpty()) {
Point point = list.removeLast();
int x = point.getX();
int y = point.getY();

if (x >= 0 && x < width && y >= 0 && y < height && isEmpty(x, y)) {
gc.fillRect(x, y, 1, 1);
gc.fill();
canvas.snapshot(null, wi);

list.addFirst(new Point(x + 1, y));
list.addFirst(new Point(x, y + 1));
list.addFirst(new Point(x, y - 1));
list.addFirst(new Point(x - 1, y));
if (type == Neighbourhood.SIX || type == Neighbourhood.EIGHT) {
if (isEmpty(x - 1, y) || isEmpty(x, y - 1)) {
list.add(new Point(x - 1, y - 1));
}

if (isEmpty(x + 1, y) || isEmpty(x, y + 1)) {
list.add(new Point(x + 1, y + 1));
}
}

if (type == Neighbourhood.EIGHT) {
if (isEmpty(x - 1, y) || isEmpty(x, y + 1)) {
list.add(new Point(x - 1, y + 1));
}

if (isEmpty(x + 1, y) || isEmpty(x, y + 1)) {
list.add(new Point(x + 1, y - 1));
}
}
}

}
}

private boolean isEmpty(int x, int y) {

if (x < 0 || x >= canvas.getWidth() || y < 0 || y >= canvas.getHeight()) {
return false;
}

if (!pr.getColor(x, y).toString().equals("0xffffffff")) {
return false;
}

return true;
}

}

现在我知道代码一开始可能看起来不太明显。该算法并不重要,因为它似乎确实有效,但主要问题是:如何让该字段逐像素填充(就像动画一样(是的,我也尝试过AnimationTimer)。

最佳答案

有多种方法,其中一种是使用这样的 AnimationTimer:

import java.util.Random;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class Main extends Application {

private static double SCENE_WIDTH = 800;
private static double SCENE_HEIGHT = 600;

static Random random = new Random();

Canvas canvas;
GraphicsContext graphicsContext;

AnimationTimer loop;

Scene scene;

@Override
public void start(Stage primaryStage) {

BorderPane root = new BorderPane();

canvas = new Canvas(SCENE_WIDTH, SCENE_HEIGHT);

graphicsContext = canvas.getGraphicsContext2D();

Pane layerPane = new Pane();

layerPane.getChildren().addAll(canvas);

root.setCenter(layerPane);

scene = new Scene(root, SCENE_WIDTH, SCENE_HEIGHT);

primaryStage.setScene(scene);
primaryStage.show();

startAnimation();

}

private void startAnimation() {

loop = new AnimationTimer() {

double startX = 100;
double endX = 200;
double y = 100;
double x = startX;
double speed = 0.2;

@Override
public void handle(long now) {

graphicsContext.fillOval(x, y, 5,5);

x+=speed;

if( x >= endX) {
loop.stop();
}
}
};

loop.start();

}

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

关于java - 如何在JavaFX(逐像素) Canvas 中创建填充动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34720911/

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