socib / Leaflet.TimeDimension

Add time dimension capabilities on a Leaflet map.
MIT License
435 stars 139 forks source link

Can dragging slider update the layer? #13

Closed karussell closed 8 years ago

karussell commented 8 years ago

Thanks for this nice plugin!

I would like to drag the slider to see the changes, without releasing it. Is it already possible - didn't find it in the docs!

bielfrontera commented 8 years ago

The default control changes the displayed date when you move the slide, and only fires changes when you stop. It uses slide and stop events from jquery UI slider(see jqueryUI slider docs and https://github.com/socib/Leaflet.TimeDimension/blob/master/src/leaflet.timedimension.control.js#L190).

You could extend L.Control.TimeDimension and overwrite _createSlider, to modify the behaviour of slide event (or others).

Here you have an example of extension of the timedimencion control: https://github.com/socib/Leaflet.TimeDimension/blob/master/examples/js/example12.js#L130

karussell commented 8 years ago

nice - thanks a lot! I've just followed this and got it working :) !


L.Control.TimeDimensionCustom = L.Control.TimeDimension.extend({
    _createSlider: function (className, container) {
        var _slider = L.DomUtil.create('a', className, container);
        _slider.href = '#';
        L.DomEvent
                .addListener(_slider, 'click', L.DomEvent.stopPropagation)
                .addListener(_slider, 'click', L.DomEvent.preventDefault);

        _slider.innerHTML = '<div class="slider"></div>';
        var slider = $(_slider).find('.slider');
        var max = this._timeDimension.getAvailableTimes().length - 1;
        slider.slider({
            min: 0,
            max: max,
            range: "min",
            stop: (function (event, ui) {
                this._sliderValueChanged(ui.value);
            }).bind(this),
            slide: (function (event, ui) {
                var date = new Date(this._timeDimension.getAvailableTimes()[ui.value]);
                this._displayDate.innerHTML = this._getDisplayDateFormat(date);

                // update route too
                this._sliderValueChanged(ui.value);
            }).bind(this),
        });
        return slider;
    },
});
map.addControl(new L.Control.TimeDimensionCustom({
    position: 'bottomleft',
    autoPlay: true,
    playerOptions: {
        transitionTime: 200,
        loop: true
    }
}));

I'm a bit untrained with these JavaScript frameworking. Can I avoid copy and pasting the whole method somehow with a super call? Like

var slider = super._createSlider(className, container);
slider.slide = (function (event, ui) {
     this._sliderValueChanged(ui.value);
}).bind(this),
return slider;
bielfrontera commented 8 years ago

Yes, you can do it. It's not as easy as other languages as Python, but you can do:

_superCreateSlider: L.Control.TimeDimension.prototype._createSlider,

_createSlider: function (className, container) {
    var slider = this._superCreateSlider(className, container);
    slider.slide = (function (event, ui) {
         this._sliderValueChanged(ui.value);
    }).bind(this),
    return slider;
},
karussell commented 8 years ago

Thanks! I had to use this slightly modified code now:

L.Control.TimeDimensionCustom = L.Control.TimeDimension.extend({
    _superCreateSlider: L.Control.TimeDimension.prototype._createSlider,
    _createSlider: function (className, container) {
        var that = this;
        var slider = this._superCreateSlider(className, container);
        slider.on("slide", function (event, ui) {
            that._sliderValueChanged(ui.value);
        });
        return slider;
    }
});

As the slide option seems only to work while creation ...