Переместить часть холста с помощью Snapshot JavaFx - PullRequest
0 голосов
/ 20 марта 2019

Я пишу функцию, которая позволяет перемещать выбранную часть холста в другую точку, это часть проекта, которая заключается в разработке такой программы, как рисование.

Это класс, который должен разрешать движущуюся функцию

public class TraslationTool {

private Canvas canvas;
private GraphicsContext gc;
private List<Canvas> list;
private double x1;
private double y1;
private double x2;
private double y2;

public TraslationTool(List<Canvas> list, double x1, double y1, double x2, double y2) {
    canvas = list.get(list.size() - 1);
    gc = canvas.getGraphicsContext2D();
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    this.list = list;
}

public void traslate(double posX, double posY) {
    if (posX > 0 && posY > 0 && checkSelection()) {

        int width = (int) x2 - (int) x1;
        int height = (int) y2 - (int) y1;
        Rectangle2D bound = new Rectangle2D(x1, y1, width, height);

        SnapshotParameters params = new SnapshotParameters();
        params.setViewport(bound);
        params.setFill(Color.TRANSPARENT);
        WritableImage write = new WritableImage(width, height);
        Image image = canvas.snapshot(params, write);

        gc.clearRect(x1, y1, width, height);
        gc.drawImage(image, posX, posY);
    }
}

private boolean checkSelection() {
    if(this.x1 == 0 || this.y1 == 0 || this.x2 == 0 || this.y2 == 0) {
        return false;
    }
    if (this.x1 > this.x2) {
        double tempX = this.x1;
        this.x1 = this.x2;
        this.x2 = tempX;
    }
    if (this.y1 > this.y2) {
        double tempY = this.y1;
        this.y1 = this.y2;
        this.y2 = tempY;
    }
    return true;
} }

Это часть контроллера, которая обрабатывает холст

drawingCanvas.setOnMousePressed(event -> {
        Canvas c = new Canvas(drawingCanvasWidth, drawingCanvasHeight);
        c.setOnMousePressed(drawingCanvas.getOnMousePressed());
        c.setOnMouseDragged(drawingCanvas.getOnMouseDragged());
        c.setOnMouseReleased(drawingCanvas.getOnMouseReleased());
        c.setOnMouseMoved(drawingCanvas.getOnMouseMoved());
        c.setOnMouseExited(drawingCanvas.getOnMouseExited());

        try {
            if (list.contains(list.get(++counter))) {
                for (int i = list.size() - 1; i >= counter; i--) {
                    list.remove(i);
                }
            }
        } catch (IndexOutOfBoundsException e) {

        }

        list.add(c);
        anchorPane.getChildren().add(c);
        gc = c.getGraphicsContext2D();
        gc.setLineWidth(size);

        x1 = event.getX();
        y1 = event.getY();

        if (event.getButton() == MouseButton.PRIMARY) {
            gc.setStroke(primaryColor);
            shapeDrawer.setCanvas(c, primaryColor);
        } else if (event.getButton() == MouseButton.SECONDARY) {
            gc.setStroke(secondaryColor);
            shapeDrawer.setCanvas(c, secondaryColor);
        }

        Color wantedColor = (Color) gc.getStroke();

        if (toolIsPressed) {
            if (toolPressed == hboxRubber) {
                gc.setStroke(Color.WHITE);
            } else if (toolPressed == hboxPencil) {
                gc.setLineWidth(0.25 * size);
            } else if (toolPressed == hboxDropper) {
                DropperTool dropperTool = new DropperTool(list, (int) event.getX(), (int) event.getY());
                Color tempColor = dropperTool.getColor();
                shapeDrawer.setCanvas(c, tempColor);
                if (event.getButton() == MouseButton.PRIMARY) {
                    shapeDrawer.setCanvas(c, primaryColor);
                    primaryColor = tempColor;
                    defColor1.setStyle("-fx-border-color: gray; -fx-background-color: " + hexToRgb(tempColor));
                } else if (event.getButton() == MouseButton.SECONDARY) {
                    shapeDrawer.setCanvas(c, secondaryColor);
                    secondaryColor = tempColor;
                    defColor2.setStyle("-fx-border-color: gray; -fx-background-color: " + hexToRgb(tempColor));
                }
                gc.setStroke(tempColor);
            } else if (toolPressed == hboxPolygon) {
                if (!polygonIsFirst) {
                    x1 = x2;
                    y1 = y2;
                } else {
                    polyX = x1;
                    polyY = y1;
                }
            } else if (toolPressed == hboxBucket) {
                BucketTool bucketTool = new BucketTool(list, (int) event.getX(), (int) event.getY(), wantedColor);
                bucketTool.paint();
            }
        }

        gc.beginPath();
        gc.moveTo(x1, y1);
        changesMade = true;
    });

    //Logic for show/unshow the Drawing Grid 
    hboxGrid.setOnMousePressed(event -> {
        if (gridIsPressed) {
            gridIsPressed = false;
            grid.setGridLinesVisible(gridIsPressed);
        } else {
            gridIsPressed = true;
            grid.setGridLinesVisible(gridIsPressed);
        }
    });


    /*
     Handle shapes.
     */
    drawingCanvas.setOnMouseReleased(event -> {
        x2 = event.getX();
        y2 = event.getY();

        if (x1 == x2 && y1 == y2 && toolIsPressed) {
            return;
        }

        changesMade = true;

        double width = x2 - x1;
        double height = y2 - y1;

        if (toolPressed == hboxLine) {
            shapeDrawer.drawLine(x2, y2);
        } else if (toolPressed == hboxRectangle) {
            shapeDrawer.drawRectangle(x1, y1, width, height);
        } else if (toolPressed == hboxOval) {
            shapeDrawer.drawOval(x1, y1, width, height);
        } else if (toolPressed == hboxCircle) {
            shapeDrawer.drawCircle(x1, y1, width, height);
        } else if (toolPressed == hboxSquare) {
            shapeDrawer.drawSquare(x1, y1, width, height);
        } else if (toolPressed == hboxTriangle) {
            shapeDrawer.drawTriangle(x1, y1, x2, y2, width);
        } else if (toolPressed == hboxRoundRectangle) {
            shapeDrawer.drawRoundRectangle(x1, y1, width, height);
        } else if (toolPressed == hboxPolygon) {
            if (polygonIsFirst) {
                polygonIsFirst = false;
            }
            if (x2 >= polyX - 10 && x2 <= polyX + 10 && y2 <= polyY + 10 && y2 >= polyY - 10) {
                gc.lineTo(polyX, polyY);
                gc.stroke();
                polygonIsFirst = true;
                return;
            }
            gc.lineTo(x2, y2);
            gc.stroke();
        } else if (toolPressed == hboxMove) {
            TraslationTool move = new TraslationTool(list, x1, y1, x2, y2);
            move.traslate(50, 50);
        }
    });
}

