doubleaxe / daxfb-calculator

Calculator/Factory Planner for factory management games. Evospace. Captain of Industry.
https://doubleaxe.github.io/daxfb-calculator/
MIT License
3 stars 4 forks source link

Small suggestion: Use mouse location as center of zoom #12

Open marvk opened 6 months ago

marvk commented 6 months ago

Hi, great Project! Zooming the canvas in and out with the mouse wheel would feel a lot more natural, if the center of the zoom were the location of the mouse pointer. It's been a few years, but I've already implemented such a zoom in a project of mine. If you want to take a look it's linked below.

https://github.com/marvk/vatprism/blob/6dcdf04ba1f8c6fe67c5b2590ba4162009bde5f2/src/main/java/net/marvk/fs/vatsim/map/view/map/MapView.java#L317-L336

private void zoomMap(final double d) {
    final double fScroll = Math.pow(viewModel.getScrollSpeed(), 1. / 4);
    final boolean scrollingIn = d > 0;
    final double delta = scrollingIn ? fScroll : 1.0 / fScroll;

    final double oldScale = viewModel.scaleProperty().get();
    final double newScale = Math.min(Math.max(oldScale * delta, MIN_SCALE), MAX_SCALE);

    if (Double.compare(oldScale, newScale) == 0) {
        return;
    }

    viewModel.scaleProperty().set(newScale);
    final Point2D worldCenter = viewModel.getWorldCenter();
    final Point2D mouseWorldPosition = viewModel.getMouseWorldPosition().multiply(-1);

    final double f = oldScale / newScale;

    viewModel.setWorldCenter(mouseWorldPosition.multiply(1 - f).add(worldCenter.multiply(f)));
}

P.S. I tried running the project locally to try and get a PR going, but I ran into some issues which I think might be related to Windows paths. If you're interested, I can share details.

doubleaxe commented 6 months ago

Hello.

This is actually not easy task. I tried to implement zoom around a center when I made this zoom feature and failed. Main problem here is browser scrollbar. I didn't expect that handling browser scrollbar will be such hard task, every time you do something, you should also correct scroll offset. So, when zooming around center you should do some complex calculations to find new scroll offset. I tried this, but scrollbar acted weird, often jumping to wrong positions.

Possible solution here is to get rid of browser scrollbar and either use custom scrollbar or just use mouse drag for scrolling without scrollbar at all. My code for handling these interaction is not very good :) My plans were to rewrite that part and to use ready external library like https://github.com/bcakmakoglu/vue-flow/ (they don't have scrollbars) - but this would consume too much time.