Есть такой код для canvas, что бы при прокрутке колесиком мышки, можно было увеличивать или уменьшать содержание canvas. Но есть одно но, при увеличении оно просто увеличивает сам Сanvas выходя за пределы допустимого окна, налаживаясь на другие части интерфейса. Как можно это решить? или каким образом сделать адекватный зум?
myCanvas.setOnScroll((event) ->
double x = myCanvas.getScaleX();
double y = myCanvas.getScaleY();
if (x <= 0.8 && y <= 0.8) {
x = 0.8;
y = 0.8;
}
if (x >= 2 && y >= 2) {
x = 2;
y = 2;
}
myCanvas.setScaleX(x + event.getDeltaY() / 800);
myCanvas.setScaleY(y + event.getDeltaY() / 800);
});
В вашем случае масштабирование следует применять не на объект класса Сanvas
, а на изображение, которое рисуется на графическом контексте (GraphicContext
).
Можно либо изменять все координаты, используемые при рисовании, либо перед рисованием установить преобразование масштабирования с помощью метода setTransform()
(установка свойства transform
графического контекста).
Используя второй метод, оформил это в виде наследника класса Canvas
и получил такой черновой вариант:
// ZoomableCanvas.java:
package example;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.EventHandler;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.ScrollEvent;
import javafx.scene.transform.Affine;
public abstract class ZoomableCanvas extends Canvas {
public ZoomableCanvas() {
this(0, 0);
}
public ZoomableCanvas(double width, double height) {
super(width, height);
this.setOnScroll(zoomHandler);
this.zoomProperty().addListener(o -> redraw());
}
static protected EventHandler<ScrollEvent> zoomHandler = new EventHandler<ScrollEvent>() {
@Override
public void handle(ScrollEvent event) {
ZoomableCanvas zcanvas = (ZoomableCanvas) event.getSource();
GraphicsContext gc = zcanvas.getGraphicsContext2D();
Affine affine = gc.getTransform();
double zoom = affine.getMxx() + event.getDeltaY() / 800;
if (zoom <= 0.8) {
zoom = 0.8;
}
if (zoom >= 2.0) {
zoom = 2.0;
}
zcanvas.setZoom(zoom);
zcanvas.redraw();
}
};
private SimpleDoubleProperty zoom = new SimpleDoubleProperty(1.0);
public void setZoom(double value) {
if (value != getZoom()) {
this.zoom.set(value);
redraw();
}
}
public double getZoom() {
return zoom.get();
}
public DoubleProperty zoomProperty() {
return zoom;
}
public void clean() {
GraphicsContext gc = this.getGraphicsContext2D();
Canvas canvas = gc.getCanvas();
Affine affine = gc.getTransform();
gc.setTransform(1, 0, 0, 1, 0, 0);
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
gc.setTransform(affine);
}
public void redraw() {
GraphicsContext gc = this.getGraphicsContext2D();
if (gc == null) return;
// Чистим:
Canvas canvas = gc.getCanvas();
double w = canvas.getWidth();
double h = canvas.getHeight();
gc.setTransform(1, 0, 0, 1, 0, 0);
gc.clearRect(0, 0, w, h);
double z = getZoom();
// Масштабирование в левый верхний угол:
//gc.setTransform(z, 0, 0, z, 0, 0);
// Масштабирование в центр canvas:
gc.setTransform(z, 0, 0, z, (w - w * z) / 2.0, (h - h * z) / 2.0);
// Рисуем:
paint(gc);
}
public abstract void paint(GraphicsContext gc);
}
// Main.java:
package example;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
ZoomableCanvas canvas = new ZoomableCanvas(300, 200) {
@Override
public void paint(GraphicsContext gc) {
// Рисуем:
gc.setFill(Color.LIGHTGREEN);
gc.fillOval(60, 10, 180, 180);
gc.setFill(Color.WHITE);
gc.fillOval(100, 50, 100, 100);
}
};
Label zoomLabel = new Label();
zoomLabel.textProperty().bind(canvas.zoomProperty().asString());
Slider slider = new Slider(0.8, 2.0, 1.0);
slider.valueProperty().bindBidirectional(canvas.zoomProperty());
VBox root = new VBox(zoomLabel, canvas, slider);
root.setPadding(new Insets(15));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
canvas.redraw();
}
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Решаю задачу парсинга вакансий с сайта HeadeHunter при помощи jsoup и пытаюсь парсить дату, но получаю ошибку:
Нужно получить значение 3 в результате выполнения следующего кода: Systemout
Доброго времени суток!Я установил андроид студио и ява,но установить сдк не получается точнее интегрировать его в андроид сдкЯ нажимаю установить,он...