Merge branch 'master' of github.com:Leaflet/Leaflet into popup-debugging
This commit is contained in:
commit
52be81b18b
29
.eslintrc
Normal file
29
.eslintrc
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"rules": {
|
||||
"camelcase": 2,
|
||||
"quotes": [2, "single"],
|
||||
"no-mixed-spaces-and-tabs": [2, "smart-tabs"],
|
||||
"space-after-function-name": 2,
|
||||
"space-in-parens": 2,
|
||||
"space-in-brackets": 2,
|
||||
"space-before-blocks": 2,
|
||||
"space-after-keywords": 2,
|
||||
"no-lonely-if": 2,
|
||||
"comma-style": 2,
|
||||
"indent": [2, "tab"],
|
||||
"no-underscore-dangle": 0,
|
||||
"no-constant-condition": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"strict": 0,
|
||||
"key-spacing": 0,
|
||||
"no-shadow": 0
|
||||
},
|
||||
"globals": {
|
||||
"L": true,
|
||||
"module": false,
|
||||
"define": false
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
}
|
||||
}
|
@ -18,8 +18,8 @@ before_script: >
|
||||
test ${TRAVIS_BRANCH} = master ||
|
||||
test ${TRAVIS_BRANCH} = stable &&
|
||||
test ${TRAVIS_PULL_REQUEST} = false &&
|
||||
gem install --no-rdoc --no-ri --version 0.8.9 faraday &&
|
||||
gem install --no-rdoc --no-ri travis-artifacts || true
|
||||
gem install --no-document --version 0.8.9 faraday &&
|
||||
gem install --no-document travis-artifacts || true
|
||||
after_success: >
|
||||
test ${TRAVIS_BRANCH} = master ||
|
||||
test ${TRAVIS_BRANCH} = stable &&
|
||||
|
@ -31,7 +31,7 @@ here are some tips for creating a helpful report that will make fixing it much e
|
||||
|
||||
* Write a **descriptive, specific title**. Bad: *Problem with polylines*. Good: *Doing X in IE9 causes Z*.
|
||||
* Include **browser, OS and Leaflet version** info in the description.
|
||||
* Create a **simple test case** that demonstrates the bug (e.g. using [JSFiddle](http://jsfiddle.net/)).
|
||||
* Create a **simple test case** that demonstrates the bug (e.g. using [JSFiddle](http://jsfiddle.net/) or [JS Bin](http://jsbin.com/)).
|
||||
* Check whether the bug can be reproduced in **other browsers**.
|
||||
* Check if the bug occurs in the stable version, master, or both.
|
||||
* *Bonus tip:* if the bug only appears in the master version but the stable version is fine,
|
||||
@ -125,7 +125,7 @@ From there you can click through folders/files to get details on their individua
|
||||
## Improving Documentation
|
||||
|
||||
The code of the live Leaflet website that contains all documentation and examples is located in the `gh-pages` branch
|
||||
and is automatically generated from a set of HTML and Markdown files by [Jekyll](https://github.com/mojombo/jekyll).
|
||||
and is automatically generated from a set of HTML and Markdown files by [Jekyll](http://jekyllrb.com/).
|
||||
|
||||
The easiest way to make little improvements such as fixing typos without even leaving the browser
|
||||
is by editing one of the files with the online GitHub editor:
|
||||
|
12
Jakefile.js
12
Jakefile.js
@ -15,10 +15,10 @@ For a custom build, open build/build.html in the browser and follow the instruct
|
||||
var build = require('./build/build.js'),
|
||||
version = require('./src/Leaflet.js').version;
|
||||
|
||||
function hint(msg, paths) {
|
||||
function hint(msg, args) {
|
||||
return function () {
|
||||
console.log(msg);
|
||||
jake.exec('node node_modules/jshint/bin/jshint -c ' + paths,
|
||||
jake.exec('node node_modules/eslint/bin/eslint.js ' + args,
|
||||
{printStdout: true}, function () {
|
||||
console.log('\tCheck passed.\n');
|
||||
complete();
|
||||
@ -26,11 +26,11 @@ function hint(msg, paths) {
|
||||
};
|
||||
}
|
||||
|
||||
desc('Check Leaflet source for errors with JSHint');
|
||||
task('lint', {async: true}, hint('Checking for JS errors...', 'build/hintrc.js src'));
|
||||
desc('Check Leaflet source for errors with ESLint');
|
||||
task('lint', {async: true}, hint('Checking for JS errors...', 'src --config .eslintrc'));
|
||||
|
||||
desc('Check Leaflet specs source for errors with JSHint');
|
||||
task('lintspec', {async: true}, hint('Checking for specs JS errors...', 'spec/spec.hintrc.js spec/suites'));
|
||||
desc('Check Leaflet specs source for errors with ESLint');
|
||||
task('lintspec', {async: true}, hint('Checking for specs JS errors...', 'spec/suites --config spec/.eslintrc'));
|
||||
|
||||
desc('Combine and compress Leaflet source files');
|
||||
task('build', {async: true}, function (compsBase32, buildName) {
|
||||
|
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2010-2014, Vladimir Agafonkin
|
||||
Copyright (c) 2010-2015, Vladimir Agafonkin
|
||||
Copyright (c) 2010-2011, CloudMade
|
||||
All rights reserved.
|
||||
|
||||
|
@ -113,7 +113,7 @@ Function, method and property names should be in `camelCase`.<br>
|
||||
Class names should be in `CapitalizedCamelCase`.
|
||||
|
||||
If you have a lot of arguments in your function, consider accepting an options object instead
|
||||
(putting default values where possible so that users don't need specify all of them):
|
||||
(putting default values where possible so that users don't need to specify all of them):
|
||||
|
||||
```js
|
||||
// bad
|
||||
@ -168,12 +168,11 @@ You can add support for AMD/CommonJS loaders to your Leaflet plugin by following
|
||||
// define a Common JS module that relies on 'leaflet'
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory(require('leaflet'));
|
||||
|
||||
}
|
||||
|
||||
// attach your plugin to the global 'L' variable
|
||||
if(typeof window !== 'undefined' && window.L){
|
||||
window.L.YourPlugin = factory(L);
|
||||
if (typeof window !== 'undefined' && window.L) {
|
||||
window.L.YourPlugin = factory(L);
|
||||
}
|
||||
}(function (L) {
|
||||
var MyLeafletPlugin = {};
|
||||
|
@ -19,7 +19,7 @@ If you want to **get involved** with Leaflet development, check out the [contrib
|
||||
Let's make the best mapping library that will ever exist,
|
||||
and push the limits of what's possible with online maps!
|
||||
|
||||
[![Build Status](https://travis-ci.org/Leaflet/Leaflet.png?branch=master)](https://travis-ci.org/Leaflet/Leaflet)
|
||||
[![Build Status](https://travis-ci.org/Leaflet/Leaflet.svg?branch=master)](https://travis-ci.org/Leaflet/Leaflet)
|
||||
|
||||
[Vladimir Agafonkin]: http://agafonkin.com/en
|
||||
[contributors]: https://github.com/Leaflet/Leaflet/graphs/contributors
|
||||
|
@ -1,40 +0,0 @@
|
||||
{
|
||||
// environment
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"globals": {
|
||||
"L": true,
|
||||
"define": true
|
||||
},
|
||||
"strict": false,
|
||||
"es3": true,
|
||||
|
||||
// code style
|
||||
"bitwise": true,
|
||||
"camelcase": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"forin": false,
|
||||
"immed": true,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"quotmark": "single",
|
||||
|
||||
// whitespace
|
||||
"indent": 4,
|
||||
"trailing": true,
|
||||
"white": true,
|
||||
"smarttabs": true,
|
||||
"maxlen": 120
|
||||
|
||||
// code simplicity - not enforced but nice to check from time to time
|
||||
// "maxstatements": 20,
|
||||
// "maxcomplexity": 5
|
||||
// "maxparams": 4,
|
||||
// "maxdepth": 4
|
||||
}
|
@ -40,8 +40,8 @@
|
||||
map.addLayer(overlay);
|
||||
|
||||
overlay.on('dblclick',function (e) {
|
||||
console.log('Double click on image.')
|
||||
})
|
||||
console.log('Double click on image.');
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
11
dist/leaflet.css
vendored
11
dist/leaflet.css
vendored
@ -139,7 +139,9 @@
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-tile,
|
||||
.leaflet-fade-anim .leaflet-tile {
|
||||
will-change: opacity;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
@ -147,11 +149,12 @@
|
||||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-tile-loaded,
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
@ -440,7 +443,7 @@
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
|
20
package.json
20
package.json
@ -3,20 +3,20 @@
|
||||
"version": "0.8.0-dev",
|
||||
"description": "JavaScript library for mobile-friendly interactive maps",
|
||||
"devDependencies": {
|
||||
"jake": "~8.0.10",
|
||||
"jshint": "~2.5.7",
|
||||
"uglify-js": "~2.4.15",
|
||||
"mocha": "~2.0.1",
|
||||
"copyfiles": "0.1.0",
|
||||
"eslint": "^0.15.1",
|
||||
"happen": "~0.1.3",
|
||||
"karma": "~0.12.24",
|
||||
"karma-mocha": "~0.1.9",
|
||||
"karma-coverage": "~0.2.6",
|
||||
"jake": "~8.0.10",
|
||||
"karma": "~0.12.31",
|
||||
"karma-chrome-launcher": "^0.1.7",
|
||||
"karma-coverage": "~0.2.7",
|
||||
"karma-firefox-launcher": "~0.1.4",
|
||||
"karma-mocha": "~0.1.10",
|
||||
"karma-phantomjs-launcher": "^0.1.4",
|
||||
"karma-chrome-launcher": "^0.1.5",
|
||||
"karma-firefox-launcher": "~0.1.3",
|
||||
"karma-safari-launcher": "~0.1.1",
|
||||
"mocha": "~2.1.0",
|
||||
"tin": "^0.5.0",
|
||||
"copyfiles": "0.1.0"
|
||||
"uglify-js": "~2.4.16"
|
||||
},
|
||||
"main": "dist/leaflet-src.js",
|
||||
"style": "dist/leaflet.css",
|
||||
|
38
spec/.eslintrc
Normal file
38
spec/.eslintrc
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"rules": {
|
||||
"camelcase": 2,
|
||||
"no-mixed-spaces-and-tabs": [2, "smart-tabs"],
|
||||
"space-after-function-name": 2,
|
||||
"space-in-parens": 2,
|
||||
"space-in-brackets": 2,
|
||||
"space-before-blocks": 2,
|
||||
"space-after-keywords": 2,
|
||||
"no-lonely-if": 2,
|
||||
"comma-style": 2,
|
||||
"no-unused-vars": 0,
|
||||
"quotes": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-constant-condition": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"strict": 0,
|
||||
"key-spacing": 0,
|
||||
"no-shadow": 0,
|
||||
"no-irregular-whitespace": 0,
|
||||
"no-console": 0
|
||||
},
|
||||
"globals": {
|
||||
"L": true,
|
||||
"module": false,
|
||||
"define": false,
|
||||
"expect": false,
|
||||
"it": false,
|
||||
"describe": false,
|
||||
"sinon": false,
|
||||
"happen": false,
|
||||
"beforeEach": false,
|
||||
"afterEach": false
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
}
|
||||
}
|
@ -63,6 +63,10 @@ module.exports = function (config) {
|
||||
// If browser does not capture in given timeout [ms], kill it
|
||||
captureTimeout: 5000,
|
||||
|
||||
// Workaround for PhantomJS random DISCONNECTED error
|
||||
browserDisconnectTimeout: 10000, // default 2000
|
||||
browserDisconnectTolerance: 1, // default 0
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, it capture browsers, run tests and exit
|
||||
singleRun: true
|
||||
|
@ -1,4 +1,5 @@
|
||||
if (!Array.prototype.map) {
|
||||
/*eslint no-extend-native:0*/
|
||||
Array.prototype.map = function (fun /*, thisp */) {
|
||||
"use strict";
|
||||
|
||||
@ -7,7 +8,6 @@ if (!Array.prototype.map) {
|
||||
}
|
||||
|
||||
var t = Object(this);
|
||||
// jshint bitwise: false
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun !== "function") {
|
||||
throw new TypeError();
|
||||
|
@ -14,7 +14,7 @@ describe('Events', function () {
|
||||
obj.addEventListener('test', spy1);
|
||||
obj.addEventListener('test', spy2);
|
||||
obj.addEventListener('other', spy3);
|
||||
obj.addEventListener({ test: spy4, other: spy5 });
|
||||
obj.addEventListener({test: spy4, other: spy5});
|
||||
// obj.addEventListener({'test other': spy6 });
|
||||
|
||||
expect(spy1.called).to.be(false);
|
||||
@ -72,8 +72,8 @@ describe('Events', function () {
|
||||
|
||||
obj.addEventListener('test', listener1);
|
||||
obj2.addEventListener('test', listener2, foo);
|
||||
obj3.addEventListener({ test: listener3 });
|
||||
obj4.addEventListener({ test: listener4 }, foo);
|
||||
obj3.addEventListener({test: listener3});
|
||||
obj4.addEventListener({test: listener4}, foo);
|
||||
|
||||
obj.fireEvent('test', {baz: 1});
|
||||
obj2.fireEvent('test', {baz: 2});
|
||||
@ -358,15 +358,15 @@ describe('Events', function () {
|
||||
});
|
||||
|
||||
it("doesn't call listeners to events that have been removed", function () {
|
||||
var obj = new L.Evented(),
|
||||
spy = sinon.spy();
|
||||
var obj = new L.Evented(),
|
||||
spy = sinon.spy();
|
||||
|
||||
obj.once('test', spy, obj);
|
||||
obj.off('test', spy, obj);
|
||||
obj.once('test', spy, obj);
|
||||
obj.off('test', spy, obj);
|
||||
|
||||
obj.fire('test');
|
||||
obj.fire('test');
|
||||
|
||||
expect(spy.called).to.be(false);
|
||||
expect(spy.called).to.be(false);
|
||||
});
|
||||
|
||||
it('works if called from a context that doesnt implement #Events', function () {
|
||||
|
@ -40,9 +40,9 @@ describe('Util', function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
var fn2 = L.Util.bind(fn, { foo: 'bar' });
|
||||
var fn2 = L.Util.bind(fn, {foo: 'bar'});
|
||||
|
||||
expect(fn2()).to.eql({ foo: 'bar' });
|
||||
expect(fn2()).to.eql({foo: 'bar'});
|
||||
});
|
||||
|
||||
it('passes additional arguments to the bound function', function () {
|
||||
@ -230,6 +230,7 @@ describe('Util', function () {
|
||||
|
||||
describe('#isArray', function () {
|
||||
expect(L.Util.isArray([1, 2, 3])).to.be(true);
|
||||
/*eslint no-array-constructor:0*/
|
||||
expect(L.Util.isArray(new Array(1, 2, 3))).to.be(true);
|
||||
expect(L.Util.isArray('blabla')).to.be(false);
|
||||
expect(L.Util.isArray({0: 1, 1: 2})).to.be(false);
|
||||
|
@ -112,9 +112,8 @@ describe('LatLng', function () {
|
||||
});
|
||||
|
||||
it('accepts an object with alt', function () {
|
||||
expect(L.latLng({lat: 50, lng: 30, alt:100})).to.eql(new L.LatLng(50, 30, 100));
|
||||
expect(L.latLng({lat: 50, lon: 30, alt:100})).to.eql(new L.LatLng(50, 30, 100));
|
||||
expect(L.latLng({lat: 50, lng: 30, alt: 100})).to.eql(new L.LatLng(50, 30, 100));
|
||||
expect(L.latLng({lat: 50, lon: 30, alt: 100})).to.eql(new L.LatLng(50, 30, 100));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -33,6 +33,21 @@ describe('LineUtil', function () {
|
||||
|
||||
expect(segment).to.be(false);
|
||||
});
|
||||
|
||||
it('can round numbers in clipped bounds', function () {
|
||||
var a = new L.Point(4, 5);
|
||||
var b = new L.Point(8, 6);
|
||||
|
||||
var segment1 = L.LineUtil.clipSegment(a, b, bounds);
|
||||
|
||||
expect(segment1[0]).to.eql(new L.Point(5, 5.25));
|
||||
expect(segment1[1]).to.eql(b);
|
||||
|
||||
var segment2 = L.LineUtil.clipSegment(a, b, bounds, false, true);
|
||||
|
||||
expect(segment2[0]).to.eql(new L.Point(5, 5));
|
||||
expect(segment2[1]).to.eql(b);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointToSegmentDistance & #closestPointOnSegment', function () {
|
||||
|
@ -10,6 +10,7 @@ describe('PolyUtil', function () {
|
||||
new L.Point(10, 15)
|
||||
];
|
||||
|
||||
//check clip without rounding
|
||||
var clipped = L.PolyUtil.clipPolygon(points, bounds);
|
||||
|
||||
for (var i = 0, len = clipped.length; i < len; i++) {
|
||||
@ -17,6 +18,20 @@ describe('PolyUtil', function () {
|
||||
}
|
||||
|
||||
expect(clipped).to.eql([
|
||||
new L.Point(7.5, 10),
|
||||
new L.Point(5, 5),
|
||||
new L.Point(10, 7.5),
|
||||
new L.Point(10, 10)
|
||||
]);
|
||||
|
||||
//check clip with rounding
|
||||
var clippedRounded = L.PolyUtil.clipPolygon(points, bounds, true);
|
||||
|
||||
for (i = 0, len = clippedRounded.length; i < len; i++) {
|
||||
delete clippedRounded[i]._code;
|
||||
}
|
||||
|
||||
expect(clippedRounded).to.eql([
|
||||
new L.Point(8, 10),
|
||||
new L.Point(5, 5),
|
||||
new L.Point(10, 8),
|
||||
|
@ -58,7 +58,7 @@
|
||||
it('iterates over all layers', function () {
|
||||
var lg = L.layerGroup(),
|
||||
marker = L.marker([0, 0]),
|
||||
ctx = { foo: 'bar' };
|
||||
ctx = {foo: 'bar'};
|
||||
|
||||
lg.addLayer(marker);
|
||||
|
||||
|
@ -112,6 +112,41 @@ describe('Popup', function () {
|
||||
marker1.closePopup();
|
||||
expect(spy.callCount).to.be(2);
|
||||
});
|
||||
|
||||
it("should take into account icon popupAnchor option", function () {
|
||||
var autoPanBefore = L.Popup.prototype.options.autoPan;
|
||||
L.Popup.prototype.options.autoPan = false;
|
||||
var popupAnchorBefore = L.Icon.Default.prototype.options.popupAnchor;
|
||||
L.Icon.Default.prototype.options.popupAnchor = [0, 0];
|
||||
|
||||
var latlng = new L.LatLng(55.8, 37.6),
|
||||
offset = new L.Point(20, 30),
|
||||
icon = new L.DivIcon({popupAnchor: offset}),
|
||||
marker1 = new L.Marker(latlng),
|
||||
marker2 = new L.Marker(latlng, {icon: icon});
|
||||
marker1.bindPopup('Popup').addTo(map);
|
||||
marker1.openPopup();
|
||||
var defaultLeft = parseInt(marker1._popup._container.style.left, 10);
|
||||
var defaultBottom = parseInt(marker1._popup._container.style.bottom, 10);
|
||||
marker2.bindPopup('Popup').addTo(map);
|
||||
marker2.openPopup();
|
||||
var offsetLeft = parseInt(marker2._popup._container.style.left, 10);
|
||||
var offsetBottom = parseInt(marker2._popup._container.style.bottom, 10);
|
||||
expect(offsetLeft - offset.x).to.eql(defaultLeft);
|
||||
expect(offsetBottom + offset.y).to.eql(defaultBottom);
|
||||
|
||||
// Now retry passing a popup instance to bindPopup
|
||||
marker2.bindPopup(new L.Popup());
|
||||
marker2.openPopup();
|
||||
offsetLeft = parseInt(marker2._popup._container.style.left, 10);
|
||||
offsetBottom = parseInt(marker2._popup._container.style.bottom, 10);
|
||||
expect(offsetLeft - offset.x).to.eql(defaultLeft);
|
||||
expect(offsetBottom + offset.y).to.eql(defaultBottom);
|
||||
|
||||
L.Popup.prototype.options.autoPan = autoPanBefore;
|
||||
L.Icon.Default.prototype.options.popupAnchor = popupAnchorBefore;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("L.Map#openPopup", function () {
|
||||
|
@ -1,11 +1,16 @@
|
||||
describe("Marker", function () {
|
||||
var map,
|
||||
spy,
|
||||
div,
|
||||
icon1,
|
||||
icon2;
|
||||
|
||||
beforeEach(function () {
|
||||
map = L.map(document.createElement('div')).setView([0, 0], 0);
|
||||
div = document.createElement('div');
|
||||
div.style.height = '100px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div).setView([0, 0], 0);
|
||||
icon1 = new L.Icon.Default();
|
||||
icon2 = new L.Icon.Default({
|
||||
iconUrl: icon1._getIconUrl('icon') + '?2',
|
||||
@ -13,6 +18,10 @@ describe("Marker", function () {
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
describe("#setIcon", function () {
|
||||
it("changes the icon to another image", function () {
|
||||
var marker = new L.Marker([0, 0], {icon: icon1});
|
||||
@ -40,14 +49,25 @@ describe("Marker", function () {
|
||||
marker.setIcon(icon1);
|
||||
|
||||
expect(marker.dragging.enabled()).to.be(true);
|
||||
|
||||
map.removeLayer(marker);
|
||||
map.addLayer(marker);
|
||||
|
||||
expect(marker.dragging.enabled()).to.be(true);
|
||||
|
||||
map.removeLayer(marker);
|
||||
// Dragging is still enabled, we should be able to disable it,
|
||||
// even if marker is off the map.
|
||||
marker.dragging.disable();
|
||||
map.addLayer(marker);
|
||||
});
|
||||
|
||||
it("changes the icon to another DivIcon", function () {
|
||||
var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text' }) });
|
||||
var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text'})});
|
||||
map.addLayer(marker);
|
||||
|
||||
var beforeIcon = marker._icon;
|
||||
marker.setIcon(new L.DivIcon({html: 'Inner2Text' }));
|
||||
marker.setIcon(new L.DivIcon({html: 'Inner2Text'}));
|
||||
var afterIcon = marker._icon;
|
||||
|
||||
expect(beforeIcon).to.be(afterIcon);
|
||||
@ -55,7 +75,7 @@ describe("Marker", function () {
|
||||
});
|
||||
|
||||
it("removes text when changing to a blank DivIcon", function () {
|
||||
var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text' }) });
|
||||
var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text'})});
|
||||
map.addLayer(marker);
|
||||
|
||||
marker.setIcon(new L.DivIcon());
|
||||
@ -65,7 +85,7 @@ describe("Marker", function () {
|
||||
});
|
||||
|
||||
it("changes a DivIcon to an image", function () {
|
||||
var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text' }) });
|
||||
var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text'})});
|
||||
map.addLayer(marker);
|
||||
var oldIcon = marker._icon;
|
||||
|
||||
@ -87,7 +107,7 @@ describe("Marker", function () {
|
||||
map.addLayer(marker);
|
||||
var oldIcon = marker._icon;
|
||||
|
||||
marker.setIcon(new L.DivIcon({html: 'Inner1Text' }));
|
||||
marker.setIcon(new L.DivIcon({html: 'Inner1Text'}));
|
||||
|
||||
expect(oldIcon).to.not.be(marker._icon);
|
||||
expect(oldIcon.parentNode).to.be(null);
|
||||
@ -97,7 +117,7 @@ describe("Marker", function () {
|
||||
});
|
||||
|
||||
it("reuses the icon/shadow when changing icon", function () {
|
||||
var marker = new L.Marker([0, 0], { icon: icon1});
|
||||
var marker = new L.Marker([0, 0], {icon: icon1});
|
||||
map.addLayer(marker);
|
||||
var oldIcon = marker._icon;
|
||||
var oldShadow = marker._shadow;
|
||||
@ -115,7 +135,7 @@ describe("Marker", function () {
|
||||
describe("#setLatLng", function () {
|
||||
it("fires a move event", function () {
|
||||
|
||||
var marker = new L.Marker([0, 0], { icon: icon1 });
|
||||
var marker = new L.Marker([0, 0], {icon: icon1});
|
||||
map.addLayer(marker);
|
||||
|
||||
var beforeLatLng = marker._latlng;
|
||||
@ -134,4 +154,17 @@ describe("Marker", function () {
|
||||
expect(marker.getLatLng()).to.be(afterLatLng);
|
||||
});
|
||||
});
|
||||
|
||||
describe('events', function () {
|
||||
it('fires click event when clicked', function () {
|
||||
var spy = sinon.spy();
|
||||
|
||||
var marker = L.marker([0, 0]).addTo(map);
|
||||
|
||||
marker.on('click', spy);
|
||||
happen.click(marker._icon);
|
||||
|
||||
expect(spy.called).to.be.ok();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -104,32 +104,6 @@ describe('GridLayer', function () {
|
||||
map.setZoom(0, {animate: false});
|
||||
clock.tick(250);
|
||||
});
|
||||
|
||||
it('prunes and retains the correct tiles for back-to-back zooms', function () {
|
||||
map.setView([0, 0], 1);
|
||||
|
||||
var grid = L.gridLayer();
|
||||
var tiles = {};
|
||||
|
||||
grid.createTile = function (coords) {
|
||||
tiles[grid._tileCoordsToKey(coords)] = true;
|
||||
return document.createElement('div');
|
||||
};
|
||||
|
||||
map.addLayer(grid);
|
||||
clock.tick(500);
|
||||
|
||||
map.setZoom(0, {animate: false});
|
||||
clock.tick(250);
|
||||
|
||||
map.setZoom(1, {animate: false});
|
||||
clock.tick(500);
|
||||
|
||||
var tileContainers = div.querySelectorAll('.leaflet-tile-container');
|
||||
expect(tileContainers.length).to.eql(2);
|
||||
expect(tileContainers[0].childNodes.length).to.equal(8);
|
||||
expect(tileContainers[1].childNodes.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#onAdd", function () {
|
||||
@ -202,11 +176,12 @@ describe('GridLayer', function () {
|
||||
});
|
||||
describe("when a tilelayer is removed from a map", function () {
|
||||
it("has its zoomlevels updated to only fit the layers it currently has", function () {
|
||||
var tiles = [ L.gridLayer({minZoom: 10, maxZoom: 15}).addTo(map),
|
||||
L.gridLayer({minZoom: 5, maxZoom: 10}).addTo(map),
|
||||
L.gridLayer({minZoom: 10, maxZoom: 20}).addTo(map),
|
||||
L.gridLayer({minZoom: 0, maxZoom: 25}).addTo(map)
|
||||
];
|
||||
var tiles = [
|
||||
L.gridLayer({minZoom: 10, maxZoom: 15}).addTo(map),
|
||||
L.gridLayer({minZoom: 5, maxZoom: 10}).addTo(map),
|
||||
L.gridLayer({minZoom: 10, maxZoom: 20}).addTo(map),
|
||||
L.gridLayer({minZoom: 0, maxZoom: 25}).addTo(map)
|
||||
];
|
||||
map.whenReady(function () {
|
||||
expect(map.getMinZoom()).to.be(0);
|
||||
expect(map.getMaxZoom()).to.be(25);
|
||||
|
@ -8,7 +8,7 @@
|
||||
describe("when a CircleMarker is added to the map ", function () {
|
||||
describe("with a radius set as an option", function () {
|
||||
it("takes that radius", function () {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 }).addTo(map);
|
||||
var marker = L.circleMarker([0, 0], {radius: 20}).addTo(map);
|
||||
|
||||
expect(marker._radius).to.be(20);
|
||||
});
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
describe("and radius is set before adding it", function () {
|
||||
it("takes that radius", function () {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 });
|
||||
var marker = L.circleMarker([0, 0], {radius: 20});
|
||||
marker.setRadius(15);
|
||||
marker.addTo(map);
|
||||
expect(marker._radius).to.be(15);
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
describe("and radius is set after adding it", function () {
|
||||
it("takes that radius", function () {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 });
|
||||
var marker = L.circleMarker([0, 0], {radius: 20});
|
||||
marker.addTo(map);
|
||||
marker.setRadius(15);
|
||||
expect(marker._radius).to.be(15);
|
||||
@ -34,16 +34,16 @@
|
||||
|
||||
describe("and setStyle is used to change the radius after adding", function () {
|
||||
it("takes the given radius", function () {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 });
|
||||
var marker = L.circleMarker([0, 0], {radius: 20});
|
||||
marker.addTo(map);
|
||||
marker.setStyle({ radius: 15 });
|
||||
marker.setStyle({radius: 15});
|
||||
expect(marker._radius).to.be(15);
|
||||
});
|
||||
});
|
||||
describe("and setStyle is used to change the radius before adding", function () {
|
||||
it("takes the given radius", function () {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 });
|
||||
marker.setStyle({ radius: 15 });
|
||||
var marker = L.circleMarker([0, 0], {radius: 20});
|
||||
marker.setStyle({radius: 15});
|
||||
marker.addTo(map);
|
||||
expect(marker._radius).to.be(15);
|
||||
});
|
||||
|
@ -570,4 +570,24 @@ describe("Map", function () {
|
||||
expect(spy.called).to.be.ok();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#flyTo', function () {
|
||||
|
||||
it('move to requested center and zoom, and call zoomend once', function (done) {
|
||||
var spy = sinon.spy(),
|
||||
newCenter = new L.LatLng(10, 11),
|
||||
newZoom = 12,
|
||||
callback = function () {
|
||||
expect(map.getCenter()).to.eql(newCenter);
|
||||
expect(map.getZoom()).to.eql(newZoom);
|
||||
spy();
|
||||
expect(spy.calledOnce).to.be.ok();
|
||||
done();
|
||||
};
|
||||
map.setView([0, 0], 0);
|
||||
map.once('zoomend', callback).flyTo(newCenter, newZoom);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -39,7 +39,7 @@ L.Control.Attribution = L.Control.extend({
|
||||
},
|
||||
|
||||
addAttribution: function (text) {
|
||||
if (!text) { return; }
|
||||
if (!text) { return this; }
|
||||
|
||||
if (!this._attributions[text]) {
|
||||
this._attributions[text] = 0;
|
||||
@ -52,7 +52,7 @@ L.Control.Attribution = L.Control.extend({
|
||||
},
|
||||
|
||||
removeAttribution: function (text) {
|
||||
if (!text) { return; }
|
||||
if (!text) { return this; }
|
||||
|
||||
if (this._attributions[text]) {
|
||||
this._attributions[text]--;
|
||||
|
@ -123,7 +123,7 @@ L.Control.Layers = L.Control.extend({
|
||||
},
|
||||
|
||||
_update: function () {
|
||||
if (!this._container) { return; }
|
||||
if (!this._container) { return this; }
|
||||
|
||||
L.DomUtil.empty(this._baseLayersList);
|
||||
L.DomUtil.empty(this._overlaysList);
|
||||
|
@ -31,12 +31,28 @@ L.Control.Zoom = L.Control.extend({
|
||||
map.off('zoomend zoomlevelschange', this._updateDisabled, this);
|
||||
},
|
||||
|
||||
disable: function () {
|
||||
this._disabled = true;
|
||||
this._updateDisabled();
|
||||
return this;
|
||||
},
|
||||
|
||||
enable: function () {
|
||||
this._disabled = false;
|
||||
this._updateDisabled();
|
||||
return this;
|
||||
},
|
||||
|
||||
_zoomIn: function (e) {
|
||||
this._map.zoomIn(e.shiftKey ? 3 : 1);
|
||||
if (!this._disabled) {
|
||||
this._map.zoomIn(e.shiftKey ? 3 : 1);
|
||||
}
|
||||
},
|
||||
|
||||
_zoomOut: function (e) {
|
||||
this._map.zoomOut(e.shiftKey ? 3 : 1);
|
||||
if (!this._disabled) {
|
||||
this._map.zoomOut(e.shiftKey ? 3 : 1);
|
||||
}
|
||||
},
|
||||
|
||||
_createButton: function (html, title, className, container, fn) {
|
||||
@ -61,10 +77,10 @@ L.Control.Zoom = L.Control.extend({
|
||||
L.DomUtil.removeClass(this._zoomInButton, className);
|
||||
L.DomUtil.removeClass(this._zoomOutButton, className);
|
||||
|
||||
if (map._zoom === map.getMinZoom()) {
|
||||
if (this._disabled || map._zoom === map.getMinZoom()) {
|
||||
L.DomUtil.addClass(this._zoomOutButton, className);
|
||||
}
|
||||
if (map._zoom === map.getMaxZoom()) {
|
||||
if (this._disabled || map._zoom === map.getMaxZoom()) {
|
||||
L.DomUtil.addClass(this._zoomInButton, className);
|
||||
}
|
||||
}
|
||||
@ -84,4 +100,3 @@ L.Map.addInitHook(function () {
|
||||
L.control.zoom = function (options) {
|
||||
return new L.Control.Zoom(options);
|
||||
};
|
||||
|
||||
|
@ -71,8 +71,9 @@ L.Control = L.Class.extend({
|
||||
return this;
|
||||
},
|
||||
|
||||
_refocusOnMap: function () {
|
||||
if (this._map) {
|
||||
_refocusOnMap: function (e) {
|
||||
// if map exists and event is not a keyboard event
|
||||
if (this._map && e && e.screenX > 0 && e.screenY > 0) {
|
||||
this._map.getContainer().focus();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
Leaflet {VERSION}, a JS library for interactive maps. http://leafletjs.com
|
||||
(c) 2010-2014 Vladimir Agafonkin, (c) 2010-2011 CloudMade
|
||||
(c) 2010-2015 Vladimir Agafonkin, (c) 2010-2011 CloudMade
|
||||
*/
|
||||
|
@ -19,7 +19,6 @@ L.Class.extend = function (props) {
|
||||
this.callInitHooks();
|
||||
};
|
||||
|
||||
// jshint camelcase: false
|
||||
var parentProto = NewClass.__super__ = this.prototype;
|
||||
|
||||
var proto = L.Util.create(parentProto);
|
||||
@ -27,7 +26,7 @@ L.Class.extend = function (props) {
|
||||
|
||||
NewClass.prototype = proto;
|
||||
|
||||
//inherit parent's statics
|
||||
// inherit parent's statics
|
||||
for (var i in this) {
|
||||
if (this.hasOwnProperty(i) && i !== 'prototype') {
|
||||
NewClass[i] = this[i];
|
||||
|
@ -134,8 +134,8 @@ L.Evented = L.Class.extend({
|
||||
events = this._events;
|
||||
|
||||
if (events) {
|
||||
var typeIndex = events[type + '_idx'],
|
||||
i, len, listeners, id;
|
||||
var typeIndex = events[type + '_idx'],
|
||||
i, len, listeners, id;
|
||||
|
||||
if (events[type]) {
|
||||
// make sure adding/removing listeners inside other listeners won't cause infinite loop
|
||||
|
@ -42,9 +42,10 @@ L.Util = {
|
||||
|
||||
// return unique ID of an object
|
||||
stamp: function (obj) {
|
||||
// jshint camelcase: false
|
||||
/*eslint-disable */
|
||||
obj._leaflet_id = obj._leaflet_id || ++L.Util.lastId;
|
||||
return obj._leaflet_id;
|
||||
/*eslint-enable */
|
||||
},
|
||||
|
||||
lastId: 0,
|
||||
@ -116,7 +117,7 @@ L.Util = {
|
||||
return obj.options;
|
||||
},
|
||||
|
||||
// make an URL with GET parameters out of a set of properties/values
|
||||
// make a URL with GET parameters out of a set of properties/values
|
||||
getParamString: function (obj, existingUrl, uppercase) {
|
||||
var params = [];
|
||||
for (var i in obj) {
|
||||
|
@ -54,7 +54,7 @@ L.DomEvent = {
|
||||
|
||||
if (L.Browser.pointer && type.indexOf('touch') === 0) {
|
||||
this.addPointerListener(obj, type, handler, id);
|
||||
|
||||
|
||||
} else if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) {
|
||||
this.addDoubleTapListener(obj, handler, id);
|
||||
|
||||
@ -67,8 +67,9 @@ L.DomEvent = {
|
||||
} else if ((type === 'mouseenter') || (type === 'mouseleave')) {
|
||||
handler = function (e) {
|
||||
e = e || window.event;
|
||||
if (!L.DomEvent._checkMouse(obj, e)) { return; }
|
||||
return originalHandler(e);
|
||||
if (L.DomEvent._checkMouse(obj, e)) {
|
||||
originalHandler(e);
|
||||
}
|
||||
};
|
||||
obj.addEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false);
|
||||
|
||||
@ -240,7 +241,7 @@ L.DomEvent = {
|
||||
}
|
||||
L.DomEvent._lastClick = timeStamp;
|
||||
|
||||
return handler(e);
|
||||
handler(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -100,27 +100,30 @@ L.DomUtil = {
|
||||
el.style.opacity = value;
|
||||
|
||||
} else if ('filter' in el.style) {
|
||||
L.DomUtil._setOpacityIE(el, value);
|
||||
}
|
||||
},
|
||||
|
||||
var filter = false,
|
||||
filterName = 'DXImageTransform.Microsoft.Alpha';
|
||||
_setOpacityIE: function (el, value) {
|
||||
var filter = false,
|
||||
filterName = 'DXImageTransform.Microsoft.Alpha';
|
||||
|
||||
// filters collection throws an error if we try to retrieve a filter that doesn't exist
|
||||
try {
|
||||
filter = el.filters.item(filterName);
|
||||
} catch (e) {
|
||||
// don't set opacity to 1 if we haven't already set an opacity,
|
||||
// it isn't needed and breaks transparent pngs.
|
||||
if (value === 1) { return; }
|
||||
}
|
||||
// filters collection throws an error if we try to retrieve a filter that doesn't exist
|
||||
try {
|
||||
filter = el.filters.item(filterName);
|
||||
} catch (e) {
|
||||
// don't set opacity to 1 if we haven't already set an opacity,
|
||||
// it isn't needed and breaks transparent pngs.
|
||||
if (value === 1) { return; }
|
||||
}
|
||||
|
||||
value = Math.round(value * 100);
|
||||
value = Math.round(value * 100);
|
||||
|
||||
if (filter) {
|
||||
filter.Enabled = (value !== 100);
|
||||
filter.Opacity = value;
|
||||
} else {
|
||||
el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')';
|
||||
}
|
||||
if (filter) {
|
||||
filter.Enabled = (value !== 100);
|
||||
filter.Opacity = value;
|
||||
} else {
|
||||
el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')';
|
||||
}
|
||||
},
|
||||
|
||||
@ -145,8 +148,9 @@ L.DomUtil = {
|
||||
|
||||
setPosition: function (el, point, no3d) { // (HTMLElement, Point[, Boolean])
|
||||
|
||||
// jshint camelcase: false
|
||||
/*eslint-disable */
|
||||
el._leaflet_pos = point;
|
||||
/*eslint-enable */
|
||||
|
||||
if (L.Browser.any3d && !no3d) {
|
||||
L.DomUtil.setTransform(el, point);
|
||||
@ -160,7 +164,6 @@ L.DomUtil = {
|
||||
// this method is only used for elements previously positioned using setPosition,
|
||||
// so it's safe to cache the position for performance
|
||||
|
||||
// jshint camelcase: false
|
||||
return el._leaflet_pos;
|
||||
}
|
||||
};
|
||||
@ -216,4 +219,19 @@ L.DomUtil = {
|
||||
L.DomUtil.enableImageDrag = function () {
|
||||
L.DomEvent.off(window, 'dragstart', L.DomEvent.preventDefault);
|
||||
};
|
||||
|
||||
L.DomUtil.preventOutline = function (element) {
|
||||
L.DomUtil.restoreOutline();
|
||||
this._outlineElement = element;
|
||||
this._outlineStyle = element.style.outline;
|
||||
element.style.outline = 'none';
|
||||
L.DomEvent.on(window, 'keydown', L.DomUtil.restoreOutline, this);
|
||||
};
|
||||
L.DomUtil.restoreOutline = function () {
|
||||
if (!this._outlineElement) { return; }
|
||||
this._outlineElement.style.outline = this._outlineStyle;
|
||||
delete this._outlineElement;
|
||||
delete this._outlineStyle;
|
||||
L.DomEvent.off(window, 'keydown', L.DomUtil.restoreOutline, this);
|
||||
};
|
||||
})();
|
||||
|
@ -20,9 +20,10 @@ L.Draggable = L.Evented.extend({
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function (element, dragStartTarget) {
|
||||
initialize: function (element, dragStartTarget, preventOutline) {
|
||||
this._element = element;
|
||||
this._dragStartTarget = dragStartTarget || element;
|
||||
this._preventOutline = preventOutline;
|
||||
},
|
||||
|
||||
enable: function () {
|
||||
@ -45,10 +46,14 @@ L.Draggable = L.Evented.extend({
|
||||
_onDown: function (e) {
|
||||
this._moved = false;
|
||||
|
||||
if (e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; }
|
||||
if (e.shiftKey || ((e.which !== 1) && (e.button !== 0) && !e.touches)) { return; }
|
||||
|
||||
L.DomEvent.stopPropagation(e);
|
||||
|
||||
if (this._preventOutline) {
|
||||
L.DomUtil.preventOutline(this._element);
|
||||
}
|
||||
|
||||
if (L.DomUtil.hasClass(this._element, 'leaflet-zoom-anim')) { return; }
|
||||
|
||||
L.DomUtil.disableImageDrag();
|
||||
@ -99,13 +104,15 @@ L.Draggable = L.Evented.extend({
|
||||
this._moving = true;
|
||||
|
||||
L.Util.cancelAnimFrame(this._animRequest);
|
||||
this._lastEvent = e;
|
||||
this._animRequest = L.Util.requestAnimFrame(this._updatePosition, this, true, this._dragStartTarget);
|
||||
},
|
||||
|
||||
_updatePosition: function () {
|
||||
this.fire('predrag');
|
||||
var e = {originalEvent: this._lastEvent};
|
||||
this.fire('predrag', e);
|
||||
L.DomUtil.setPosition(this._element, this._newPos);
|
||||
this.fire('drag');
|
||||
this.fire('drag', e);
|
||||
},
|
||||
|
||||
_onUp: function () {
|
||||
|
@ -80,4 +80,3 @@ L.latLng = function (a, b, c) {
|
||||
}
|
||||
return new L.LatLng(a, b, c);
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,7 @@ L.CRS.Earth = L.extend({}, L.CRS, {
|
||||
|
||||
R: 6378137,
|
||||
|
||||
// distane between two geographical points using spherical law of cosines approximation
|
||||
// distance between two geographical points using spherical law of cosines approximation
|
||||
distance: function (latlng1, latlng2) {
|
||||
var rad = Math.PI / 180,
|
||||
lat1 = latlng1.lat * rad,
|
||||
|
@ -3,14 +3,12 @@
|
||||
* and polylines (clipping, simplification, distances, etc.)
|
||||
*/
|
||||
|
||||
/*jshint bitwise:false */ // allow bitwise operations for this file
|
||||
|
||||
L.LineUtil = {
|
||||
|
||||
// Simplify polyline with vertex reduction and Douglas-Peucker simplification.
|
||||
// Improves rendering performance dramatically by lessening the number of points to draw.
|
||||
|
||||
simplify: function (/*Point[]*/ points, /*Number*/ tolerance) {
|
||||
simplify: function (points, tolerance) {
|
||||
if (!tolerance || !points.length) {
|
||||
return points.slice();
|
||||
}
|
||||
@ -27,11 +25,11 @@ L.LineUtil = {
|
||||
},
|
||||
|
||||
// distance from a point to a segment between two points
|
||||
pointToSegmentDistance: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
|
||||
pointToSegmentDistance: function (p, p1, p2) {
|
||||
return Math.sqrt(this._sqClosestPointOnSegment(p, p1, p2, true));
|
||||
},
|
||||
|
||||
closestPointOnSegment: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
|
||||
closestPointOnSegment: function (p, p1, p2) {
|
||||
return this._sqClosestPointOnSegment(p, p1, p2);
|
||||
},
|
||||
|
||||
@ -99,7 +97,7 @@ L.LineUtil = {
|
||||
// Cohen-Sutherland line clipping algorithm.
|
||||
// Used to avoid rendering parts of a polyline that are not currently visible.
|
||||
|
||||
clipSegment: function (a, b, bounds, useLastCode) {
|
||||
clipSegment: function (a, b, bounds, useLastCode, round) {
|
||||
var codeA = useLastCode ? this._lastCode : this._getBitCode(a, bounds),
|
||||
codeB = this._getBitCode(b, bounds),
|
||||
|
||||
@ -118,7 +116,7 @@ L.LineUtil = {
|
||||
// other cases
|
||||
} else {
|
||||
codeOut = codeA || codeB;
|
||||
p = this._getEdgeIntersection(a, b, codeOut, bounds);
|
||||
p = this._getEdgeIntersection(a, b, codeOut, bounds, round);
|
||||
newCode = this._getBitCode(p, bounds);
|
||||
|
||||
if (codeOut === codeA) {
|
||||
@ -132,7 +130,7 @@ L.LineUtil = {
|
||||
}
|
||||
},
|
||||
|
||||
_getEdgeIntersection: function (a, b, code, bounds) {
|
||||
_getEdgeIntersection: function (a, b, code, bounds, round) {
|
||||
var dx = b.x - a.x,
|
||||
dy = b.y - a.y,
|
||||
min = bounds.min,
|
||||
@ -156,7 +154,7 @@ L.LineUtil = {
|
||||
y = a.y + dy * (min.x - a.x) / dx;
|
||||
}
|
||||
|
||||
return new L.Point(x, y, true);
|
||||
return new L.Point(x, y, round);
|
||||
},
|
||||
|
||||
_getBitCode: function (/*Point*/ p, bounds) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
* L.Point represents a point with x and y coordinates.
|
||||
*/
|
||||
|
||||
L.Point = function (/*Number*/ x, /*Number*/ y, /*Boolean*/ round) {
|
||||
L.Point = function (x, y, round) {
|
||||
this.x = (round ? Math.round(x) : x);
|
||||
this.y = (round ? Math.round(y) : y);
|
||||
};
|
||||
|
@ -2,15 +2,13 @@
|
||||
* L.PolyUtil contains utility functions for polygons (clipping, etc.).
|
||||
*/
|
||||
|
||||
/*jshint bitwise:false */ // allow bitwise operations here
|
||||
|
||||
L.PolyUtil = {};
|
||||
|
||||
/*
|
||||
* Sutherland-Hodgeman polygon clipping algorithm.
|
||||
* Used to avoid rendering parts of a polygon that are not currently visible.
|
||||
*/
|
||||
L.PolyUtil.clipPolygon = function (points, bounds) {
|
||||
L.PolyUtil.clipPolygon = function (points, bounds, round) {
|
||||
var clippedPoints,
|
||||
edges = [1, 4, 2, 8],
|
||||
i, j, k,
|
||||
@ -35,7 +33,7 @@ L.PolyUtil.clipPolygon = function (points, bounds) {
|
||||
if (!(a._code & edge)) {
|
||||
// if b is outside the clip window (a->b goes out of screen)
|
||||
if (b._code & edge) {
|
||||
p = lu._getEdgeIntersection(b, a, edge, bounds);
|
||||
p = lu._getEdgeIntersection(b, a, edge, bounds, round);
|
||||
p._code = lu._getBitCode(p, bounds);
|
||||
clippedPoints.push(p);
|
||||
}
|
||||
@ -43,7 +41,7 @@ L.PolyUtil.clipPolygon = function (points, bounds) {
|
||||
|
||||
// else if b is inside the clip window (a->b enters the screen)
|
||||
} else if (!(b._code & edge)) {
|
||||
p = lu._getEdgeIntersection(b, a, edge, bounds);
|
||||
p = lu._getEdgeIntersection(b, a, edge, bounds, round);
|
||||
p._code = lu._getBitCode(p, bounds);
|
||||
clippedPoints.push(p);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ L.GeoJSON = L.FeatureGroup.extend({
|
||||
|
||||
var options = this.options;
|
||||
|
||||
if (options.filter && !options.filter(geojson)) { return; }
|
||||
if (options.filter && !options.filter(geojson)) { return this; }
|
||||
|
||||
var layer = L.GeoJSON.geometryToLayer(geojson, options);
|
||||
layer.feature = L.GeoJSON.asFeature(geojson);
|
||||
@ -146,7 +146,7 @@ L.extend(L.GeoJSON, {
|
||||
|
||||
for (var i = 0, len = latlngs.length; i < len; i++) {
|
||||
coords.push(levelsDeep ?
|
||||
L.GeoJSON.latLngsToCoords(latlngs[i], levelsDeep - 1, closed):
|
||||
L.GeoJSON.latLngsToCoords(latlngs[i], levelsDeep - 1, closed) :
|
||||
L.GeoJSON.latLngToCoords(latlngs[i]));
|
||||
}
|
||||
|
||||
|
@ -26,13 +26,20 @@ L.ImageOverlay = L.Layer.extend({
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.interactive) {
|
||||
L.DomUtil.addClass(this._image, 'leaflet-interactive');
|
||||
this.addInteractiveTarget(this._image);
|
||||
}
|
||||
|
||||
this.getPane().appendChild(this._image);
|
||||
this._initInteraction();
|
||||
this._reset();
|
||||
},
|
||||
|
||||
onRemove: function () {
|
||||
L.DomUtil.remove(this._image);
|
||||
if (this.options.interactive) {
|
||||
this.removeInteractiveTarget(this._image);
|
||||
}
|
||||
},
|
||||
|
||||
setOpacity: function (opacity) {
|
||||
@ -65,19 +72,6 @@ L.ImageOverlay = L.Layer.extend({
|
||||
return this;
|
||||
},
|
||||
|
||||
_initInteraction: function () {
|
||||
if (!this.options.interactive) { return; }
|
||||
L.DomUtil.addClass(this._image, 'leaflet-interactive');
|
||||
L.DomEvent.on(this._image, 'click dblclick mousedown mouseup mouseover mousemove mouseout contextmenu',
|
||||
this._fireMouseEvent, this);
|
||||
},
|
||||
|
||||
_fireMouseEvent: function (e, type) {
|
||||
if (this._map) {
|
||||
this._map._fireMouseEvent(this, e, type, true);
|
||||
}
|
||||
},
|
||||
|
||||
setUrl: function (url) {
|
||||
this._url = url;
|
||||
|
||||
|
@ -7,6 +7,7 @@ L.Layer.include({
|
||||
bindPopup: function (content, options) {
|
||||
|
||||
if (content instanceof L.Popup) {
|
||||
L.setOptions(content, options);
|
||||
this._popup = content;
|
||||
content._source = this;
|
||||
} else {
|
||||
@ -124,4 +125,4 @@ L.Layer.include({
|
||||
_popupLatLng: function(){
|
||||
return this._latlng || this.getCenter();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -25,6 +25,16 @@ L.Layer = L.Evented.extend({
|
||||
return this._map.getPane(name ? (this.options[name] || name) : this.options.pane);
|
||||
},
|
||||
|
||||
addInteractiveTarget: function (targetEl) {
|
||||
this._map._targets[L.stamp(targetEl)] = this;
|
||||
return this;
|
||||
},
|
||||
|
||||
removeInteractiveTarget: function (targetEl) {
|
||||
delete this._map._targets[L.stamp(targetEl)];
|
||||
return this;
|
||||
},
|
||||
|
||||
_layerAdd: function (e) {
|
||||
var map = e.target;
|
||||
|
||||
|
@ -11,7 +11,7 @@ L.Handler.MarkerDrag = L.Handler.extend({
|
||||
var icon = this._marker._icon;
|
||||
|
||||
if (!this._draggable) {
|
||||
this._draggable = new L.Draggable(icon, icon);
|
||||
this._draggable = new L.Draggable(icon, icon, true);
|
||||
}
|
||||
|
||||
this._draggable.on({
|
||||
@ -30,7 +30,9 @@ L.Handler.MarkerDrag = L.Handler.extend({
|
||||
dragend: this._onDragEnd
|
||||
}, this).disable();
|
||||
|
||||
L.DomUtil.removeClass(this._marker._icon, 'leaflet-marker-draggable');
|
||||
if (this._marker._icon) {
|
||||
L.DomUtil.removeClass(this._marker._icon, 'leaflet-marker-draggable');
|
||||
}
|
||||
},
|
||||
|
||||
moved: function () {
|
||||
@ -44,7 +46,7 @@ L.Handler.MarkerDrag = L.Handler.extend({
|
||||
.fire('dragstart');
|
||||
},
|
||||
|
||||
_onDrag: function () {
|
||||
_onDrag: function (e) {
|
||||
var marker = this._marker,
|
||||
shadow = marker._shadow,
|
||||
iconPos = L.DomUtil.getPosition(marker._icon),
|
||||
@ -56,10 +58,11 @@ L.Handler.MarkerDrag = L.Handler.extend({
|
||||
}
|
||||
|
||||
marker._latlng = latlng;
|
||||
e.latlng = latlng;
|
||||
|
||||
marker
|
||||
.fire('move', {latlng: latlng})
|
||||
.fire('drag');
|
||||
.fire('move', e)
|
||||
.fire('drag', e);
|
||||
},
|
||||
|
||||
_onDragEnd: function (e) {
|
||||
|
@ -32,8 +32,8 @@ L.Marker = L.Layer.extend({
|
||||
},
|
||||
|
||||
onRemove: function () {
|
||||
if (this.dragging) {
|
||||
this.dragging.disable();
|
||||
if (this.dragging && this.dragging.enabled()) {
|
||||
this.dragging.removeHooks();
|
||||
}
|
||||
|
||||
this._removeIcon();
|
||||
@ -58,7 +58,7 @@ L.Marker = L.Layer.extend({
|
||||
var oldLatLng = this._latlng;
|
||||
this._latlng = L.latLng(latlng);
|
||||
this.update();
|
||||
return this.fire('move', { oldLatLng: oldLatLng, latlng: this._latlng });
|
||||
return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng});
|
||||
},
|
||||
|
||||
setZIndexOffset: function (offset) {
|
||||
@ -123,11 +123,11 @@ L.Marker = L.Layer.extend({
|
||||
this._icon = icon;
|
||||
this._initInteraction();
|
||||
|
||||
if (L.DomEvent && options.riseOnHover) {
|
||||
L.DomEvent.on(icon, {
|
||||
if (options.riseOnHover) {
|
||||
this.on({
|
||||
mouseover: this._bringToFront,
|
||||
mouseout: this._resetZIndex
|
||||
}, this);
|
||||
});
|
||||
}
|
||||
|
||||
var newShadow = options.icon.createShadow(this._shadow),
|
||||
@ -158,14 +158,15 @@ L.Marker = L.Layer.extend({
|
||||
},
|
||||
|
||||
_removeIcon: function () {
|
||||
if (L.DomEvent && this.options.riseOnHover) {
|
||||
L.DomEvent.off(this._icon, {
|
||||
if (this.options.riseOnHover) {
|
||||
this.off({
|
||||
mouseover: this._bringToFront,
|
||||
mouseout: this._resetZIndex
|
||||
}, this);
|
||||
});
|
||||
}
|
||||
|
||||
L.DomUtil.remove(this._icon);
|
||||
this.removeInteractiveTarget(this._icon);
|
||||
|
||||
this._icon = null;
|
||||
},
|
||||
@ -205,11 +206,7 @@ L.Marker = L.Layer.extend({
|
||||
|
||||
L.DomUtil.addClass(this._icon, 'leaflet-interactive');
|
||||
|
||||
if (L.DomEvent) {
|
||||
L.DomEvent.on(this._icon,
|
||||
'click dblclick mousedown mouseup mouseover mousemove mouseout contextmenu keypress',
|
||||
this._fireMouseEvent, this);
|
||||
}
|
||||
this.addInteractiveTarget(this._icon);
|
||||
|
||||
if (L.Handler.MarkerDrag) {
|
||||
var draggable = this.options.draggable;
|
||||
@ -226,21 +223,6 @@ L.Marker = L.Layer.extend({
|
||||
}
|
||||
},
|
||||
|
||||
_fireMouseEvent: function (e, type) {
|
||||
// to prevent outline when clicking on keyboard-focusable marker
|
||||
if (e.type === 'mousedown') {
|
||||
L.DomEvent.preventDefault(e);
|
||||
}
|
||||
|
||||
if (e.type === 'keypress' && e.keyCode === 13) {
|
||||
type = 'click';
|
||||
}
|
||||
|
||||
if (this._map) {
|
||||
this._map._fireMouseEvent(this, e, type, true, this._latlng);
|
||||
}
|
||||
},
|
||||
|
||||
setOpacity: function (opacity) {
|
||||
this.options.opacity = opacity;
|
||||
if (this._map) {
|
||||
|
@ -10,7 +10,6 @@ L.GridLayer = L.Layer.extend({
|
||||
tileSize: 256,
|
||||
opacity: 1,
|
||||
|
||||
unloadInvisibleTiles: L.Browser.mobile,
|
||||
updateWhenIdle: L.Browser.mobile,
|
||||
updateInterval: 200,
|
||||
|
||||
@ -29,16 +28,10 @@ L.GridLayer = L.Layer.extend({
|
||||
onAdd: function () {
|
||||
this._initContainer();
|
||||
|
||||
this._pruneTiles = L.Util.throttle(this._pruneTiles, 200, this);
|
||||
|
||||
this._levels = {};
|
||||
|
||||
this._tiles = {};
|
||||
this._loaded = {};
|
||||
this._retain = {};
|
||||
this._tilesToLoad = 0;
|
||||
|
||||
this._reset();
|
||||
this._viewReset();
|
||||
this._update();
|
||||
},
|
||||
|
||||
@ -103,13 +96,13 @@ L.GridLayer = L.Layer.extend({
|
||||
|
||||
getEvents: function () {
|
||||
var events = {
|
||||
viewreset: this._reset,
|
||||
moveend: this._update
|
||||
viewreset: this._viewReset,
|
||||
moveend: this._move
|
||||
};
|
||||
|
||||
if (!this.options.updateWhenIdle) {
|
||||
// update tiles on move, but not more often than once per given interval
|
||||
events.move = L.Util.throttle(this._update, this.options.updateInterval, this);
|
||||
events.move = L.Util.throttle(this._move, this.options.updateInterval, this);
|
||||
}
|
||||
|
||||
if (this._zoomAnimated) {
|
||||
@ -153,13 +146,33 @@ L.GridLayer = L.Layer.extend({
|
||||
_updateOpacity: function () {
|
||||
var opacity = this.options.opacity;
|
||||
|
||||
if (L.Browser.ielt9) {
|
||||
// IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
|
||||
for (var i in this._tiles) {
|
||||
L.DomUtil.setOpacity(this._tiles[i], opacity);
|
||||
}
|
||||
} else {
|
||||
// IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
|
||||
if (!L.Browser.ielt9 && !this._map._fadeAnimated) {
|
||||
L.DomUtil.setOpacity(this._container, opacity);
|
||||
return;
|
||||
}
|
||||
|
||||
var now = +new Date(),
|
||||
nextFrame = false;
|
||||
|
||||
for (var key in this._tiles) {
|
||||
var tile = this._tiles[key];
|
||||
if (!tile.current || !tile.loaded || tile.active) { continue; }
|
||||
|
||||
var fade = Math.min(1, (now - tile.loaded) / 200);
|
||||
if (fade < 1) {
|
||||
L.DomUtil.setOpacity(tile.el, opacity * fade);
|
||||
nextFrame = true;
|
||||
} else {
|
||||
L.DomUtil.setOpacity(tile.el, opacity);
|
||||
tile.active = true;
|
||||
this._pruneTiles();
|
||||
}
|
||||
}
|
||||
|
||||
if (nextFrame) {
|
||||
L.Util.cancelAnimFrame(this._fadeFrame);
|
||||
this._fadeFrame = L.Util.requestAnimFrame(this._updateOpacity, this);
|
||||
}
|
||||
},
|
||||
|
||||
@ -177,10 +190,16 @@ L.GridLayer = L.Layer.extend({
|
||||
},
|
||||
|
||||
_updateLevels: function () {
|
||||
var zoom = this._tileZoom;
|
||||
var zoom = this._tileZoom,
|
||||
maxZoom = this.options.maxZoom;
|
||||
|
||||
for (var z in this._levels) {
|
||||
this._levels[z].el.style.zIndex = -Math.abs(zoom - z);
|
||||
if (this._levels[z].el.children.length || z === zoom) {
|
||||
this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z);
|
||||
} else {
|
||||
L.DomUtil.remove(this._levels[z].el);
|
||||
delete this._levels[z];
|
||||
}
|
||||
}
|
||||
|
||||
var level = this._levels[zoom],
|
||||
@ -190,10 +209,15 @@ L.GridLayer = L.Layer.extend({
|
||||
level = this._levels[zoom] = {};
|
||||
|
||||
level.el = L.DomUtil.create('div', 'leaflet-tile-container leaflet-zoom-animated', this._container);
|
||||
level.el.style.zIndex = 0;
|
||||
level.el.style.zIndex = maxZoom;
|
||||
|
||||
level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round();
|
||||
level.zoom = zoom;
|
||||
|
||||
this._setZoomTransform(level, map.getCenter(), map.getZoom());
|
||||
|
||||
// force the browser to consider the newly added element for transition
|
||||
L.Util.falseFn(level.el.offsetWidth);
|
||||
}
|
||||
|
||||
this._level = level;
|
||||
@ -202,39 +226,26 @@ L.GridLayer = L.Layer.extend({
|
||||
},
|
||||
|
||||
_pruneTiles: function () {
|
||||
var key, tile;
|
||||
|
||||
if (!this._map) { return; }
|
||||
for (key in this._tiles) {
|
||||
tile = this._tiles[key];
|
||||
tile.retain = tile.current;
|
||||
}
|
||||
|
||||
this._retain = {};
|
||||
|
||||
var bounds = this._map.getBounds(),
|
||||
z = this._tileZoom,
|
||||
range = this._getTileRange(bounds, z),
|
||||
i, j, key, found;
|
||||
|
||||
for (i = range.min.x; i <= range.max.x; i++) {
|
||||
for (j = range.min.y; j <= range.max.y; j++) {
|
||||
|
||||
key = i + ':' + j + ':' + z;
|
||||
|
||||
this._retain[key] = true;
|
||||
|
||||
if (!this._loaded[key]) {
|
||||
found = this._retainParent(i, j, z, z - 5) || this._retainChildren(i, j, z, z + 2);
|
||||
for (key in this._tiles) {
|
||||
tile = this._tiles[key];
|
||||
if (tile.current && !tile.active) {
|
||||
var coords = tile.coords;
|
||||
if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) {
|
||||
this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (key in this._tiles) {
|
||||
if (!this._retain[key]) {
|
||||
if (!this._loaded[key]) {
|
||||
this._removeTile(key);
|
||||
this._tilesToLoad--;
|
||||
} else if (this._map._fadeAnimated) {
|
||||
setTimeout(L.bind(this._deferRemove, this, key), 250);
|
||||
} else {
|
||||
this._removeTile(key);
|
||||
}
|
||||
if (!this._tiles[key].retain) {
|
||||
this._removeTile(key);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -243,13 +254,6 @@ L.GridLayer = L.Layer.extend({
|
||||
for (var key in this._tiles) {
|
||||
this._removeTile(key);
|
||||
}
|
||||
this._tilesToLoad = 0;
|
||||
},
|
||||
|
||||
_deferRemove: function (key) {
|
||||
if (!this._retain[key]) {
|
||||
this._removeTile(key);
|
||||
}
|
||||
},
|
||||
|
||||
_retainParent: function (x, y, z, minZoom) {
|
||||
@ -257,13 +261,18 @@ L.GridLayer = L.Layer.extend({
|
||||
y2 = Math.floor(y / 2),
|
||||
z2 = z - 1;
|
||||
|
||||
var key = x2 + ':' + y2 + ':' + z2;
|
||||
var key = x2 + ':' + y2 + ':' + z2,
|
||||
tile = this._tiles[key];
|
||||
|
||||
if (this._loaded[key]) {
|
||||
this._retain[key] = true;
|
||||
if (tile && tile.active) {
|
||||
tile.retain = true;
|
||||
return true;
|
||||
|
||||
} else if (z2 > minZoom) {
|
||||
} else if (tile && tile.loaded) {
|
||||
tile.retain = true;
|
||||
}
|
||||
|
||||
if (z2 > minZoom) {
|
||||
return this._retainParent(x2, y2, z2, minZoom);
|
||||
}
|
||||
|
||||
@ -275,34 +284,56 @@ L.GridLayer = L.Layer.extend({
|
||||
for (var i = 2 * x; i < 2 * x + 2; i++) {
|
||||
for (var j = 2 * y; j < 2 * y + 2; j++) {
|
||||
|
||||
var key = i + ':' + j + ':' + (z + 1);
|
||||
var key = i + ':' + j + ':' + (z + 1),
|
||||
tile = this._tiles[key];
|
||||
|
||||
if (this._loaded[key]) {
|
||||
this._retain[key] = true;
|
||||
if (tile && tile.active) {
|
||||
tile.retain = true;
|
||||
continue;
|
||||
|
||||
} else if (z + 1 < maxZoom) {
|
||||
} else if (tile && tile.loaded) {
|
||||
tile.retain = true;
|
||||
}
|
||||
|
||||
if (z + 1 < maxZoom) {
|
||||
this._retainChildren(i, j, z + 1, maxZoom);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_reset: function (e) {
|
||||
var map = this._map,
|
||||
zoom = map.getZoom(),
|
||||
tileZoom = Math.round(zoom),
|
||||
tileZoomChanged = this._tileZoom !== tileZoom;
|
||||
_viewReset: function (e) {
|
||||
this._reset(this._map.getCenter(), this._map.getZoom(), e && e.hard);
|
||||
},
|
||||
|
||||
_animateZoom: function (e) {
|
||||
this._reset(e.center, e.zoom, false, true, e.noUpdate);
|
||||
},
|
||||
|
||||
_reset: function (center, zoom, hard, noPrune, noUpdate) {
|
||||
var tileZoom = Math.round(zoom),
|
||||
tileZoomChanged = this._tileZoom !== tileZoom;
|
||||
|
||||
if (!noUpdate && (hard || tileZoomChanged)) {
|
||||
|
||||
if (tileZoomChanged || (e && e.hard)) {
|
||||
if (this._abortLoading) {
|
||||
this._abortLoading();
|
||||
}
|
||||
|
||||
this._tileZoom = tileZoom;
|
||||
this._updateLevels();
|
||||
this._resetGrid();
|
||||
|
||||
if (!L.Browser.mobileWebkit) {
|
||||
this._update(center, tileZoom);
|
||||
}
|
||||
|
||||
if (!noPrune) {
|
||||
this._pruneTiles();
|
||||
}
|
||||
}
|
||||
|
||||
this._setZoomTransforms(map.getCenter(), zoom);
|
||||
this._setZoomTransforms(center, zoom);
|
||||
},
|
||||
|
||||
_setZoomTransforms: function (center, zoom) {
|
||||
@ -344,8 +375,14 @@ L.GridLayer = L.Layer.extend({
|
||||
return this.options.tileSize;
|
||||
},
|
||||
|
||||
_update: function () {
|
||||
if (!this._map) { return; }
|
||||
_move: function () {
|
||||
this._update();
|
||||
this._pruneTiles();
|
||||
},
|
||||
|
||||
_update: function (center, zoom) {
|
||||
var map = this._map;
|
||||
if (!map) { return; }
|
||||
|
||||
// TODO move to reset
|
||||
// var zoom = this._map.getZoom();
|
||||
@ -353,38 +390,30 @@ L.GridLayer = L.Layer.extend({
|
||||
// if (zoom > this.options.maxZoom ||
|
||||
// zoom < this.options.minZoom) { return; }
|
||||
|
||||
var bounds = this._map.getBounds();
|
||||
if (center === undefined) { center = map.getCenter(); }
|
||||
if (zoom === undefined) { zoom = Math.round(map.getZoom()); }
|
||||
|
||||
if (this.options.unloadInvisibleTiles) {
|
||||
this._removeOtherTiles(bounds);
|
||||
var pixelBounds = map.getPixelBounds(center, zoom),
|
||||
tileRange = this._pxBoundsToTileRange(pixelBounds),
|
||||
tileCenter = tileRange.getCenter(),
|
||||
queue = [];
|
||||
|
||||
for (var key in this._tiles) {
|
||||
this._tiles[key].current = false;
|
||||
}
|
||||
|
||||
this._addTiles(bounds);
|
||||
},
|
||||
|
||||
// tile coordinates range for particular geo bounds and zoom
|
||||
_getTileRange: function (bounds, zoom) {
|
||||
var pxBounds = new L.Bounds(
|
||||
this._map.project(bounds.getNorthWest(), zoom),
|
||||
this._map.project(bounds.getSouthEast(), zoom));
|
||||
return this._pxBoundsToTileRange(pxBounds);
|
||||
},
|
||||
|
||||
_addTiles: function (bounds) {
|
||||
var queue = [],
|
||||
tileRange = this._getTileRange(bounds, this._tileZoom),
|
||||
center = tileRange.getCenter(),
|
||||
j, i, coords;
|
||||
|
||||
// create a queue of coordinates to load tiles from
|
||||
for (j = tileRange.min.y; j <= tileRange.max.y; j++) {
|
||||
for (i = tileRange.min.x; i <= tileRange.max.x; i++) {
|
||||
for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
|
||||
for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
|
||||
var coords = new L.Point(i, j);
|
||||
coords.z = zoom;
|
||||
|
||||
coords = new L.Point(i, j);
|
||||
coords.z = this._tileZoom;
|
||||
if (!this._isValidTile(coords)) { continue; }
|
||||
|
||||
// add tile to queue if it's not in cache or out of bounds
|
||||
if (!(this._tileCoordsToKey(coords) in this._tiles) && this._isValidTile(coords)) {
|
||||
var tile = this._tiles[this._tileCoordsToKey(coords)];
|
||||
if (tile) {
|
||||
tile.current = true;
|
||||
} else {
|
||||
queue.push(coords);
|
||||
}
|
||||
}
|
||||
@ -392,31 +421,24 @@ L.GridLayer = L.Layer.extend({
|
||||
|
||||
// sort tile queue to load tiles in order of their distance to center
|
||||
queue.sort(function (a, b) {
|
||||
return a.distanceTo(center) - b.distanceTo(center);
|
||||
return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
|
||||
});
|
||||
|
||||
var tilesToLoad = queue.length;
|
||||
|
||||
|
||||
if (tilesToLoad !== 0) {
|
||||
if (queue.length !== 0) {
|
||||
// if its the first batch of tiles to load
|
||||
if (!this._tilesToLoad) {
|
||||
if (this._noTilesToLoad()) {
|
||||
this.fire('loading');
|
||||
}
|
||||
|
||||
this._tilesToLoad += tilesToLoad;
|
||||
|
||||
// create DOM fragment to append tiles in one batch
|
||||
var fragment = document.createDocumentFragment();
|
||||
|
||||
for (i = 0; i < tilesToLoad; i++) {
|
||||
for (i = 0; i < queue.length; i++) {
|
||||
this._addTile(queue[i], fragment);
|
||||
}
|
||||
|
||||
this._level.el.appendChild(fragment);
|
||||
}
|
||||
|
||||
this._pruneTiles();
|
||||
},
|
||||
|
||||
_isValidTile: function (coords) {
|
||||
@ -468,27 +490,16 @@ L.GridLayer = L.Layer.extend({
|
||||
return coords;
|
||||
},
|
||||
|
||||
// remove any present tiles that are off the specified bounds
|
||||
_removeOtherTiles: function (bounds) {
|
||||
for (var key in this._tiles) {
|
||||
var tileBounds = this._keyToBounds(key);
|
||||
if (!bounds.intersects(tileBounds)) {
|
||||
this._removeTile(key);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_removeTile: function (key) {
|
||||
var tile = this._tiles[key];
|
||||
if (!tile) { return; }
|
||||
|
||||
L.DomUtil.remove(tile);
|
||||
L.DomUtil.remove(tile.el);
|
||||
|
||||
delete this._tiles[key];
|
||||
delete this._loaded[key];
|
||||
|
||||
this.fire('tileunload', {
|
||||
tile: tile,
|
||||
tile: tile.el,
|
||||
coords: this._keyToTileCoords(key)
|
||||
});
|
||||
},
|
||||
@ -534,7 +545,11 @@ L.GridLayer = L.Layer.extend({
|
||||
L.DomUtil.setPosition(tile, tilePos, true);
|
||||
|
||||
// save tile in cache
|
||||
this._tiles[key] = tile;
|
||||
this._tiles[key] = {
|
||||
el: tile,
|
||||
coords: coords,
|
||||
current: true
|
||||
};
|
||||
|
||||
container.appendChild(tile);
|
||||
this.fire('tileloadstart', {
|
||||
@ -544,6 +559,8 @@ L.GridLayer = L.Layer.extend({
|
||||
},
|
||||
|
||||
_tileReady: function (coords, err, tile) {
|
||||
if (!this._map) { return; }
|
||||
|
||||
if (err) {
|
||||
this.fire('tileerror', {
|
||||
error: err,
|
||||
@ -554,21 +571,27 @@ L.GridLayer = L.Layer.extend({
|
||||
|
||||
var key = this._tileCoordsToKey(coords);
|
||||
|
||||
if (!this._tiles[key]) { return; }
|
||||
tile = this._tiles[key];
|
||||
if (!tile) { return; }
|
||||
|
||||
this._loaded[key] = true;
|
||||
this._pruneTiles();
|
||||
tile.loaded = +new Date();
|
||||
if (this._map._fadeAnimated) {
|
||||
L.DomUtil.setOpacity(tile.el, 0);
|
||||
L.Util.cancelAnimFrame(this._fadeFrame);
|
||||
this._fadeFrame = L.Util.requestAnimFrame(this._updateOpacity, this);
|
||||
} else {
|
||||
tile.active = true;
|
||||
this._pruneTiles();
|
||||
}
|
||||
|
||||
L.DomUtil.addClass(tile, 'leaflet-tile-loaded');
|
||||
L.DomUtil.addClass(tile.el, 'leaflet-tile-loaded');
|
||||
|
||||
this.fire('tileload', {
|
||||
tile: tile,
|
||||
tile: tile.el,
|
||||
coords: coords
|
||||
});
|
||||
|
||||
this._tilesToLoad--;
|
||||
|
||||
if (this._tilesToLoad === 0) {
|
||||
if (this._noTilesToLoad()) {
|
||||
this.fire('load');
|
||||
}
|
||||
},
|
||||
@ -591,8 +614,11 @@ L.GridLayer = L.Layer.extend({
|
||||
bounds.max.divideBy(this._tileSize).ceil().subtract([1, 1]));
|
||||
},
|
||||
|
||||
_animateZoom: function (e) {
|
||||
this._setZoomTransforms(e.center, e.zoom);
|
||||
_noTilesToLoad: function () {
|
||||
for (var key in this._tiles) {
|
||||
if (!this._tiles[key].loaded) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -99,18 +99,17 @@ L.TileLayer = L.GridLayer.extend({
|
||||
_getTileSize: function () {
|
||||
var map = this._map,
|
||||
options = this.options,
|
||||
zoom = map.getZoom() + options.zoomOffset,
|
||||
zoom = this._tileZoom + options.zoomOffset,
|
||||
zoomN = options.maxNativeZoom;
|
||||
|
||||
// increase tile size when overscaling
|
||||
return zoomN !== null && zoom > zoomN ?
|
||||
Math.round(map.getZoomScale(zoomN, zoom) * options.tileSize) :
|
||||
Math.round(options.tileSize / map.getZoomScale(zoomN, zoom)) :
|
||||
options.tileSize;
|
||||
},
|
||||
|
||||
_onTileRemove: function (e) {
|
||||
e.tile.onload = null;
|
||||
e.tile.src = L.Util.emptyImageUrl;
|
||||
},
|
||||
|
||||
_getZoomForUrl: function () {
|
||||
@ -136,7 +135,7 @@ L.TileLayer = L.GridLayer.extend({
|
||||
_abortLoading: function () {
|
||||
var i, tile;
|
||||
for (i in this._tiles) {
|
||||
tile = this._tiles[i];
|
||||
tile = this._tiles[i].el;
|
||||
|
||||
tile.onload = L.Util.falseFn;
|
||||
tile.onerror = L.Util.falseFn;
|
||||
|
@ -114,7 +114,7 @@ L.Canvas = L.Renderer.extend({
|
||||
len = parts.length,
|
||||
ctx = this._ctx;
|
||||
|
||||
if (!len) { return; }
|
||||
if (!len) { return; }
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
@ -169,7 +169,7 @@ L.Canvas = L.Renderer.extend({
|
||||
ctx.fill(options.fillRule || 'evenodd');
|
||||
}
|
||||
|
||||
if (options.stroke) {
|
||||
if (options.stroke && options.weight !== 0) {
|
||||
ctx.globalAlpha = clear ? 1 : options.opacity;
|
||||
|
||||
// if clearing shape, do it with the previously drawn line width
|
||||
@ -190,7 +190,8 @@ L.Canvas = L.Renderer.extend({
|
||||
|
||||
for (var id in this._layers) {
|
||||
if (this._layers[id]._containsPoint(point)) {
|
||||
this._layers[id]._fireMouseEvent(e);
|
||||
L.DomEvent._fakeStop(e);
|
||||
this._fireEvent(this._layers[id], e);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -213,20 +214,24 @@ L.Canvas = L.Renderer.extend({
|
||||
// if we just got inside the layer, fire mouseover
|
||||
if (!layer._mouseInside) {
|
||||
L.DomUtil.addClass(this._container, 'leaflet-interactive'); // change cursor
|
||||
layer._fireMouseEvent(e, 'mouseover');
|
||||
this._fireEvent(layer, e, 'mouseover');
|
||||
layer._mouseInside = true;
|
||||
}
|
||||
// fire mousemove
|
||||
layer._fireMouseEvent(e);
|
||||
this._fireEvent(layer, e);
|
||||
|
||||
} else if (layer._mouseInside) {
|
||||
// if we're leaving the layer, fire mouseout
|
||||
L.DomUtil.removeClass(this._container, 'leaflet-interactive');
|
||||
layer._fireMouseEvent(e, 'mouseout');
|
||||
this._fireEvent(layer, e, 'mouseout');
|
||||
layer._mouseInside = false;
|
||||
}
|
||||
},
|
||||
|
||||
_fireEvent: function (layer, e, type) {
|
||||
this._map._fireDOMEvent(layer, e, type || e.type);
|
||||
},
|
||||
|
||||
// TODO _bringToFront & _bringToBack, pretty tricky
|
||||
|
||||
_bringToFront: L.Util.falseFn,
|
||||
|
@ -74,10 +74,6 @@ L.Path = L.Layer.extend({
|
||||
return this;
|
||||
},
|
||||
|
||||
_fireMouseEvent: function (e, type) {
|
||||
this._map._fireMouseEvent(this, e, type, true);
|
||||
},
|
||||
|
||||
_clickTolerance: function () {
|
||||
// used when doing hit detection for Canvas layers
|
||||
return (this.options.stroke ? this.options.weight / 2 : 0) + (L.Browser.touch ? 10 : 0);
|
||||
|
@ -58,7 +58,7 @@ L.Polygon = L.Polyline.extend({
|
||||
this._parts = [];
|
||||
|
||||
for (var i = 0, len = this._rings.length, clipped; i < len; i++) {
|
||||
clipped = L.PolyUtil.clipPolygon(this._rings[i], bounds);
|
||||
clipped = L.PolyUtil.clipPolygon(this._rings[i], bounds, true);
|
||||
if (clipped.length) {
|
||||
this._parts.push(clipped);
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ L.Polyline = L.Path.extend({
|
||||
points = this._rings[i];
|
||||
|
||||
for (j = 0, len2 = points.length; j < len2 - 1; j++) {
|
||||
segment = L.LineUtil.clipSegment(points[j], points[j + 1], bounds, j);
|
||||
segment = L.LineUtil.clipSegment(points[j], points[j + 1], bounds, j, true);
|
||||
|
||||
if (!segment) { continue; }
|
||||
|
||||
|
@ -64,7 +64,7 @@ L.Renderer = L.Layer.extend({
|
||||
L.Map.include({
|
||||
// used by each vector layer to decide which renderer to use
|
||||
getRenderer: function (layer) {
|
||||
var renderer = layer.options.renderer || this.options.renderer || this._renderer;
|
||||
var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer;
|
||||
|
||||
if (!renderer) {
|
||||
renderer = this._renderer = (L.SVG && L.svg()) || (L.Canvas && L.canvas());
|
||||
@ -74,5 +74,18 @@ L.Map.include({
|
||||
this.addLayer(renderer);
|
||||
}
|
||||
return renderer;
|
||||
},
|
||||
|
||||
_getPaneRenderer: function (name) {
|
||||
if (name === 'overlayPane' || name === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var renderer = this._paneRenderers[name];
|
||||
if (renderer === undefined) {
|
||||
renderer = (L.SVG && L.svg({pane: name})) || (L.Canvas && L.canvas({pane: name}));
|
||||
this._paneRenderers[name] = renderer;
|
||||
}
|
||||
return renderer;
|
||||
}
|
||||
});
|
||||
|
@ -7,9 +7,6 @@ L.SVG = L.Renderer.extend({
|
||||
_initContainer: function () {
|
||||
this._container = L.SVG.create('svg');
|
||||
|
||||
this._paths = {};
|
||||
this._initEvents();
|
||||
|
||||
// makes it possible to click through svg root; we'll reset it back in individual paths
|
||||
this._container.setAttribute('pointer-events', 'none');
|
||||
},
|
||||
@ -54,15 +51,13 @@ L.SVG = L.Renderer.extend({
|
||||
},
|
||||
|
||||
_addPath: function (layer) {
|
||||
var path = layer._path;
|
||||
this._container.appendChild(path);
|
||||
this._paths[L.stamp(path)] = layer;
|
||||
this._container.appendChild(layer._path);
|
||||
layer.addInteractiveTarget(layer._path);
|
||||
},
|
||||
|
||||
_removePath: function (layer) {
|
||||
var path = layer._path;
|
||||
L.DomUtil.remove(path);
|
||||
delete this._paths[L.stamp(path)];
|
||||
L.DomUtil.remove(layer._path);
|
||||
layer.removeInteractiveTarget(layer._path);
|
||||
},
|
||||
|
||||
_updatePath: function (layer) {
|
||||
@ -122,7 +117,7 @@ L.SVG = L.Renderer.extend({
|
||||
// drawing a circle with two half-arcs
|
||||
var d = layer._empty() ? 'M0 0' :
|
||||
'M' + (p.x - r) + ',' + p.y +
|
||||
arc + (r * 2) + ',0 ' +
|
||||
arc + (r * 2) + ',0 ' +
|
||||
arc + (-r * 2) + ',0 ';
|
||||
|
||||
this._setPath(layer, d);
|
||||
@ -139,19 +134,6 @@ L.SVG = L.Renderer.extend({
|
||||
|
||||
_bringToBack: function (layer) {
|
||||
L.DomUtil.toBack(layer._path);
|
||||
},
|
||||
|
||||
// TODO remove duplication with L.Map
|
||||
_initEvents: function () {
|
||||
L.DomEvent.on(this._container, 'click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu',
|
||||
this._fireMouseEvent, this);
|
||||
},
|
||||
|
||||
_fireMouseEvent: function (e) {
|
||||
var path = this._paths[L.stamp(e.target || e.srcElement)];
|
||||
if (path) {
|
||||
path._fireMouseEvent(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -220,7 +220,7 @@ L.Map = L.Evented.extend({
|
||||
|
||||
remove: function () {
|
||||
|
||||
this._initEvents('off');
|
||||
this._initEvents(true);
|
||||
|
||||
try {
|
||||
// throws error in IE6-8
|
||||
@ -328,8 +328,8 @@ L.Map = L.Evented.extend({
|
||||
return this._size.clone();
|
||||
},
|
||||
|
||||
getPixelBounds: function () {
|
||||
var topLeftPoint = this._getTopLeftPoint();
|
||||
getPixelBounds: function (center, zoom) {
|
||||
var topLeftPoint = this._getTopLeftPoint(center, zoom);
|
||||
return new L.Bounds(topLeftPoint, topLeftPoint.add(this.getSize()));
|
||||
},
|
||||
|
||||
@ -470,6 +470,7 @@ L.Map = L.Evented.extend({
|
||||
|
||||
_initPanes: function () {
|
||||
var panes = this._panes = {};
|
||||
this._paneRenderers = {};
|
||||
|
||||
this._mapPane = this.createPane('mapPane', this._container);
|
||||
|
||||
@ -545,16 +546,17 @@ L.Map = L.Evented.extend({
|
||||
}
|
||||
},
|
||||
|
||||
// map events
|
||||
// DOM event handling
|
||||
|
||||
_initEvents: function (onOff) {
|
||||
_initEvents: function (remove) {
|
||||
if (!L.DomEvent) { return; }
|
||||
|
||||
onOff = onOff || 'on';
|
||||
this._targets = {};
|
||||
|
||||
L.DomEvent[onOff](this._container,
|
||||
'click dblclick mousedown mouseup mouseenter mouseleave mousemove contextmenu',
|
||||
this._handleMouseEvent, this);
|
||||
var onOff = remove ? 'off' : 'on';
|
||||
|
||||
L.DomEvent[onOff](this._container, 'click dblclick mousedown mouseup ' +
|
||||
'mouseover mouseout mousemove contextmenu keypress', this._handleDOMEvent, this);
|
||||
|
||||
if (this.options.trackResize) {
|
||||
L.DomEvent[onOff](window, 'resize', this._onResize, this);
|
||||
@ -567,46 +569,53 @@ L.Map = L.Evented.extend({
|
||||
function () { this.invalidateSize({debounceMoveend: true}); }, this, false, this._container);
|
||||
},
|
||||
|
||||
_handleMouseEvent: function (e) {
|
||||
if (!this._loaded) { return; }
|
||||
_handleDOMEvent: function (e) {
|
||||
if (!this._loaded || L.DomEvent._skipped(e)) { return; }
|
||||
|
||||
this._fireMouseEvent(this, e,
|
||||
e.type === 'mouseenter' ? 'mouseover' :
|
||||
e.type === 'mouseleave' ? 'mouseout' : e.type);
|
||||
},
|
||||
// find the layer the event is propagating from
|
||||
var target = this._targets[L.stamp(e.target || e.srcElement)],
|
||||
type = e.type === 'keypress' && e.keyCode === 13 ? 'click' : e.type;
|
||||
|
||||
_fireMouseEvent: function (obj, e, type, propagate, latlng) {
|
||||
type = type || e.type;
|
||||
// special case for map mouseover/mouseout events so that they're actually mouseenter/mouseleave
|
||||
if (!target && (type === 'mouseover' || type === 'mouseout') &&
|
||||
!L.DomEvent._checkMouse(this._container, e)) { return; }
|
||||
|
||||
if (L.DomEvent._skipped(e)) { return; }
|
||||
if (type === 'click') {
|
||||
var draggableObj = obj.options.draggable === true ? obj : this;
|
||||
if (!e._simulated && ((draggableObj.dragging && draggableObj.dragging.moved()) ||
|
||||
(this.boxZoom && this.boxZoom.moved()))) {
|
||||
L.DomEvent.stopPropagation(e);
|
||||
return;
|
||||
}
|
||||
obj.fire('preclick');
|
||||
// prevents outline when clicking on keyboard-focusable element
|
||||
if (type === 'mousedown') {
|
||||
L.DomUtil.preventOutline(e.target || e.srcElement);
|
||||
}
|
||||
|
||||
if (!obj.listens(type, propagate)) { return; }
|
||||
this._fireDOMEvent(target || this, e, type);
|
||||
},
|
||||
|
||||
_fireDOMEvent: function (target, e, type) {
|
||||
if (!target.listens(type, true) && (type !== 'click' || !target.listens('preclick', true))) { return; }
|
||||
|
||||
if (type === 'contextmenu') {
|
||||
L.DomEvent.preventDefault(e);
|
||||
}
|
||||
if (type === 'click' || type === 'dblclick' || type === 'contextmenu') {
|
||||
L.DomEvent.stopPropagation(e);
|
||||
}
|
||||
|
||||
// prevents firing click after you just dragged an object
|
||||
if (e.type === 'click' && !e._simulated && this._draggableMoved(target)) { return; }
|
||||
|
||||
var data = {
|
||||
originalEvent: e,
|
||||
containerPoint: this.mouseEventToContainerPoint(e)
|
||||
originalEvent: e
|
||||
};
|
||||
if (e.type !== 'keypress') {
|
||||
data.containerPoint = target instanceof L.Marker ?
|
||||
this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e);
|
||||
data.layerPoint = this.containerPointToLayerPoint(data.containerPoint);
|
||||
data.latlng = this.layerPointToLatLng(data.layerPoint);
|
||||
}
|
||||
if (type === 'click') {
|
||||
target.fire('preclick', data, true);
|
||||
}
|
||||
target.fire(type, data, true);
|
||||
},
|
||||
|
||||
data.layerPoint = this.containerPointToLayerPoint(data.containerPoint);
|
||||
data.latlng = latlng || this.layerPointToLatLng(data.layerPoint);
|
||||
|
||||
obj.fire(type, data, propagate);
|
||||
_draggableMoved: function (obj) {
|
||||
obj = obj.options.draggable ? obj : this;
|
||||
return (obj.dragging && obj.dragging.moved()) || (this.boxZoom && this.boxZoom.moved());
|
||||
},
|
||||
|
||||
_clearHandlers: function () {
|
||||
@ -636,8 +645,11 @@ L.Map = L.Evented.extend({
|
||||
return pos && !pos.equals([0, 0]);
|
||||
},
|
||||
|
||||
_getTopLeftPoint: function () {
|
||||
return this.getPixelOrigin().subtract(this._getMapPanePos());
|
||||
_getTopLeftPoint: function (center, zoom) {
|
||||
var pixelOrigin = center && zoom !== undefined ?
|
||||
this._getNewPixelOrigin(center, zoom) :
|
||||
this.getPixelOrigin();
|
||||
return pixelOrigin.subtract(this._getMapPanePos());
|
||||
},
|
||||
|
||||
_getNewPixelOrigin: function (center, zoom) {
|
||||
|
@ -9,6 +9,7 @@ L.Map.include({
|
||||
size = this.getSize(),
|
||||
startZoom = this._zoom;
|
||||
|
||||
targetCenter = L.latLng(targetCenter);
|
||||
targetZoom = targetZoom === undefined ? startZoom : targetZoom;
|
||||
|
||||
var w0 = Math.max(size.x, size.y),
|
||||
|
@ -96,6 +96,6 @@ L.Map.include({
|
||||
|
||||
this.panBy(offset, options);
|
||||
|
||||
return true;
|
||||
return (options && options.animate) !== false;
|
||||
}
|
||||
});
|
||||
|
@ -34,7 +34,15 @@ L.Map.include(!zoomAnimated ? {} : {
|
||||
this._panes.mapPane.appendChild(proxy);
|
||||
|
||||
this.on('zoomanim', function (e) {
|
||||
var prop = L.DomUtil.TRANSFORM,
|
||||
transform = proxy.style[prop];
|
||||
|
||||
L.DomUtil.setTransform(proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1));
|
||||
|
||||
// workaround for case when transform is the same and so transitionend event is not fired
|
||||
if (transform === proxy.style[prop] && this._animatingZoom) {
|
||||
this._onZoomTransitionEnd();
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.on('load moveend', function () {
|
||||
@ -81,7 +89,7 @@ L.Map.include(!zoomAnimated ? {} : {
|
||||
return true;
|
||||
},
|
||||
|
||||
_animateZoom: function (center, zoom, startAnim) {
|
||||
_animateZoom: function (center, zoom, startAnim, noUpdate) {
|
||||
if (startAnim) {
|
||||
this._animatingZoom = true;
|
||||
|
||||
@ -97,7 +105,8 @@ L.Map.include(!zoomAnimated ? {} : {
|
||||
zoom: zoom,
|
||||
scale: this.getZoomScale(zoom),
|
||||
origin: this.latLngToLayerPoint(center),
|
||||
offset: this._getCenterOffset(center).multiplyBy(-1)
|
||||
offset: this._getCenterOffset(center).multiplyBy(-1),
|
||||
noUpdate: noUpdate
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -14,7 +14,7 @@ L.Map.include({
|
||||
|
||||
locate: function (/*Object*/ options) {
|
||||
|
||||
options = this._locateOptions = L.extend(this._defaultLocateOptions, options);
|
||||
options = this._locateOptions = L.extend({}, this._defaultLocateOptions, options);
|
||||
|
||||
if (!navigator.geolocation) {
|
||||
this._handleGeolocationError({
|
||||
|
@ -27,7 +27,7 @@ L.Map.BoxZoom = L.Handler.extend({
|
||||
},
|
||||
|
||||
_onMouseDown: function (e) {
|
||||
if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
|
||||
if (!e.shiftKey || ((e.which !== 1) && (e.button !== 0))) { return false; }
|
||||
|
||||
this._moved = false;
|
||||
|
||||
@ -83,7 +83,7 @@ L.Map.BoxZoom = L.Handler.extend({
|
||||
},
|
||||
|
||||
_onMouseUp: function (e) {
|
||||
if ((e.which !== 1) && (e.button !== 1)) { return false; }
|
||||
if ((e.which !== 1) && (e.button !== 0)) { return; }
|
||||
|
||||
this._finish();
|
||||
|
||||
|
@ -8,7 +8,6 @@ L.Map.mergeOptions({
|
||||
inertia: !L.Browser.android23,
|
||||
inertiaDeceleration: 3400, // px/s^2
|
||||
inertiaMaxSpeed: Infinity, // px/s
|
||||
inertiaThreshold: L.Browser.touch ? 32 : 18, // ms
|
||||
easeLinearity: 0.2,
|
||||
|
||||
// TODO refactor, move to CRS
|
||||
@ -64,7 +63,7 @@ L.Map.Drag = L.Handler.extend({
|
||||
}
|
||||
},
|
||||
|
||||
_onDrag: function () {
|
||||
_onDrag: function (e) {
|
||||
if (this._map.options.inertia) {
|
||||
var time = this._lastTime = +new Date(),
|
||||
pos = this._lastPos = this._draggable._absPos || this._draggable._newPos;
|
||||
@ -72,15 +71,15 @@ L.Map.Drag = L.Handler.extend({
|
||||
this._positions.push(pos);
|
||||
this._times.push(time);
|
||||
|
||||
if (time - this._times[0] > 100) {
|
||||
if (time - this._times[0] > 50) {
|
||||
this._positions.shift();
|
||||
this._times.shift();
|
||||
}
|
||||
}
|
||||
|
||||
this._map
|
||||
.fire('move')
|
||||
.fire('drag');
|
||||
.fire('move', e)
|
||||
.fire('drag', e);
|
||||
},
|
||||
|
||||
_onViewReset: function () {
|
||||
@ -108,9 +107,8 @@ L.Map.Drag = L.Handler.extend({
|
||||
_onDragEnd: function (e) {
|
||||
var map = this._map,
|
||||
options = map.options,
|
||||
delay = +new Date() - this._lastTime,
|
||||
|
||||
noInertia = !options.inertia || delay > options.inertiaThreshold || !this._positions[0];
|
||||
noInertia = !options.inertia || this._times.length < 2;
|
||||
|
||||
map.fire('dragend', e);
|
||||
|
||||
@ -120,7 +118,7 @@ L.Map.Drag = L.Handler.extend({
|
||||
} else {
|
||||
|
||||
var direction = this._lastPos.subtract(this._positions[0]),
|
||||
duration = (this._lastTime + delay - this._times[0]) / 1000,
|
||||
duration = (this._lastTime - this._times[0]) / 1000,
|
||||
ease = options.easeLinearity,
|
||||
|
||||
speedVector = direction.multiplyBy(ease / duration),
|
||||
|
@ -35,14 +35,14 @@ L.Map.Keyboard = L.Handler.extend({
|
||||
}
|
||||
|
||||
L.DomEvent.on(container, {
|
||||
focus: this._onFocus,
|
||||
blur: this._onBlur,
|
||||
mousedown: this._onMouseDown
|
||||
focus: this._onFocus,
|
||||
blur: this._onBlur,
|
||||
mousedown: this._onMouseDown
|
||||
}, this);
|
||||
|
||||
this._map.on({
|
||||
focus: this._addHooks,
|
||||
blur: this._removeHooks
|
||||
blur: this._removeHooks
|
||||
}, this);
|
||||
},
|
||||
|
||||
@ -50,14 +50,14 @@ L.Map.Keyboard = L.Handler.extend({
|
||||
this._removeHooks();
|
||||
|
||||
L.DomEvent.off(this._map._container, {
|
||||
focus: this._onFocus,
|
||||
blur: this._onBlur,
|
||||
mousedown: this._onMouseDown
|
||||
focus: this._onFocus,
|
||||
blur: this._onBlur,
|
||||
mousedown: this._onMouseDown
|
||||
}, this);
|
||||
|
||||
this._map.off({
|
||||
focus: this._addHooks,
|
||||
blur: this._removeHooks
|
||||
blur: this._removeHooks
|
||||
}, this);
|
||||
},
|
||||
|
||||
|
@ -48,7 +48,7 @@ L.Map.Tap = L.Handler.extend({
|
||||
this._simulateEvent('contextmenu', first);
|
||||
}
|
||||
}, this), 1000);
|
||||
|
||||
|
||||
this._simulateEvent('mousedown', first);
|
||||
|
||||
L.DomEvent.on(document, {
|
||||
@ -73,7 +73,7 @@ L.Map.Tap = L.Handler.extend({
|
||||
if (el && el.tagName && el.tagName.toLowerCase() === 'a') {
|
||||
L.DomUtil.removeClass(el, 'leaflet-active');
|
||||
}
|
||||
|
||||
|
||||
this._simulateEvent('mouseup', first);
|
||||
|
||||
// simulate click if the touch didn't move too much
|
||||
|
@ -80,9 +80,12 @@ L.Map.TouchZoom = L.Handler.extend({
|
||||
} else {
|
||||
this._center = map.layerPointToLatLng(this._getTargetCenter());
|
||||
}
|
||||
|
||||
this._zoom = map.getScaleZoom(this._scale);
|
||||
|
||||
map._animateZoom(this._center, this._zoom);
|
||||
if (this._scale !== 1 || this._delta.x !== 0 || this._delta.y !== 0) {
|
||||
map._animateZoom(this._center, this._zoom, false, true);
|
||||
}
|
||||
},
|
||||
|
||||
_onTouchEnd: function () {
|
||||
@ -103,7 +106,7 @@ L.Map.TouchZoom = L.Handler.extend({
|
||||
zoomDelta = this._zoom - oldZoom,
|
||||
finalZoom = map._limitZoom(zoomDelta > 0 ? Math.ceil(this._zoom) : Math.floor(this._zoom));
|
||||
|
||||
map._animateZoom(this._center, finalZoom, true);
|
||||
map._animateZoom(this._center, finalZoom, true, true);
|
||||
},
|
||||
|
||||
_getTargetCenter: function () {
|
||||
|
Loading…
Reference in New Issue
Block a user