diff --git a/examples/common/css/examples.css b/examples/common/css/examples.css index 2804a78433..57c8c30091 100644 --- a/examples/common/css/examples.css +++ b/examples/common/css/examples.css @@ -16,4 +16,5 @@ html, body { #map { width: 100%; height: calc(100% - 60px); + overflow: hidden; } diff --git a/package.json b/package.json index c1dec27c00..ec9ec217b2 100644 --- a/package.json +++ b/package.json @@ -62,12 +62,15 @@ "karma-webpack": "^1.7.0", "mousetrap": "^1.6.0", "node-fs-extra": "^0.8.1", + "nib": "^1.1.2", "node-resemble": "^1.1.3", "phantomjs-prebuilt": "^2.1.5", "proj4": "^2.3.14", "raw-body": "^2.1.6", "sinon": "1.17.3", "style-loader": "^0.13.1", + "stylus": "^0.54.5", + "stylus-loader": "^2.4.0", "url-loader": "^0.5.7", "vgl": "0.3.10", "webpack": "^1.12.14", diff --git a/src/annotationLayer.js b/src/annotationLayer.js index 93cf89a67d..9f4558fbdf 100644 --- a/src/annotationLayer.js +++ b/src/annotationLayer.js @@ -326,7 +326,7 @@ var annotationLayer = function (args) { var createAnnotation, actions, mapNode = m_this.map().node(), oldMode = m_mode; m_mode = arg; - mapNode.css('cursor', m_mode ? 'crosshair' : ''); + mapNode.toggleClass('annotation-input', !!m_mode); if (m_mode) { Mousetrap(mapNode[0]).bind('esc', function () { m_this.mode(null); }); } else { diff --git a/src/canvas/canvasRenderer.js b/src/canvas/canvasRenderer.js index f6bab2ce5b..1174f19a26 100644 --- a/src/canvas/canvasRenderer.js +++ b/src/canvas/canvasRenderer.js @@ -24,7 +24,6 @@ var canvasRenderer = function (arg) { renderer.call(this, arg); var m_this = this, - m_renderAnimFrameRef = null, m_clearCanvas = true, s_init = this._init, s_exit = this._exit; @@ -57,8 +56,7 @@ var canvasRenderer = function (arg) { var canvas = $(document.createElement('canvas')); m_this.context2d = canvas[0].getContext('2d'); - canvas.attr('class', 'canvas-canvas'); - canvas.css('display', 'block'); + canvas.addClass('canvas-canvas'); $(m_this.layer().node().get(0)).append(canvas); m_this.canvas(canvas); @@ -89,32 +87,35 @@ var canvasRenderer = function (arg) { */ //////////////////////////////////////////////////////////////////////////// this._render = function () { - if (m_renderAnimFrameRef === null) { - m_renderAnimFrameRef = window.requestAnimationFrame(function () { - m_renderAnimFrameRef = null; - - var layer = m_this.layer(), - map = layer.map(), - camera = map.camera(), - viewport = camera._viewport; - - // Clear the canvas. - if (m_clearCanvas) { - m_this.context2d.setTransform(1, 0, 0, 1, 0, 0); - m_this.context2d.clearRect(0, 0, viewport.width, viewport.height); - } - - var features = layer.features(); - for (var i = 0; i < features.length; i += 1) { - if (features[i].visible()) { - features[i]._renderOnCanvas(m_this.context2d, map); - } - } - }); - } + m_this.layer().map().scheduleAnimationFrame(this._renderFrame); return m_this; }; + //////////////////////////////////////////////////////////////////////////// + /** + * Render during an animation frame callback. + */ + //////////////////////////////////////////////////////////////////////////// + this._renderFrame = function () { + var layer = m_this.layer(), + map = layer.map(), + camera = map.camera(), + viewport = camera._viewport; + + // Clear the canvas. + if (m_clearCanvas) { + m_this.context2d.setTransform(1, 0, 0, 1, 0, 0); + m_this.context2d.clearRect(0, 0, viewport.width, viewport.height); + } + + var features = layer.features(); + for (var i = 0; i < features.length; i += 1) { + if (features[i].visible()) { + features[i]._renderOnCanvas(m_this.context2d, map); + } + } + }; + //////////////////////////////////////////////////////////////////////////// /** * Exit diff --git a/src/canvas/heatmapFeature.js b/src/canvas/heatmapFeature.js index 1ff1fc920d..85481c50f9 100644 --- a/src/canvas/heatmapFeature.js +++ b/src/canvas/heatmapFeature.js @@ -38,6 +38,7 @@ var canvas_heatmapFeature = function (arg) { m_typedClampedBuffer, m_typedBufferData, m_heatMapPosition, + m_heatMapTransform, s_exit = this._exit, s_init = this._init, s_update = this._update, @@ -349,7 +350,9 @@ var canvas_heatmapFeature = function (arg) { context2d.setTransform(1, 0, 0, 1, 0, 0); context2d.clearRect(0, 0, viewport.width, viewport.height); - layer.canvas().css({transform: '', 'transform-origin': '0px 0px'}); + m_heatMapTransform = ''; + map.scheduleAnimationFrame(m_this._setTransform, false); + layer.canvas().css({transform: ''}); m_this._createCircle(); m_this._computeGradient(); @@ -408,6 +411,16 @@ var canvas_heatmapFeature = function (arg) { return m_this; }; + //////////////////////////////////////////////////////////////////////////// + /** + * Update the css transform for the layer as part of an animation frame. + * @protected + */ + //////////////////////////////////////////////////////////////////////////// + this._setTransform = function () { + m_this.layer().canvas()[0].style.transform = m_heatMapTransform; + }; + //////////////////////////////////////////////////////////////////////////// /** * Animate pan (and zoom) @@ -434,8 +447,9 @@ var canvas_heatmapFeature = function (arg) { ' scale(' + scale + ')' + ' rotate(' + ((rotation - m_heatMapPosition.rotation) * 180 / Math.PI) + 'deg)'; - m_this.layer().canvas()[0].style.transform = transform; + map.scheduleAnimationFrame(m_this._setTransform); + m_heatMapTransform = transform; m_heatMapPosition.lastScale = scale; m_heatMapPosition.lastOrigin.x = origin.x; m_heatMapPosition.lastOrigin.y = origin.y; diff --git a/src/gl/vglRenderer.js b/src/gl/vglRenderer.js index 076a5a33b6..51cc9a0669 100644 --- a/src/gl/vglRenderer.js +++ b/src/gl/vglRenderer.js @@ -87,8 +87,7 @@ var vglRenderer = function (arg) { s_init.call(m_this); var canvas = $(document.createElement('canvas')); - canvas.attr('class', 'webgl-canvas'); - canvas.css('display', 'block'); + canvas.addClass('webgl-canvas'); $(m_this.layer().node().get(0)).append(canvas); if (window.contextPreserveDrawingBuffer) { diff --git a/src/index.js b/src/index.js index dfc38e7ce6..b49958d7d3 100644 --- a/src/index.js +++ b/src/index.js @@ -30,6 +30,8 @@ var $ = require('jquery'); require('./polyfills'); +require('./main.styl'); + module.exports = $.extend({ annotation: require('./annotation'), annotationLayer: require('./annotationLayer'), diff --git a/src/layer.js b/src/layer.js index c8f22c4197..74cf53a6ae 100644 --- a/src/layer.js +++ b/src/layer.js @@ -386,9 +386,7 @@ var layer = function (arg) { m_canvas = m_renderer.canvas(); } - if (!m_this.active()) { - m_node.css('pointerEvents', 'none'); - } + m_node.toggleClass('active', m_this.active()); m_initialized = true; @@ -481,10 +479,8 @@ var layer = function (arg) { // Create top level div for the layer m_node = $(document.createElement('div')); + m_node.addClass('geojs-layer'); m_node.attr('id', m_name); - m_node.css('position', 'absolute'); - m_node.css('width', '100%'); - m_node.css('height', '100%'); m_this.opacity(m_opacity); // set the z-index diff --git a/src/main.styl b/src/main.styl new file mode 100644 index 0000000000..801c804ec6 --- /dev/null +++ b/src/main.styl @@ -0,0 +1,47 @@ +@import '~nib/index.styl' + +.geojs-map + position relative + + .geo-attribution + position absolute + right 0px + bottom 0px + padding-right 5px + cursor auto + font 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif + z-index 1001 + background rgba(255,255,255,0.7) + clear both + display block + pointer-events auto + + .geo-attribution-layer + padding-left 5px + + .canvas-canvas + display block + transform-origin 0px 0px + .webgl-canvas + display block + + .geojs-layer + position absolute + width 100% + height 100% + pointer-events none + &.active + pointer-events auto + + .geo-tile-layer + transform-origin 0px 0px + line-height 0 + font-size 0 + + &.annotation-input + cursor crosshair + +.geo-tile-container + position absolute + &.crop + overflow hidden diff --git a/src/map.js b/src/map.js index 1eaa639815..adb21005ef 100644 --- a/src/map.js +++ b/src/map.js @@ -894,7 +894,7 @@ var map = function (arg) { throw 'Map require DIV node'; } - m_node.css('position', 'relative'); + m_node.addClass('geojs-map'); return m_this; }; @@ -1518,19 +1518,7 @@ var map = function (arg) { // generate a new attribution node var $a = $('
') .addClass('geo-attribution') - .css({ - position: 'absolute', - right: '0px', - bottom: '0px', - 'padding-right': '5px', - cursor: 'auto', - font: '11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif', - 'z-index': '1001', - background: 'rgba(255,255,255,0.7)', - clear: 'both', - display: 'block', - 'pointer-events': 'auto' - }).on('mousedown', function (evt) { + .on('mousedown', function (evt) { evt.stopPropagation(); }); @@ -1540,9 +1528,6 @@ var map = function (arg) { if (content) { $('') .addClass('geo-attribution-layer') - .css({ - 'padding-left': '5px' - }) .html(content) .appendTo($a); } diff --git a/src/tileLayer.js b/src/tileLayer.js index c61c6f587a..ac39d2a963 100644 --- a/src/tileLayer.js +++ b/src/tileLayer.js @@ -779,17 +779,15 @@ module.exports = (function () { // apply a transform to place the image correctly container.append(tile.image); container.css({ - position: 'absolute', left: (bounds.left - parseInt(div.attr('offsetx') || 0, 10)) + 'px', top: (bounds.top - parseInt(div.attr('offsety') || 0, 10)) + 'px' }); crop = this.tileCropFromBounds(tile); if (crop) { - container.css({ + container.addClass('crop').css({ width: crop.x + 'px', - height: crop.y + 'px', - overflow: 'hidden' + height: crop.y + 'px' }); } @@ -1005,11 +1003,7 @@ module.exports = (function () { if (!node) { node = $( '
' - ).css({ - 'transform-origin': '0px 0px', - 'line-height': 0, - 'font-size': 0 - }).get(0); + ).get(0); this.canvas().append(node); } return node; diff --git a/tests/cases/tileLayer.js b/tests/cases/tileLayer.js index ad2eb3c286..a4a1cc872b 100644 --- a/tests/cases/tileLayer.js +++ b/tests/cases/tileLayer.js @@ -1332,7 +1332,7 @@ describe('geo.tileLayer', function () { }); }); - describe('HTML renderering', function () { + describe('HTML rendering', function () { function layer_html(opts) { var node = $('