viewsliderzoomingopenlayers

OL5.3 ZoomSlider and the steps between the zoom-levels - how?


I used a useful bug in older OL5, now it was fixed and I seaching again for a solution since weeks...

My wish with the ZoomSlider is to stay at the step between the integer zooming levels. When I click on the Slider it moves e.g. from 16 to 17. My Polygon in the View may a little bit bigger than I need. Then I move the Sliderbutton a little bit and the View ist perfect - but as I leave the mousebutton the Sliderbutton jumps to the nearest level...

The bug in the past, there I could leave the Sliderbutton to left or right and the perfect View stood at the step between the levels (but the view did't refresh in this state, but most time this view was ok for me; I printed this view).

Now sadly this bug is fixed... - so I search a possibility to reach the steps between the levels again.

I tried with combinations (surely wrong) of constrainResolution false/true, pinchZoom false/true, zoomDelta or delta values between 0.5 and 2 ... nothing helps and after searching in API, google, .. and trying a lot, I'm very confused now.

I don't understand the meaning of "pinch" (normally I speak German; in the dictionary there are so much meanings for this word...) - because I don't see any change, neither I set pinchZoom to true nor set to false...

Is there any solution for "hold view between the Zoom Level"?


Solution

  • I cannot find any earlier version of OpenLayers where ZoomSlider works as you described.

    One workaround would be to set the view zoom factor very small to create many more zoom levels and set the delta options on the zoom button control and interactions correspondingly large so they continue to work at normal zoom levels.

    e.g. to divide each normal zoom level into 100 zoom levels:

    var zoomFactorDelta = 100;
    var map = new ol.Map({
        target: 'map',
        layers: [
            new ol.layer.Tile({
                source: new ol.source.OSM()
            })
        ],
        controls: ol.control.defaults({
            zoomOptions: { delta: zoomFactorDelta }
        }).extend([
            new ol.control.ZoomSlider()
        ]),
        interactions: ol.interaction.defaults({
            zoomDelta: zoomFactorDelta
        }),
        keyboardEventTarget: document,
        view: new ol.View({
            center: ol.proj.fromLonLat( [8, 50] ),
            zoomFactor: Math.pow(2,1/zoomFactorDelta),
            zoom: 10 * zoomFactorDelta,
            maxZoom: 20 * zoomFactorDelta
        })
    });
    

    However, while the zoomDelta setting works as expected for keyboard and double click zooms, it doesn't have any effect on mousewheel zoom (despite the documentation description "Zoom level delta when using keyboard or mousewheel zoom"), making mousewheel zoom 100 times slower than before. An alternative which keeps mousewheel zoom working at normal speed is to redefine the view's constrainResolution function to multiply the default delta parameter:

    var zoomFactorDelta = 100;
    var map = new ol.Map({
        target: 'map',
        layers: [
            new ol.layer.Tile({
                source: new ol.source.OSM()
            })
        ],
        controls: ol.control.defaults().extend([
            new ol.control.ZoomSlider()
        ]),
        keyboardEventTarget: document,
        view: new ol.View({
            center: ol.proj.fromLonLat( [8, 50] ),
            zoomFactor: Math.pow(2,1/zoomFactorDelta),
            zoom: 10 * zoomFactorDelta,
            maxZoom: 20 * zoomFactorDelta
        })
    });
    var view = map.getView();
    var defaultConstrainResolution = view.constrainResolution.bind(view);
    view.constrainResolution = function(resolution, delta, direction) {
        return defaultConstrainResolution(resolution, delta*zoomFactorDelta, direction)
    };
    

    This workaround using only an override of the constrainResolution function also works, but it might have side effects elsewhere:

    var map = new ol.Map({
        target: 'map',
        layers: [
            new ol.layer.Tile({
                source: new ol.source.OSM()
            })
        ],
        controls: ol.control.defaults().extend([
            new ol.control.ZoomSlider()
        ]),
        keyboardEventTarget: document,
        view: new ol.View({
            center: ol.proj.fromLonLat( [8, 50] ),
            zoom: 10
        })
    });
    var view = map.getView();
    var defaultConstrainResolution = view.constrainResolution.bind(view);
    view.constrainResolution = function(resolution, delta, direction) {
        return Math.abs(delta) > 0 ? defaultConstrainResolution(resolution, delta, direction)
                                   : resolution;
    };