publiclab / Leaflet.DistortableImage

A Leaflet extension to distort or "rubber sheet" images
https://publiclab.github.io/Leaflet.DistortableImage/examples/
BSD 2-Clause "Simplified" License
271 stars 283 forks source link

constrained distorsion #66

Open ccloquet opened 8 years ago

ccloquet commented 8 years ago

Although probably not the main point of this awesome plugin, I am sharing here how I handled constrained distorsion (eg : allowing only zoom from a center, or rectangular redimension) :

` _updateCorner: function(corner, latlng) {
switch(this.options.disto_style) { case 'constrained':

            switch(corner)
            {
                case 0: // leave 3 unchanged
                    // adapt the lat of 1 and the lon of 2
                    this._corners[1] = L.latLng(latlng.lat, this._corners[1].lng);
                    this._corners[2] = L.latLng(this._corners[2].lat, latlng.lng);
                    break;
                case 1: // leave 2 unchanged
                    // adapt the lat of 0 and the lon of 3
                    this._corners[0] = L.latLng(latlng.lat, this._corners[0].lng);
                    this._corners[3] = L.latLng(this._corners[3].lat, latlng.lng);
                    break;
                case 2: // leave 1 unchanged
                    // adapt the lat of 3 and the lon of 0
                    this._corners[3] = L.latLng(latlng.lat, this._corners[3].lng);
                    this._corners[0] = L.latLng(this._corners[0].lat, latlng.lng);
                    break;
                case 3: // leave 0 unchanged
                    // adapt the lat of 2 and the lon of 1
                    this._corners[2] = L.latLng(latlng.lat, this._corners[2].lng);
                    this._corners[1] = L.latLng(this._corners[1].lat, latlng.lng);
                    break;
            }

            this._corners[corner] = latlng;

            break;

        case 'zoom_from_center':
            var slat = 0, slng = 0, dlat, dlng;
            for(var i=0; i<4; ++i)
            {
                slat += this._corners[i].lat;
                slng += this._corners[i].lng;
            }
            slat /= 4.0; slng /= 4.0;

            dlat = Math.abs(latlng.lat-slat)
            dlng = Math.abs(latlng.lng-slng)

            this._corners[0] = L.latLng(slat+dlat, slng-dlng);
            this._corners[1] = L.latLng(slat+dlat, slng+dlng);
            this._corners[2] = L.latLng(slat-dlat, slng-dlng);
            this._corners[3] = L.latLng(slat-dlat, slng+dlng);
            break;
        case 'free':
        case 'default':
            this._corners[corner] = latlng;
            break;
        default:
            this._corners[corner] = latlng;
    }
    this._reset();
},`

Then in the options to initialize the plugin :

disto_style:'constrained' or disto_style:'zoom_from_center'

jywarren commented 8 years ago

Hi, awesome! if you'd like to submit this as a pull request with the options switch, I'd love to include it as an option for other folks using this lib.

On Mon, May 30, 2016 at 1:31 PM, Christophe Cloquet < notifications@github.com> wrote:

Although probably not the main point of this awesome plugin, I am sharing here how I handled constrained distorsion (eg : allowing only zoom from a center, or rectangular redimension) :

` _updateCorner: function(corner, latlng) {

switch(this.options.disto_style) { case 'constrained':

        switch(corner)
        {
            case 0: // leave 3 unchanged
                // adapt the lat of 1 and the lon of 2
                this._corners[1] = L.latLng(latlng.lat, this._corners[1].lng);
                this._corners[2] = L.latLng(this._corners[2].lat, latlng.lng);
                break;
            case 1: // leave 2 unchanged
                // adapt the lat of 0 and the lon of 3
                this._corners[0] = L.latLng(latlng.lat, this._corners[0].lng);
                this._corners[3] = L.latLng(this._corners[3].lat, latlng.lng);
                break;
            case 2: // leave 1 unchanged
                // adapt the lat of 3 and the lon of 0
                this._corners[3] = L.latLng(latlng.lat, this._corners[3].lng);
                this._corners[0] = L.latLng(this._corners[0].lat, latlng.lng);
                break;
            case 3: // leave 0 unchanged
                // adapt the lat of 2 and the lon of 1
                this._corners[2] = L.latLng(latlng.lat, this._corners[2].lng);
                this._corners[1] = L.latLng(this._corners[1].lat, latlng.lng);
                break;
        }

        this._corners[corner] = latlng;

        break;

    case 'zoom_from_center':
        var slat = 0, slng = 0, dlat, dlng;
        for(var i=0; i<4; ++i)
        {
            slat += this._corners[i].lat;
            slng += this._corners[i].lng;
        }
        slat /= 4.0; slng /= 4.0;

        dlat = Math.abs(latlng.lat-slat)
        dlng = Math.abs(latlng.lng-slng)

        this._corners[0] = L.latLng(slat+dlat, slng-dlng);
        this._corners[1] = L.latLng(slat+dlat, slng+dlng);
        this._corners[2] = L.latLng(slat-dlat, slng-dlng);
        this._corners[3] = L.latLng(slat-dlat, slng+dlng);
        break;
    case 'free':
    case 'default':
        this._corners[corner] = latlng;
        break;
    default:
        this._corners[corner] = latlng;
}
this._reset();

},`

Then in the options to initialize the plugin :

disto_style:'constrained' or disto_style:'zoom_from_center'

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/publiclab/Leaflet.DistortableImage/issues/66, or mute the thread https://github.com/notifications/unsubscribe/AABfJ254_toUMgPMkjYCPxI2PNvL5DP3ks5qGx7ygaJpZM4Ip8lO .

grvsachdeva commented 5 years ago

@jywarren if you think the above method stated by @ccloquet is apt, then we can open a separate issue for handling the case. What do you think? Thanks!