diff --git a/bundle.js b/bundle.js index b5a8915..a8f0d70 100644 --- a/bundle.js +++ b/bundle.js @@ -1,19 +1,15 @@ 'use strict'; function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } + if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayWithHoles(arr) { @@ -21,10 +17,11 @@ function _arrayWithHoles(arr) { } function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } function _iterableToArrayLimit(arr, i) { + if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; @@ -50,12 +47,29 @@ function _iterableToArrayLimit(arr, i) { return _arr; } +function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); +} + +function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; +} + function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var rgba = require('color-normalize'); @@ -143,6 +157,7 @@ function Scatter(regl, options) { var shaderOptions = { uniforms: { + constPointSize: !!options.constPointSize, pixelRatio: regl.context('pixelRatio'), palette: paletteTexture, paletteSize: function paletteSize(ctx, prop) { @@ -258,17 +273,17 @@ function Scatter(regl, options) { elements: regl.prop('elements'), count: regl.prop('count'), offset: regl.prop('offset'), - primitive: 'points' // draw sdf-marker + primitive: 'points' + }; // draw sdf-marker - }; var markerOptions = extend({}, shaderOptions); - markerOptions.frag = glslify(["precision highp float;\n#define GLSLIFY 1\n\nvarying vec4 fragColor, fragBorderColor;\nvarying float fragWidth, fragBorderColorLevel, fragColorLevel;\n\nuniform sampler2D marker;\nuniform float pixelRatio, opacity;\n\nfloat smoothStep(float x, float y) {\n return 1.0 / (1.0 + exp(50.0*(x - y)));\n}\n\nvoid main() {\n float dist = texture2D(marker, gl_PointCoord).r, delta = fragWidth;\n\n // max-distance alpha\n if (dist < 0.003) discard;\n\n // null-border case\n if (fragBorderColorLevel == fragColorLevel || fragBorderColor.a == 0.) {\n float colorAmt = smoothstep(.5 - delta, .5 + delta, dist);\n gl_FragColor = vec4(fragColor.rgb, colorAmt * fragColor.a * opacity);\n }\n else {\n float borderColorAmt = smoothstep(fragBorderColorLevel - delta, fragBorderColorLevel + delta, dist);\n float colorAmt = smoothstep(fragColorLevel - delta, fragColorLevel + delta, dist);\n\n vec4 color = fragBorderColor;\n color.a *= borderColorAmt;\n color = mix(color, fragColor, colorAmt);\n color.a *= opacity;\n\n gl_FragColor = color;\n }\n\n}\n"]); - markerOptions.vert = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute float x, y, xFract, yFract;\nattribute float size, borderSize;\nattribute vec4 colorId, borderColorId;\nattribute float isActive;\n\nuniform vec2 scale, scaleFract, translate, translateFract, paletteSize;\nuniform float pixelRatio;\nuniform sampler2D palette;\n\nconst float maxSize = 100.;\nconst float borderLevel = .5;\n\nvarying vec4 fragColor, fragBorderColor;\nvarying float fragPointSize, fragBorderRadius, fragWidth, fragBorderColorLevel, fragColorLevel;\n\nbool isDirect = (paletteSize.x < 1.);\n\nvec4 getColor(vec4 id) {\n return isDirect ? id / 255. : texture2D(palette,\n vec2(\n (id.x + .5) / paletteSize.x,\n (id.y + .5) / paletteSize.y\n )\n );\n}\n\nvoid main() {\n if (isActive == 0.) return;\n\n vec2 position = vec2(x, y);\n vec2 positionFract = vec2(xFract, yFract);\n\n vec4 color = getColor(colorId);\n vec4 borderColor = getColor(borderColorId);\n\n float size = size * maxSize / 255.;\n float borderSize = borderSize * maxSize / 255.;\n\n gl_PointSize = 2. * size * pixelRatio;\n fragPointSize = size * pixelRatio;\n\n vec2 pos = (position + translate) * scale\n + (positionFract + translateFract) * scale\n + (position + translate) * scaleFract\n + (positionFract + translateFract) * scaleFract;\n\n gl_Position = vec4(pos * 2. - 1., 0, 1);\n\n fragColor = color;\n fragBorderColor = borderColor;\n fragWidth = 1. / gl_PointSize;\n\n fragBorderColorLevel = clamp(borderLevel - borderLevel * borderSize / size, 0., 1.);\n fragColorLevel = clamp(borderLevel + (1. - borderLevel) * borderSize / size, 0., 1.);\n}"]); + markerOptions.frag = glslify(["precision highp float;\n#define GLSLIFY 1\n\nvarying vec4 fragColor, fragBorderColor;\nvarying float fragWidth, fragBorderColorLevel, fragColorLevel;\n\nuniform sampler2D marker;\nuniform float opacity;\n\nfloat smoothStep(float x, float y) {\n return 1.0 / (1.0 + exp(50.0*(x - y)));\n}\n\nvoid main() {\n float dist = texture2D(marker, gl_PointCoord).r, delta = fragWidth;\n\n // max-distance alpha\n if (dist < 0.003) discard;\n\n // null-border case\n if (fragBorderColorLevel == fragColorLevel || fragBorderColor.a == 0.) {\n float colorAmt = smoothstep(.5 - delta, .5 + delta, dist);\n gl_FragColor = vec4(fragColor.rgb, colorAmt * fragColor.a * opacity);\n }\n else {\n float borderColorAmt = smoothstep(fragBorderColorLevel - delta, fragBorderColorLevel + delta, dist);\n float colorAmt = smoothstep(fragColorLevel - delta, fragColorLevel + delta, dist);\n\n vec4 color = fragBorderColor;\n color.a *= borderColorAmt;\n color = mix(color, fragColor, colorAmt);\n color.a *= opacity;\n\n gl_FragColor = color;\n }\n\n}\n"]); + markerOptions.vert = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute float x, y, xFract, yFract;\nattribute float size, borderSize;\nattribute vec4 colorId, borderColorId;\nattribute float isActive;\n\nuniform vec2 scale, scaleFract, translate, translateFract, paletteSize;\nuniform float pixelRatio;\nuniform bool constPointSize;\nuniform sampler2D palette;\n\nconst float maxSize = 100.;\nconst float borderLevel = .5;\n\nvarying vec4 fragColor, fragBorderColor;\nvarying float fragPointSize, fragBorderRadius, fragWidth, fragBorderColorLevel, fragColorLevel;\n\nfloat pointSizeScale = (constPointSize) ? 2. : pixelRatio;\n\nbool isDirect = (paletteSize.x < 1.);\n\nvec4 getColor(vec4 id) {\n return isDirect ? id / 255. : texture2D(palette,\n vec2(\n (id.x + .5) / paletteSize.x,\n (id.y + .5) / paletteSize.y\n )\n );\n}\n\nvoid main() {\n // ignore inactive points\n if (isActive == 0.) return;\n\n vec2 position = vec2(x, y);\n vec2 positionFract = vec2(xFract, yFract);\n\n vec4 color = getColor(colorId);\n vec4 borderColor = getColor(borderColorId);\n\n float size = size * maxSize / 255.;\n float borderSize = borderSize * maxSize / 255.;\n\n gl_PointSize = 2. * size * pointSizeScale;\n fragPointSize = size * pixelRatio;\n\n vec2 pos = (position + translate) * scale\n + (positionFract + translateFract) * scale\n + (position + translate) * scaleFract\n + (positionFract + translateFract) * scaleFract;\n\n gl_Position = vec4(pos * 2. - 1., 0., 1.);\n\n fragColor = color;\n fragBorderColor = borderColor;\n fragWidth = 1. / gl_PointSize;\n\n fragBorderColorLevel = clamp(borderLevel - borderLevel * borderSize / size, 0., 1.);\n fragColorLevel = clamp(borderLevel + (1. - borderLevel) * borderSize / size, 0., 1.);\n}"]); this.drawMarker = regl(markerOptions); // draw circle var circleOptions = extend({}, shaderOptions); circleOptions.frag = glslify(["precision highp float;\n#define GLSLIFY 1\n\nvarying vec4 fragColor, fragBorderColor;\n\nuniform float opacity;\nvarying float fragBorderRadius, fragWidth;\n\nfloat smoothStep(float edge0, float edge1, float x) {\n\tfloat t;\n\tt = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n\treturn t * t * (3.0 - 2.0 * t);\n}\n\nvoid main() {\n\tfloat radius, alpha = 1.0, delta = fragWidth;\n\n\tradius = length(2.0 * gl_PointCoord.xy - 1.0);\n\n\tif (radius > 1.0 + delta) {\n\t\tdiscard;\n\t}\n\n\talpha -= smoothstep(1.0 - delta, 1.0 + delta, radius);\n\n\tfloat borderRadius = fragBorderRadius;\n\tfloat ratio = smoothstep(borderRadius - delta, borderRadius + delta, radius);\n\tvec4 color = mix(fragColor, fragBorderColor, ratio);\n\tcolor.a *= alpha * opacity;\n\tgl_FragColor = color;\n}\n"]); - circleOptions.vert = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute float x, y, xFract, yFract;\nattribute float size, borderSize;\nattribute vec4 colorId, borderColorId;\nattribute float isActive;\n\nuniform vec2 scale, scaleFract, translate, translateFract;\nuniform float pixelRatio;\nuniform sampler2D palette;\nuniform vec2 paletteSize;\n\nconst float maxSize = 100.;\n\nvarying vec4 fragColor, fragBorderColor;\nvarying float fragBorderRadius, fragWidth;\n\nbool isDirect = (paletteSize.x < 1.);\n\nvec4 getColor(vec4 id) {\n return isDirect ? id / 255. : texture2D(palette,\n vec2(\n (id.x + .5) / paletteSize.x,\n (id.y + .5) / paletteSize.y\n )\n );\n}\n\nvoid main() {\n // ignore inactive points\n if (isActive == 0.) return;\n\n vec2 position = vec2(x, y);\n vec2 positionFract = vec2(xFract, yFract);\n\n vec4 color = getColor(colorId);\n vec4 borderColor = getColor(borderColorId);\n\n float size = size * maxSize / 255.;\n float borderSize = borderSize * maxSize / 255.;\n\n gl_PointSize = (size + borderSize) * pixelRatio;\n\n vec2 pos = (position + translate) * scale\n + (positionFract + translateFract) * scale\n + (position + translate) * scaleFract\n + (positionFract + translateFract) * scaleFract;\n\n gl_Position = vec4(pos * 2. - 1., 0, 1);\n\n fragBorderRadius = 1. - 2. * borderSize / (size + borderSize);\n fragColor = color;\n fragBorderColor = borderColor.a == 0. || borderSize == 0. ? vec4(color.rgb, 0.) : borderColor;\n fragWidth = 1. / gl_PointSize;\n}\n"]); // polyfill IE + circleOptions.vert = glslify(["precision highp float;\n#define GLSLIFY 1\n\nattribute float x, y, xFract, yFract;\nattribute float size, borderSize;\nattribute vec4 colorId, borderColorId;\nattribute float isActive;\n\nuniform vec2 scale, scaleFract, translate, translateFract;\nuniform float pixelRatio;\nuniform bool constPointSize;\nuniform sampler2D palette;\nuniform vec2 paletteSize;\n\nconst float maxSize = 100.;\n\nvarying vec4 fragColor, fragBorderColor;\nvarying float fragBorderRadius, fragWidth;\n\nfloat pointSizeScale = (constPointSize) ? 2. : pixelRatio;\n\nbool isDirect = (paletteSize.x < 1.);\n\nvec4 getColor(vec4 id) {\n return isDirect ? id / 255. : texture2D(palette,\n vec2(\n (id.x + .5) / paletteSize.x,\n (id.y + .5) / paletteSize.y\n )\n );\n}\n\nvoid main() {\n // ignore inactive points\n if (isActive == 0.) return;\n\n vec2 position = vec2(x, y);\n vec2 positionFract = vec2(xFract, yFract);\n\n vec4 color = getColor(colorId);\n vec4 borderColor = getColor(borderColorId);\n\n float size = size * maxSize / 255.;\n float borderSize = borderSize * maxSize / 255.;\n\n gl_PointSize = (size + borderSize) * pointSizeScale;\n\n vec2 pos = (position + translate) * scale\n + (positionFract + translateFract) * scale\n + (position + translate) * scaleFract\n + (positionFract + translateFract) * scaleFract;\n\n gl_Position = vec4(pos * 2. - 1., 0., 1.);\n\n fragBorderRadius = 1. - 2. * borderSize / (size + borderSize);\n fragColor = color;\n fragBorderColor = borderColor.a == 0. || borderSize == 0. ? vec4(color.rgb, 0.) : borderColor;\n fragWidth = 1. / gl_PointSize;\n}\n"]); // polyfill IE if (ie) { circleOptions.frag = circleOptions.frag.replace('smoothstep', 'smoothStep'); @@ -293,9 +308,8 @@ Scatter.defaults = { offset: 0, bounds: null, positions: [], - snap: 1e4 // update & redraw - -}; + snap: 1e4 +}; // update & redraw Scatter.prototype.render = function () { if (arguments.length) { @@ -463,9 +477,9 @@ Scatter.prototype.update = function () { };else if (typeof options === 'function') options = { ondraw: options };else if (typeof options[0] === 'number') options = { - positions: options // copy options to avoid mutation & handle aliases + positions: options + }; // copy options to avoid mutation & handle aliases - }; options = pick(options, { positions: 'positions data points', snap: 'snap cluster lod tree', @@ -947,20 +961,20 @@ Scatter.prototype.destroy = function () { var extend$1 = require('object-assign'); var reglScatter2d = function reglScatter2d(regl, options) { - var scatter$$1 = new scatter(regl, options); - var render = scatter$$1.render.bind(scatter$$1); // expose API + var scatter$1 = new scatter(regl, options); + var render = scatter$1.render.bind(scatter$1); // expose API extend$1(render, { render: render, - update: scatter$$1.update.bind(scatter$$1), - draw: scatter$$1.draw.bind(scatter$$1), - destroy: scatter$$1.destroy.bind(scatter$$1), - regl: scatter$$1.regl, - gl: scatter$$1.gl, - canvas: scatter$$1.gl.canvas, - groups: scatter$$1.groups, - markers: scatter$$1.markerCache, - palette: scatter$$1.palette + update: scatter$1.update.bind(scatter$1), + draw: scatter$1.draw.bind(scatter$1), + destroy: scatter$1.destroy.bind(scatter$1), + regl: scatter$1.regl, + gl: scatter$1.gl, + canvas: scatter$1.gl.canvas, + groups: scatter$1.groups, + markers: scatter$1.markerCache, + palette: scatter$1.palette }); return render; }; diff --git a/circle-vert.glsl b/circle-vert.glsl index d2b16a3..b4a59c9 100644 --- a/circle-vert.glsl +++ b/circle-vert.glsl @@ -7,6 +7,7 @@ attribute float isActive; uniform vec2 scale, scaleFract, translate, translateFract; uniform float pixelRatio; +uniform bool constPointSize; uniform sampler2D palette; uniform vec2 paletteSize; @@ -15,6 +16,8 @@ const float maxSize = 100.; varying vec4 fragColor, fragBorderColor; varying float fragBorderRadius, fragWidth; +float pointSizeScale = (constPointSize) ? 2. : pixelRatio; + bool isDirect = (paletteSize.x < 1.); vec4 getColor(vec4 id) { @@ -39,14 +42,14 @@ void main() { float size = size * maxSize / 255.; float borderSize = borderSize * maxSize / 255.; - gl_PointSize = (size + borderSize) * pixelRatio; + gl_PointSize = (size + borderSize) * pointSizeScale; vec2 pos = (position + translate) * scale + (positionFract + translateFract) * scale + (position + translate) * scaleFract + (positionFract + translateFract) * scaleFract; - gl_Position = vec4(pos * 2. - 1., 0, 1); + gl_Position = vec4(pos * 2. - 1., 0., 1.); fragBorderRadius = 1. - 2. * borderSize / (size + borderSize); fragColor = color; diff --git a/marker-frag.glsl b/marker-frag.glsl index 1b4b652..0f572cc 100644 --- a/marker-frag.glsl +++ b/marker-frag.glsl @@ -4,7 +4,7 @@ varying vec4 fragColor, fragBorderColor; varying float fragWidth, fragBorderColorLevel, fragColorLevel; uniform sampler2D marker; -uniform float pixelRatio, opacity; +uniform float opacity; float smoothStep(float x, float y) { return 1.0 / (1.0 + exp(50.0*(x - y))); diff --git a/marker-vert.glsl b/marker-vert.glsl index 3036420..e8604d7 100644 --- a/marker-vert.glsl +++ b/marker-vert.glsl @@ -7,6 +7,7 @@ attribute float isActive; uniform vec2 scale, scaleFract, translate, translateFract, paletteSize; uniform float pixelRatio; +uniform bool constPointSize; uniform sampler2D palette; const float maxSize = 100.; @@ -15,6 +16,8 @@ const float borderLevel = .5; varying vec4 fragColor, fragBorderColor; varying float fragPointSize, fragBorderRadius, fragWidth, fragBorderColorLevel, fragColorLevel; +float pointSizeScale = (constPointSize) ? 2. : pixelRatio; + bool isDirect = (paletteSize.x < 1.); vec4 getColor(vec4 id) { @@ -27,6 +30,7 @@ vec4 getColor(vec4 id) { } void main() { + // ignore inactive points if (isActive == 0.) return; vec2 position = vec2(x, y); @@ -38,7 +42,7 @@ void main() { float size = size * maxSize / 255.; float borderSize = borderSize * maxSize / 255.; - gl_PointSize = 2. * size * pixelRatio; + gl_PointSize = 2. * size * pointSizeScale; fragPointSize = size * pixelRatio; vec2 pos = (position + translate) * scale @@ -46,7 +50,7 @@ void main() { + (position + translate) * scaleFract + (positionFract + translateFract) * scaleFract; - gl_Position = vec4(pos * 2. - 1., 0, 1); + gl_Position = vec4(pos * 2. - 1., 0., 1.); fragColor = color; fragBorderColor = borderColor; diff --git a/scatter.js b/scatter.js index ad44317..5581fe4 100644 --- a/scatter.js +++ b/scatter.js @@ -81,6 +81,7 @@ function Scatter (regl, options) { // common shader options let shaderOptions = { uniforms: { + constPointSize: !!options.constPointSize, pixelRatio: regl.context('pixelRatio'), palette: paletteTexture, paletteSize: (ctx, prop) => [this.tooManyColors ? 0 : maxColors, paletteTexture.height],