1/** 2 * Copyright (C) 2013 Maxime Hadjinlian <[email protected]> 3 * All Rights Reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * - Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28(function () { 29 30 // Retain the value of the original onAdd and onRemove functions 31 var originalOnAdd = L.Marker.prototype.onAdd; 32 var originalOnRemove = L.Marker.prototype.onRemove; 33 34 // Add bounceonAdd options 35 L.Marker.mergeOptions({ 36 bounceOnAdd: false, 37 bounceOnAddOptions: { 38 duration: 1000, 39 height: -1 40 }, 41 bounceOnAddCallback: function() {} 42 }); 43 44 L.Marker.include({ 45 46 _toPoint: function (latlng) { 47 return this._map.latLngToContainerPoint(latlng); 48 }, 49 _toLatLng: function (point) { 50 return this._map.containerPointToLatLng(point); 51 }, 52 53 _motionStep: function (opts) { 54 var self = this; 55 56 var start = new Date(); 57 self._intervalId = setInterval(function () { 58 var timePassed = new Date() - start; 59 var progress = timePassed / opts.duration; 60 if (progress > 1) { 61 progress = 1; 62 } 63 var delta = opts.delta(progress); 64 opts.step(delta); 65 if (progress === 1) { 66 opts.end(); 67 clearInterval(self._intervalId); 68 } 69 }, opts.delay || 10); 70 }, 71 72 _bounceMotion: function (delta, duration, callback) { 73 var original = L.latLng(this._origLatlng), 74 start_y = this._dropPoint.y, 75 start_x = this._dropPoint.x, 76 distance = this._point.y - start_y; 77 var self = this; 78 79 this._motionStep({ 80 delay: 10, 81 duration: duration || 1000, // 1 sec by default 82 delta: delta, 83 step: function (delta) { 84 self._dropPoint.y = 85 start_y 86 + (distance * delta) 87 - (self._map.project(self._map.getCenter()).y - self._origMapCenter.y); 88 self._dropPoint.x = 89 start_x 90 - (self._map.project(self._map.getCenter()).x - self._origMapCenter.x); 91 self.setLatLng(self._toLatLng(self._dropPoint)); 92 }, 93 end: function () { 94 self.setLatLng(original); 95 if (typeof callback === "function") callback(); 96 } 97 }); 98 }, 99 100 // Many thanks to Robert Penner for this function 101 _easeOutBounce: function (pos) { 102 if ((pos) < (1 / 2.75)) { 103 return (7.5625 * pos * pos); 104 } else if (pos < (2 / 2.75)) { 105 return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75); 106 } else if (pos < (2.5 / 2.75)) { 107 return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375); 108 } else { 109 return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375); 110 } 111 }, 112 113 // Bounce : if options.height in pixels is not specified, drop from top. 114 // If options.duration is not specified animation is 1s long. 115 bounce: function(options, endCallback) { 116 this._origLatlng = this.getLatLng(); 117 this._bounce(options, endCallback); 118 }, 119 120 _bounce: function (options, endCallback) { 121 if (typeof options === "function") { 122 endCallback = options; 123 options = null; 124 } 125 options = options || {duration: 1000, height: -1}; 126 127 //backward compatibility 128 if (typeof options === "number") { 129 options.duration = arguments[0]; 130 options.height = arguments[1]; 131 } 132 133 // Keep original map center
134 this._origMapCenter = this._map.project(this._map.getCenter()); 135 this._dropPoint = this._getDropPoint(options.height); 136 this._bounceMotion(this._easeOutBounce, options.duration, endCallback); 137 }, 138 139 // This will get you a drop point given a height. 140 // If no height is given, the top y will be used. 141 _getDropPoint: function (height) { 142 // Get current coordidates in pixel 143 this._point = this._toPoint(this._origLatlng); 144 var top_y; 145 if (height === undefined || height < 0) { 146 top_y = this._toPoint(this._map.getBounds()._northEast).y; 147 } else { 148 top_y = this._point.y - height; 149 } 150 return new L.Point(this._point.x, top_y); 151 }, 152 153 onAdd: function (map) { 154 this._map = map; 155 // Keep original latitude and longitude 156 this._origLatlng = this._latlng; 157 158 // We need to have our drop point BEFORE adding the marker to the map 159 // otherwise, it would create a flicker. (The marker would appear at final 160 // location then move to its drop location, and you may be able to see it.) 161 if (this.options.bounceOnAdd === true) { 162 // backward compatibility 163 if (typeof this.options.bounceOnAddDuration !== 'undefined') { 164 this.options.bounceOnAddOptions.duration = this.options.bounceOnAddDuration; 165 } 166 167 // backward compatibility 168 if (typeof this.options.bounceOnAddHeight !== 'undefined') { 169 this.options.bounceOnAddOptions.height = this.options.bounceOnAddHeight; 170 } 171 172 this._dropPoint = this._getDropPoint(this.options.bounceOnAddOptions.height); 173 this.setLatLng(this._toLatLng(this._dropPoint)); 174 } 175 176 // Call leaflet original method to add the Marker to the map. 177 originalOnAdd.call(this, map); 178 179 if (this.options.bounceOnAdd === true) { 180 this._bounce(this.options.bounceOnAddOptions, this.options.bounceOnAddCallback); 181 } 182 }, 183 184 onRemove: function (map) { 185 clearInterval(this._intervalId); 186 originalOnRemove.call(this, map); 187 } 188 }); 189})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.