相对于鼠标缩放在 JavaFX 中不起作用

Zooming relative to mouse doesnt work in JavaFX

我有一个工作代码,它在缩放时使用了 ParallelCamera,并且运行良好。 在这里:

double s = camera.getScaleX();
double d = e.getDeltaY();
double f = 1.2;

double x = e.getSceneX();
double y = e.getSceneY();

if (d < 0) {
    f = 2;
} else if (d > 0) {
    f = 0.5;
}

double ps = s;

/*if (s * f > 1) {
    camera.setScaleX(1);
    camera.setScaleY(1);
    camera.setScaleZ(1);
    camera.setTranslateX(0);
    camera.setTranslateY(0);
    return;
}

camera.setScaleX(s * f);
camera.setScaleY(s * f);
camera.setScaleZ(s * f);

s = camera.getScaleX();

double dx = ps * (1 - f) * x;
double dy = ps * (1 - f) * y;
                
System.out.println(dx);

double width = primaryScene.getWidth();
double height = primaryScene.getHeight();

if (camera.getTranslateX() + s * width + dx > width) {
    camera.setTranslateX(width - s * width);
} else if ((camera.getTranslateX() + dx < 0)) {
    camera.setTranslateX(0);
} else {
    camera.setTranslateX(camera.getTranslateX() + dx);
}

if (camera.getTranslateY() + s * height + dy > height) {
    camera.setTranslateY(height - s * height);
} else if ((camera.getTranslateY() + dy < 0)) {
    camera.setTranslateY(0);
} else {
    camera.setTranslateY(camera.getTranslateY() + dy);
}

但我不想有质量损失,所以我重写了它。 现在它缩放窗格,而不是相机。 我遵循完全相同的代码,只是这次缩放比例相反。 当我计算位置时,我首先设置一个偏移量来模仿我的原始代码。 (相机的枢轴点位于 0,0,但窗格位于中心) 质量损失消失了,但它并没有真正起作用:

double s = mapLayer.getScaleX();
double d = e.getDeltaY();
double f = 1.2;
                
double width = primaryScene.getWidth();
double height = primaryScene.getHeight();

double x = (e.getSceneX());
double y = (e.getSceneY());

if (d > 0) {
    f = 2;
} else{
    f = 0.5;
}

double ps = s;

mapLayer.setScaleX(s * f);
mapLayer.setScaleY(s * f);
mapLayer.setScaleZ(s * f);
                
            
s = mapLayer.getScaleX();

double dx = ps * (1 - f) * x;
double dy = ps * (1 - f) * y;

mapLayer.setTranslateX(mapLayer.getTranslateX()+ps*(width/2)*(f-1));
mapLayer.setTranslateY(mapLayer.getTranslateY()+ps*(height/2)*(f-1));
mapLayer.setTranslateX(mapLayer.getTranslateX()+dx);
mapLayer.setTranslateY(mapLayer.getTranslateY()+dy);

我找到了这个,它非常有效: 。现在的解决方案是这样的(没有夹紧):

double delta = 1.2;
double scale = mapLayer.getScaleX(); // currently we only use Y, same value is used for X
double oldScale = scale;
if (e.getDeltaY() < 0) {
    scale /= delta;
} else {
    scale *= delta;
}
double f = (scale / oldScale) - 1;
double dx = (e.getSceneX()
    - (mapLayer.getBoundsInParent().getWidth() / 2
    + mapLayer.getBoundsInParent().getMinX()));
double dy = (e.getSceneY()
    - (mapLayer.getBoundsInParent().getHeight() / 2
    + mapLayer.getBoundsInParent().getMinY()));

mapLayer.setScaleX(scale);
mapLayer.setScaleY(scale);
mapLayer.setScaleZ(scale);

mapLayer.setTranslateX(mapLayer.getTranslateX() - f * dx);
mapLayer.setTranslateY(mapLayer.getTranslateY() - f * dy);