Merge pull request #2377 from Leaflet/accel

Smarter hardware acceleration
This commit is contained in:
Vladimir Agafonkin 2014-01-28 03:22:31 -08:00
commit bce7c49c17
5 changed files with 25 additions and 14 deletions

10
dist/leaflet.css vendored
View File

@ -26,6 +26,16 @@
user-select: none; user-select: none;
-webkit-user-drag: none; -webkit-user-drag: none;
} }
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
image-rendering: -webkit-optimize-contrast;
}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
width: 1600px;
height: 1600px;
-webkit-transform-origin: 0 0;
}
.leaflet-marker-icon, .leaflet-marker-icon,
.leaflet-marker-shadow { .leaflet-marker-shadow {
display: block; display: block;

View File

@ -12,6 +12,7 @@
webkit = ua.indexOf('webkit') !== -1, webkit = ua.indexOf('webkit') !== -1,
phantomjs = ua.indexOf('phantom') !== -1, phantomjs = ua.indexOf('phantom') !== -1,
android23 = ua.search('android [23]') !== -1, android23 = ua.search('android [23]') !== -1,
chrome = ua.indexOf('chrome') !== -1,
mobile = typeof orientation !== 'undefined', mobile = typeof orientation !== 'undefined',
msPointer = navigator.msPointerEnabled && navigator.msMaxTouchPoints && !window.PointerEvent, msPointer = navigator.msPointerEnabled && navigator.msMaxTouchPoints && !window.PointerEvent,
@ -40,7 +41,8 @@
gecko: (ua.indexOf('gecko') !== -1) && !webkit && !window.opera && !ie, gecko: (ua.indexOf('gecko') !== -1) && !webkit && !window.opera && !ie,
android: ua.indexOf('android') !== -1, android: ua.indexOf('android') !== -1,
android23: android23, android23: android23,
chrome: ua.indexOf('chrome') !== -1, chrome: chrome,
safari: !chrome && ua.indexOf('safari') !== -1,
ie3d: ie3d, ie3d: ie3d,
webkit3d: webkit3d, webkit3d: webkit3d,

View File

@ -131,22 +131,18 @@ L.DomUtil = {
}, },
setTransform: function (el, offset, scale) { setTransform: function (el, offset, scale) {
var is3d = L.Browser.webkit3d, var pos = offset || new L.Point(0, 0);
pos = offset || new L.Point(0, 0);
el.style[L.DomUtil.TRANSFORM] = el.style[L.DomUtil.TRANSFORM] =
'translate' + (is3d ? '3d(' : '(') + pos.x + 'px,' + pos.y + 'px' + (is3d ? ',0)' : ')') + 'translate3d(' + pos.x + 'px,' + pos.y + 'px' + ',0)' + (scale ? ' scale(' + scale + ')' : '');
(scale ? ' scale(' + scale + ')' : '');
}, },
setPosition: function (el, point, disable3D) { // (HTMLElement, Point[, Boolean]) setPosition: function (el, point, no3d) { // (HTMLElement, Point[, Boolean])
// jshint camelcase: false // jshint camelcase: false
el._leaflet_pos = point; el._leaflet_pos = point;
if (!disable3D && L.Browser.any3d) { if (L.Browser.any3d && !no3d) {
// on WebKit browsers, using translate3d instead of translate makes animation smoother
// as it ensures HW acceleration is used. Firefox doesn't care (same speed either way).
L.DomUtil.setTransform(el, point); L.DomUtil.setTransform(el, point);
} else { } else {
el.style.left = point.x + 'px'; el.style.left = point.x + 'px';

View File

@ -171,6 +171,8 @@ L.GridLayer = L.Layer.extend({
this._bgBuffer = L.DomUtil.create('div', className, this._container); this._bgBuffer = L.DomUtil.create('div', className, this._container);
this._tileContainer = L.DomUtil.create('div', className, this._container); this._tileContainer = L.DomUtil.create('div', className, this._container);
L.DomUtil.setTransform(this._tileContainer);
} else { } else {
this._tileContainer = this._container; this._tileContainer = this._container;
} }
@ -297,6 +299,7 @@ L.GridLayer = L.Layer.extend({
for (i = 0; i < tilesToLoad; i++) { for (i = 0; i < tilesToLoad; i++) {
this._addTile(queue[i], fragment); this._addTile(queue[i], fragment);
} }
this._tileContainer.appendChild(fragment); this._tileContainer.appendChild(fragment);
}, },
@ -383,7 +386,7 @@ L.GridLayer = L.Layer.extend({
// without this hack, tiles disappear after zoom on Chrome for Android // without this hack, tiles disappear after zoom on Chrome for Android
// https://github.com/Leaflet/Leaflet/issues/2078 // https://github.com/Leaflet/Leaflet/issues/2078
if (L.Browser.mobileWebkit3d) { if (L.Browser.android && !L.Browser.android23) {
tile.style.WebkitBackfaceVisibility = 'hidden'; tile.style.WebkitBackfaceVisibility = 'hidden';
} }
}, },
@ -405,10 +408,9 @@ L.GridLayer = L.Layer.extend({
setTimeout(L.bind(this._tileReady, this, null, tile), 0); setTimeout(L.bind(this._tileReady, this, null, tile), 0);
} }
// Chrome 20 layouts much faster with top/left (verify with timeline, frames) // we prefer top/left over translate3d so that we don't create a HW-accelerated layer from each tile
// Android 4 browser has display issues with top/left and requires transform instead // which is slow, and it also fixes gaps between tiles in Safari
// (other browsers don't currently care) - see debug/hacks/jitter.html for an example L.DomUtil.setPosition(tile, tilePos, true);
L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome);
// save tile in cache // save tile in cache
this._tiles[this._tileCoordsToKey(coords)] = tile; this._tiles[this._tileCoordsToKey(coords)] = tile;

View File

@ -435,6 +435,7 @@ L.Map = L.Evented.extend({
(L.Browser.touch ? ' leaflet-touch' : '') + (L.Browser.touch ? ' leaflet-touch' : '') +
(L.Browser.retina ? ' leaflet-retina' : '') + (L.Browser.retina ? ' leaflet-retina' : '') +
(L.Browser.ielt9 ? ' leaflet-oldie' : '') + (L.Browser.ielt9 ? ' leaflet-oldie' : '') +
(L.Browser.safari ? ' leaflet-safari' : '') +
(this._fadeAnimated ? ' leaflet-fade-anim' : '')); (this._fadeAnimated ? ' leaflet-fade-anim' : ''));
var position = L.DomUtil.getStyle(container, 'position'); var position = L.DomUtil.getStyle(container, 'position');