Я использую многоуровневую систему холстов, чтобы разрешить функцию отмены / повтора. Чтобы разрешить функцию перемещения, я делаю снимок требуемой части Canvas, а затем записываю этот снимок в желаемых координатах. Проблема в том, что когда я выполняю код, вызов в классе TraslationTool создает только новый слой Canvas и не выполняет функцию перемещения. Моя идея состоит в том, что что-то идет не так при создании нового слоя, но я не могу понять, что это такое. Извините за длинный пост, и спасибо заранее.

1 Ответ

0 голосов
/ 25 марта 2019

Я решил свою проблему с изменением подхода. Проблема с движущейся частью холста была связана с реализацией функции Undo / Redo (многоуровневая система холстов создает проблему с рендерингом WritableImage). Я изменил реализацию функции Undo / Redo, используя This Solution , таким образом работает Class TraslationTool.

Это код, который я использую для перевода части холста:

public class MovingTool implements DrawOperation {

private final Canvas canvas;
private double x1;
private double y1;
private double x2;
private double y2;
private final double posX;
private final double posY;

public MovingTool(Canvas canvas, double x1, double y1, double x2, double y2, double posX, double posY) {
    this.canvas = canvas;
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    this.posX = posX;
    this.posY = posY;
}

@Override
public void draw(GraphicsContext gc) {
    if ((posX >= 0) && (posY >= 0)) {

        checkSelection();

        int width = (int) x2 - (int) x1;
        int height = (int) y2 - (int) y1;
        Rectangle2D bound = new Rectangle2D(x1, y1, width, height);

        SnapshotParameters params = new SnapshotParameters();
        params.setViewport(bound);
        params.setFill(Color.TRANSPARENT);
        WritableImage write = new WritableImage(width, height);
        Image image = canvas.snapshot(params, write);

        gc.clearRect(x1, y1, width, height);
        gc.drawImage(image, x1, y1);
    }
}

private void checkSelection() {
    if (this.x1 > this.x2) {
        double tempX = this.x1;
        this.x1 = this.x2;
        this.x2 = tempX;
    }
    if (this.y1 > this.y2) {
        double tempY = this.y1;
        this.y1 = this.y2;
        this.y2 = tempY;
    }
}}
...