three-globe
Advanced tools
Comparing version 0.6.0 to 1.0.0
@@ -170,4 +170,2 @@ 'use strict'; | ||
customThreeObject: { | ||
default: [], | ||
onChange(_, state) { | ||
@@ -342,9 +340,9 @@ state.customLayerNeedsRepopulating = true; | ||
} | ||
} | ||
obj.__globeObjType = 'custom'; // Add object type | ||
obj.__globeObjType = 'custom'; // Add object type | ||
obj.__data = d; // Attach point data | ||
obj.__data = d; // Attach point data | ||
state.customLayerG.add(d.__threeObj = obj); | ||
state.customLayerG.add(d.__threeObj = obj); | ||
} | ||
}); | ||
@@ -351,0 +349,0 @@ } |
@@ -1,2 +0,2 @@ | ||
// Version 0.6.0 three-globe - https://github.com/vasturiano/three-globe | ||
// Version 1.0.0 three-globe - https://github.com/vasturiano/three-globe | ||
(function (global, factory) { | ||
@@ -193,4 +193,2 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('three')) : | ||
customThreeObject: { | ||
default: [], | ||
onChange(_, state) { | ||
@@ -365,9 +363,9 @@ state.customLayerNeedsRepopulating = true; | ||
} | ||
} | ||
obj.__globeObjType = 'custom'; // Add object type | ||
obj.__globeObjType = 'custom'; // Add object type | ||
obj.__data = d; // Attach point data | ||
obj.__data = d; // Attach point data | ||
state.customLayerG.add(d.__threeObj = obj); | ||
state.customLayerG.add(d.__threeObj = obj); | ||
} | ||
}); | ||
@@ -374,0 +372,0 @@ } |
@@ -1,2 +0,2 @@ | ||
// Version 0.6.0 three-globe - https://github.com/vasturiano/three-globe | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("three")):"function"==typeof define&&define.amd?define(["three"],t):(e=e||self).ThreeGlobe=t(e.THREE)}(this,function(e){"use strict";"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function n(e,t){return e(t={exports:{}},t.exports),t.exports}var o=n(function(e,t){"undefined"!=typeof self&&self,e.exports=function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:o})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){var o,r,a,i;i=function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=e.stateInit,n=void 0===t?function(){return{}}:t,o=e.props,s=void 0===o?{}:o,l=e.methods,u=void 0===l?{}:l,c=e.aliases,p=void 0===c?{}:c,d=e.init,f=void 0===d?function(){}:d,h=e.update,g=void 0===h?function(){}:h,m=Object.keys(s).map(function(e){return new i(e,s[e])});return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=Object.assign({},n instanceof Function?n(e):n,{initialised:!1});function o(t){return i(t,e),s(),o}var i=function(e,n){f.call(o,e,t,n),t.initialised=!0},s=(0,r.default)(function(){t.initialised&&g.call(o,t)},1);return m.forEach(function(e){o[e.name]=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e,t){};return function(a){var i=t[e];return arguments.length?(t[e]=a,r.call(o,a,t,i),n&&s(),o):i}}(e.name,e.triggerUpdate,e.onChange)}),Object.keys(u).forEach(function(e){o[e]=function(){for(var n,r=arguments.length,a=Array(r),i=0;i<r;i++)a[i]=arguments[i];return(n=u[e]).call.apply(n,[o,t].concat(a))}}),Object.entries(p).forEach(function(e){var t=a(e,2),n=t[0],r=t[1];return o[n]=o[r]}),o.resetProps=function(){return m.forEach(function(e){o[e.name](e.defaultVal)}),o},o.resetProps(),t._rerender=s,o}};var o,r=(o=n)&&o.__esModule?o:{default:o},a=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],o=!0,r=!1,a=void 0;try{for(var i,s=e[Symbol.iterator]();!(o=(i=s.next()).done)&&(n.push(i.value),!t||n.length!==t);o=!0);}catch(e){r=!0,a=e}finally{try{!o&&s.return&&s.return()}finally{if(r)throw a}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},i=function e(t,n){var o=n.default,r=void 0===o?null:o,a=n.triggerUpdate,i=void 0===a||a,s=n.onChange,l=void 0===s?function(e,t){}:s;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.name=t,this.defaultVal=r,this.triggerUpdate=i,this.onChange=l};e.exports=t.default},r=[e,t,n(1)],void 0===(a="function"==typeof(o=i)?o.apply(t,r):o)||(e.exports=a)},function(e,t){e.exports=function(e,t,n){var o,r,a,i,s;function l(){var u=Date.now()-i;u<t&&u>=0?o=setTimeout(l,t-u):(o=null,n||(s=e.apply(a,r),a=r=null))}null==t&&(t=100);var u=function(){a=this,r=arguments,i=Date.now();var u=n&&!o;return o||(o=setTimeout(l,t)),u&&(s=e.apply(a,r),a=r=null),s};return u.clear=function(){o&&(clearTimeout(o),o=null)},u.flush=function(){o&&(s=e.apply(a,r),a=r=null,clearTimeout(o),o=null)},u}}])}),r=t(o),a=(o.Kapsule,n(function(e,t){e.exports=function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){var o,r,a;r=[e,t],void 0!==(a="function"==typeof(o=function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e instanceof Function?e:"string"==typeof e?function(t){return t[e]}:function(t){return e}},e.exports=t.default})?o.apply(t,r):o)&&(e.exports=a)}])})),i=t(a);a.accessorFn;const s=window.THREE?window.THREE:{AdditiveBlending:e.AdditiveBlending,BackSide:e.BackSide,Color:e.Color,CylinderGeometry:e.CylinderGeometry,FaceColors:e.FaceColors,Geometry:e.Geometry,Group:e.Group,Matrix4:e.Matrix4,Mesh:e.Mesh,MeshBasicMaterial:e.MeshBasicMaterial,ShaderMaterial:e.ShaderMaterial,SphereGeometry:e.SphereGeometry,TextureLoader:e.TextureLoader,UniformsUtils:e.UniformsUtils},l=e=>{const t=e=>{e instanceof Array?e.forEach(t):(e.map&&e.map.dispose(),e.dispose())},n=e=>{e.geometry&&e.geometry.dispose(),e.material&&t(e.material),e.texture&&e.texture.dispose(),e.children&&e.children.forEach(n)};for(;e.children.length;){const e=state.pointsG.children[0];state.pointsG.remove(e),n(e)}},u={earth:{uniforms:{texture:{type:"t",value:null}},vertexShader:["varying vec3 vNormal;","varying vec2 vUv;","void main() {","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","vNormal = normalize( normalMatrix * normal );","vUv = uv;","}"].join("\n"),fragmentShader:["uniform sampler2D texture;","varying vec3 vNormal;","varying vec2 vUv;","void main() {","vec3 diffuse = texture2D( texture, vUv ).xyz;","float intensity = 1.05 - dot( vNormal, vec3( 0.0, 0.0, 1.0 ) );","vec3 atmosphere = vec3( 1.0, 1.0, 1.0 ) * pow( intensity, 3.0 );","gl_FragColor = vec4( diffuse + atmosphere, 1.0 );","}"].join("\n")},atmosphere:{uniforms:{},vertexShader:["varying vec3 vNormal;","void main() {","vNormal = normalize( normalMatrix * normal );","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["varying vec3 vNormal;","void main() {","float intensity = pow( 0.8 - dot( vNormal, vec3( 0, 0, 1.0 ) ), 12.0 );","gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ) * intensity;","}"].join("\n")}};return function(e,t=Object,n=!1){class o extends t{constructor(...t){super(...t),this.__kapsuleInstance=e()(...n?[this]:[],...t)}}return Object.keys(e()).forEach(e=>o.prototype[e]=function(...t){const n=this.__kapsuleInstance[e](...t);return n===this.__kapsuleInstance?this:n}),o}(r({props:{globeImageUrl:{onChange(e){this._loadGlobeImage(e)},triggerUpdate:!1},pointsData:{default:[],onChange(e,t){t.pointsNeedsRepopulating=!0}},pointLat:{default:"lat",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointLng:{default:"lng",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointColor:{default:()=>"#ffffaa",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointHeight:{default:.1,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointRadius:{default:.25,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointResolution:{default:12,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointsMerge:{default:!1,onChange(e,t){t.pointsNeedsRepopulating=!0}},customLayerData:{default:[],onChange(e,t){t.customLayerNeedsRepopulating=!0}},customThreeObject:{default:[],onChange(e,t){t.customLayerNeedsRepopulating=!0}}},methods:{getCoords(e,t,n,o=1){const r=(90-t)*Math.PI/180,a=(-45-n)*Math.PI/180,i=100*o;return{x:i*Math.sin(r)*Math.cos(a),y:i*Math.cos(r),z:i*Math.sin(r)*Math.sin(a)}},_loadGlobeImage:function(e,t){if(e.globeObj&&t){const n=u.earth,o=s.UniformsUtils.clone(n.uniforms);o.texture.value=(new s.TextureLoader).load(t),e.globeObj.material=new s.ShaderMaterial({uniforms:o,vertexShader:n.vertexShader,fragmentShader:n.fragmentShader})}return this}},stateInit:()=>({pointsNeedsRepopulating:!0}),init(e,t){t.scene=e,l(t.scene);const n=new s.SphereGeometry(100,40,30),o=t.globeObj=new s.Mesh(n,new s.MeshBasicMaterial({color:0}));o.rotation.y=Math.PI/4,o.__globeObjType="globe",t.scene.add(o),t.globeImageUrl&&this._loadGlobeImage(t.globeImageUrl);{const e=u.atmosphere,o=s.UniformsUtils.clone(e.uniforms),r=new s.ShaderMaterial({uniforms:o,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,side:s.BackSide,blending:s.AdditiveBlending,transparent:!0}),a=new s.Mesh(n,r);a.scale.set(1.1,1.1,1.1),a.__globeObjType="atmosphere",t.scene.add(a)}t.scene.add(t.pointsG=new s.Group),t.scene.add(t.customLayerG=new s.Group)},update(e){const t=2*Math.PI*100/360;if(e.pointsNeedsRepopulating){e.pointsNeedRepopulating=!1,l(e.pointsG);const n=i(e.pointLat),o=i(e.pointLng),r=i(e.pointHeight),a=i(e.pointRadius),u=i(e.pointColor),c=new s.CylinderGeometry(1,1,1,e.pointResolution);c.applyMatrix((new s.Matrix4).makeRotationX(Math.PI/2)),c.applyMatrix((new s.Matrix4).makeTranslation(0,0,-.5));const p=[];if(e.pointsData.forEach(i=>{const l=new s.Mesh(c);Object.assign(l.position,this.getCoords(n(i),o(i))),l.lookAt(e.globeObj.position),l.scale.x=l.scale.y=Math.min(30,a(i))*t,l.scale.z=Math.max(100*r(i),.1),l.__globeObjType="point",l.__data=i,p.push(l)}),e.pointsMerge){const t=new s.Geometry;p.forEach(e=>{const n=e.__data,o=new s.Color(u(n));e.geometry.faces.forEach(e=>e.color=o),e.updateMatrix(),t.merge(e.geometry,e.matrix)});const n=new s.Mesh(t,new s.MeshBasicMaterial({color:16777215,vertexColors:s.FaceColors,morphTargets:!1}));n.__globeObjType="points",n.__data=e.pointsData,e.pointsG.add(n)}else{const t={};p.forEach(n=>{const o=n.__data,r=u(o);t.hasOwnProperty(r)||(t[r]=new s.MeshBasicMaterial({color:new s.Color(r)})),n.material=t[r],n.__globeObjType="point",n.__data=o,e.pointsG.add(o.__threeObj=n)})}}if(e.customLayerNeedsRepopulating){e.pointsNeedRepopulating=!1,l(e.customLayerG);const t=i(e.customThreeObject);e.customLayerData.forEach(n=>{let o=t(n,100);o&&e.customThreeObject===o&&(o=o.clone()),o.__globeObjType="custom",o.__data=n,e.customLayerG.add(n.__threeObj=o)})}}}),e.Group,!0)}); | ||
// Version 1.0.0 three-globe - https://github.com/vasturiano/three-globe | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("three")):"function"==typeof define&&define.amd?define(["three"],t):(e=e||self).ThreeGlobe=t(e.THREE)}(this,function(e){"use strict";"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function n(e,t){return e(t={exports:{}},t.exports),t.exports}var o=n(function(e,t){"undefined"!=typeof self&&self,e.exports=function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:o})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){var o,r,a,i;i=function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=e.stateInit,n=void 0===t?function(){return{}}:t,o=e.props,s=void 0===o?{}:o,l=e.methods,u=void 0===l?{}:l,c=e.aliases,p=void 0===c?{}:c,d=e.init,f=void 0===d?function(){}:d,h=e.update,g=void 0===h?function(){}:h,m=Object.keys(s).map(function(e){return new i(e,s[e])});return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=Object.assign({},n instanceof Function?n(e):n,{initialised:!1});function o(t){return i(t,e),s(),o}var i=function(e,n){f.call(o,e,t,n),t.initialised=!0},s=(0,r.default)(function(){t.initialised&&g.call(o,t)},1);return m.forEach(function(e){o[e.name]=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e,t){};return function(a){var i=t[e];return arguments.length?(t[e]=a,r.call(o,a,t,i),n&&s(),o):i}}(e.name,e.triggerUpdate,e.onChange)}),Object.keys(u).forEach(function(e){o[e]=function(){for(var n,r=arguments.length,a=Array(r),i=0;i<r;i++)a[i]=arguments[i];return(n=u[e]).call.apply(n,[o,t].concat(a))}}),Object.entries(p).forEach(function(e){var t=a(e,2),n=t[0],r=t[1];return o[n]=o[r]}),o.resetProps=function(){return m.forEach(function(e){o[e.name](e.defaultVal)}),o},o.resetProps(),t._rerender=s,o}};var o,r=(o=n)&&o.__esModule?o:{default:o},a=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],o=!0,r=!1,a=void 0;try{for(var i,s=e[Symbol.iterator]();!(o=(i=s.next()).done)&&(n.push(i.value),!t||n.length!==t);o=!0);}catch(e){r=!0,a=e}finally{try{!o&&s.return&&s.return()}finally{if(r)throw a}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},i=function e(t,n){var o=n.default,r=void 0===o?null:o,a=n.triggerUpdate,i=void 0===a||a,s=n.onChange,l=void 0===s?function(e,t){}:s;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.name=t,this.defaultVal=r,this.triggerUpdate=i,this.onChange=l};e.exports=t.default},r=[e,t,n(1)],void 0===(a="function"==typeof(o=i)?o.apply(t,r):o)||(e.exports=a)},function(e,t){e.exports=function(e,t,n){var o,r,a,i,s;function l(){var u=Date.now()-i;u<t&&u>=0?o=setTimeout(l,t-u):(o=null,n||(s=e.apply(a,r),a=r=null))}null==t&&(t=100);var u=function(){a=this,r=arguments,i=Date.now();var u=n&&!o;return o||(o=setTimeout(l,t)),u&&(s=e.apply(a,r),a=r=null),s};return u.clear=function(){o&&(clearTimeout(o),o=null)},u.flush=function(){o&&(s=e.apply(a,r),a=r=null,clearTimeout(o),o=null)},u}}])}),r=t(o),a=(o.Kapsule,n(function(e,t){e.exports=function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){var o,r,a;r=[e,t],void 0!==(a="function"==typeof(o=function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e instanceof Function?e:"string"==typeof e?function(t){return t[e]}:function(t){return e}},e.exports=t.default})?o.apply(t,r):o)&&(e.exports=a)}])})),i=t(a);a.accessorFn;const s=window.THREE?window.THREE:{AdditiveBlending:e.AdditiveBlending,BackSide:e.BackSide,Color:e.Color,CylinderGeometry:e.CylinderGeometry,FaceColors:e.FaceColors,Geometry:e.Geometry,Group:e.Group,Matrix4:e.Matrix4,Mesh:e.Mesh,MeshBasicMaterial:e.MeshBasicMaterial,ShaderMaterial:e.ShaderMaterial,SphereGeometry:e.SphereGeometry,TextureLoader:e.TextureLoader,UniformsUtils:e.UniformsUtils},l=e=>{const t=e=>{e instanceof Array?e.forEach(t):(e.map&&e.map.dispose(),e.dispose())},n=e=>{e.geometry&&e.geometry.dispose(),e.material&&t(e.material),e.texture&&e.texture.dispose(),e.children&&e.children.forEach(n)};for(;e.children.length;){const e=state.pointsG.children[0];state.pointsG.remove(e),n(e)}},u={earth:{uniforms:{texture:{type:"t",value:null}},vertexShader:["varying vec3 vNormal;","varying vec2 vUv;","void main() {","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","vNormal = normalize( normalMatrix * normal );","vUv = uv;","}"].join("\n"),fragmentShader:["uniform sampler2D texture;","varying vec3 vNormal;","varying vec2 vUv;","void main() {","vec3 diffuse = texture2D( texture, vUv ).xyz;","float intensity = 1.05 - dot( vNormal, vec3( 0.0, 0.0, 1.0 ) );","vec3 atmosphere = vec3( 1.0, 1.0, 1.0 ) * pow( intensity, 3.0 );","gl_FragColor = vec4( diffuse + atmosphere, 1.0 );","}"].join("\n")},atmosphere:{uniforms:{},vertexShader:["varying vec3 vNormal;","void main() {","vNormal = normalize( normalMatrix * normal );","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["varying vec3 vNormal;","void main() {","float intensity = pow( 0.8 - dot( vNormal, vec3( 0, 0, 1.0 ) ), 12.0 );","gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ) * intensity;","}"].join("\n")}};return function(e,t=Object,n=!1){class o extends t{constructor(...t){super(...t),this.__kapsuleInstance=e()(...n?[this]:[],...t)}}return Object.keys(e()).forEach(e=>o.prototype[e]=function(...t){const n=this.__kapsuleInstance[e](...t);return n===this.__kapsuleInstance?this:n}),o}(r({props:{globeImageUrl:{onChange(e){this._loadGlobeImage(e)},triggerUpdate:!1},pointsData:{default:[],onChange(e,t){t.pointsNeedsRepopulating=!0}},pointLat:{default:"lat",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointLng:{default:"lng",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointColor:{default:()=>"#ffffaa",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointHeight:{default:.1,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointRadius:{default:.25,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointResolution:{default:12,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointsMerge:{default:!1,onChange(e,t){t.pointsNeedsRepopulating=!0}},customLayerData:{default:[],onChange(e,t){t.customLayerNeedsRepopulating=!0}},customThreeObject:{onChange(e,t){t.customLayerNeedsRepopulating=!0}}},methods:{getCoords(e,t,n,o=1){const r=(90-t)*Math.PI/180,a=(-45-n)*Math.PI/180,i=100*o;return{x:i*Math.sin(r)*Math.cos(a),y:i*Math.cos(r),z:i*Math.sin(r)*Math.sin(a)}},_loadGlobeImage:function(e,t){if(e.globeObj&&t){const n=u.earth,o=s.UniformsUtils.clone(n.uniforms);o.texture.value=(new s.TextureLoader).load(t),e.globeObj.material=new s.ShaderMaterial({uniforms:o,vertexShader:n.vertexShader,fragmentShader:n.fragmentShader})}return this}},stateInit:()=>({pointsNeedsRepopulating:!0}),init(e,t){t.scene=e,l(t.scene);const n=new s.SphereGeometry(100,40,30),o=t.globeObj=new s.Mesh(n,new s.MeshBasicMaterial({color:0}));o.rotation.y=Math.PI/4,o.__globeObjType="globe",t.scene.add(o),t.globeImageUrl&&this._loadGlobeImage(t.globeImageUrl);{const e=u.atmosphere,o=s.UniformsUtils.clone(e.uniforms),r=new s.ShaderMaterial({uniforms:o,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,side:s.BackSide,blending:s.AdditiveBlending,transparent:!0}),a=new s.Mesh(n,r);a.scale.set(1.1,1.1,1.1),a.__globeObjType="atmosphere",t.scene.add(a)}t.scene.add(t.pointsG=new s.Group),t.scene.add(t.customLayerG=new s.Group)},update(e){const t=2*Math.PI*100/360;if(e.pointsNeedsRepopulating){e.pointsNeedRepopulating=!1,l(e.pointsG);const n=i(e.pointLat),o=i(e.pointLng),r=i(e.pointHeight),a=i(e.pointRadius),u=i(e.pointColor),c=new s.CylinderGeometry(1,1,1,e.pointResolution);c.applyMatrix((new s.Matrix4).makeRotationX(Math.PI/2)),c.applyMatrix((new s.Matrix4).makeTranslation(0,0,-.5));const p=[];if(e.pointsData.forEach(i=>{const l=new s.Mesh(c);Object.assign(l.position,this.getCoords(n(i),o(i))),l.lookAt(e.globeObj.position),l.scale.x=l.scale.y=Math.min(30,a(i))*t,l.scale.z=Math.max(100*r(i),.1),l.__globeObjType="point",l.__data=i,p.push(l)}),e.pointsMerge){const t=new s.Geometry;p.forEach(e=>{const n=e.__data,o=new s.Color(u(n));e.geometry.faces.forEach(e=>e.color=o),e.updateMatrix(),t.merge(e.geometry,e.matrix)});const n=new s.Mesh(t,new s.MeshBasicMaterial({color:16777215,vertexColors:s.FaceColors,morphTargets:!1}));n.__globeObjType="points",n.__data=e.pointsData,e.pointsG.add(n)}else{const t={};p.forEach(n=>{const o=n.__data,r=u(o);t.hasOwnProperty(r)||(t[r]=new s.MeshBasicMaterial({color:new s.Color(r)})),n.material=t[r],n.__globeObjType="point",n.__data=o,e.pointsG.add(o.__threeObj=n)})}}if(e.customLayerNeedsRepopulating){e.pointsNeedRepopulating=!1,l(e.customLayerG);const t=i(e.customThreeObject);e.customLayerData.forEach(n=>{let o=t(n,100);o&&(e.customThreeObject===o&&(o=o.clone()),o.__globeObjType="custom",o.__data=n,e.customLayerG.add(n.__threeObj=o))})}}}),e.Group,!0)}); |
@@ -166,4 +166,2 @@ import { AdditiveBlending, BackSide, Color, CylinderGeometry, FaceColors, Geometry, Group, Matrix4, Mesh, MeshBasicMaterial, ShaderMaterial, SphereGeometry, TextureLoader, UniformsUtils } from 'three'; | ||
customThreeObject: { | ||
default: [], | ||
onChange(_, state) { | ||
@@ -338,9 +336,9 @@ state.customLayerNeedsRepopulating = true; | ||
} | ||
} | ||
obj.__globeObjType = 'custom'; // Add object type | ||
obj.__globeObjType = 'custom'; // Add object type | ||
obj.__data = d; // Attach point data | ||
obj.__data = d; // Attach point data | ||
state.customLayerG.add(d.__threeObj = obj); | ||
state.customLayerG.add(d.__threeObj = obj); | ||
} | ||
}); | ||
@@ -347,0 +345,0 @@ } |
{ | ||
"name": "three-globe", | ||
"version": "0.6.0", | ||
"version": "1.0.0", | ||
"description": "Globe data visualization as a ThreeJS reusable 3D object", | ||
@@ -5,0 +5,0 @@ "unpkg": "dist/three-globe.min.js", |
104
README.md
@@ -6,7 +6,6 @@ # ThreeJS Globe Visualization | ||
<p align="center"> | ||
<a href="http://bl.ocks.org/vasturiano/02affe306ce445e423f992faeea13521"><img width="80%" src="http://gist.github.com/vasturiano/02affe306ce445e423f992faeea13521/raw/preview.png"></a> | ||
<a href="//vasturiano.github.io/three-globe/example/basic/"><img width="80%" src="//vasturiano.github.io/three-globe/example/sshot.png"></a> | ||
</p> | ||
A [ThreeJS](https://threejs.org/) WebGL class to represent a graph data structure in a 3-dimensional space using a force-directed iterative layout. | ||
Uses either [d3-force-3d](https://github.com/vasturiano/d3-force-3d) or [ngraph](https://github.com/anvaka/ngraph.forcelayout3d) for the underlying physics engine. | ||
Largely inspired by the [WebGL Globe](https://experiments.withgoogle.com/chrome/globe), this is a [ThreeJS](https://threejs.org/) WebGL class to represent data visualization layers on a globe, using spherical projection. | ||
@@ -20,3 +19,3 @@ ## Quick start | ||
``` | ||
var ThreeGlobe = require('three-globe'); | ||
const ThreeGlobe = require('three-globe'); | ||
``` | ||
@@ -29,11 +28,8 @@ or even | ||
``` | ||
var myGlobe = new ThreeGlobe(); | ||
const myGlobe = new ThreeGlobe() | ||
.globeImageUrl(<imageUrl>) | ||
.pointsData(<myData>); | ||
var myScene = new THREE.Scene(); | ||
const myScene = new THREE.Scene(); | ||
myScene.add(myGlobe); | ||
... | ||
// on animation frame | ||
myGlobe.tickFrame(); | ||
``` | ||
@@ -45,76 +41,12 @@ | ||
| --- | --- | :--: | | ||
| <b>graphData</b>([<i>data</i>]) | Getter/setter for graph data structure (see below for syntax details). Can also be used to apply [incremental updates](https://bl.ocks.org/vasturiano/2f602ea6c51c664c29ec56cbe2d6a5f6). | `{ nodes: [], links: [] }` | | ||
| <b>jsonUrl</b>([<i>url</i>]) | URL of JSON file to load graph data directly from, as an alternative to specifying <i>graphData</i> directly. | | | ||
| <b>numDimensions</b>([<i>int</i>]) | Getter/setter for number of dimensions to run the force simulation on (1, 2 or 3). | 3 | | ||
| <b>dagMode</b>([<i>str</i>]) | Apply layout constraints based on the graph directionality. Only works for [DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph) graph structures (without cycles). Choice between `td` (top-down), `bu` (bottom-up), `lr` (left-to-right), `rl` (right-to-left), `zout` (near-to-far), `zin` (far-to-near), `radialout` (outwards-radially) or `radialin` (inwards-radially). | | | ||
| <b>dagLevelDistance</b>([<i>num</i>]) | If `dagMode` is engaged, this specifies the distance between the different graph depths. | *auto-derived from the number of nodes* | | ||
| <b>nodeRelSize</b>([<i>num</i>]) | Getter/setter for the ratio of node sphere volume (cubic px) per value unit. | 4 | | ||
| <b>nodeId</b>([<i>str</i>]) | Node object accessor attribute for unique node id (used in link objects source/target). | `id` | | ||
| <b>nodeVal</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Node object accessor function, attribute or a numeric constant for the node numeric value (affects sphere volume). | `val` | | ||
| <b>nodeResolution</b>([<i>num</i>]) | Getter/setter for the geometric resolution of each node, expressed in how many slice segments to divide the circumference. Higher values yield smoother spheres. | 8 | | ||
| <b>nodeColor</b>([<i>str</i> or <i>fn</i>]) | Node object accessor function or attribute for node color (affects sphere color). | `color` | | ||
| <b>nodeAutoColorBy</b>([<i>str</i> or <i>fn</i>]) | Node object accessor function (`fn(node)`) or attribute (e.g. `'type'`) to automatically group colors by. Only affects nodes without a color attribute. | | | ||
| <b>nodeOpacity</b>([<i>num</i>]) | Getter/setter for all the nodes sphere opacity, between [0,1]. | 0.75 | | ||
| <b>nodeThreeObject</b>([<i>Object3d</i>, <i>str</i> or <i>fn</i>]) | Node object accessor function or attribute for generating a custom 3d object to render as graph nodes. Should return an instance of [ThreeJS Object3d](https://threejs.org/docs/index.html#api/core/Object3D). If a <i>falsy</i> value is returned, the default 3d object type will be used instead for that node. | *default node object is a sphere, sized according to `val` and styled according to `color`.* | | ||
| <b>linkSource</b>([<i>str</i>]) | Link object accessor attribute referring to id of source node. | `source` | | ||
| <b>linkTarget</b>([<i>str</i>]) | Link object accessor attribute referring to id of target node. | `target` | | ||
| <b>linkVisibility</b>([<i>boolean</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a boolean constant for whether to display the link line. A value of `false` maintains the link force without rendering it. | `true` | | ||
| <b>linkColor</b>([<i>str</i> or <i>fn</i>]) | Link object accessor function or attribute for line color. | `color` | | ||
| <b>linkAutoColorBy</b>([<i>str</i> or <i>fn</i>]) | Link object accessor function (`fn(link)`) or attribute (e.g. `'type'`) to automatically group colors by. Only affects links without a color attribute. | | | ||
| <b>linkOpacity</b>([<i>num</i>]) | Getter/setter for line opacity of all the links, between [0,1]. | 0.2 | | ||
| <b>linkWidth</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a numeric constant for the link line width. A value of zero will render a [ThreeJS Line](https://threejs.org/docs/#api/objects/Line) whose width is constant (`1px`) regardless of distance. Values are rounded to the nearest decimal for indexing purposes. | 0 | | ||
| <b>linkResolution</b>([<i>num</i>]) | Getter/setter for the geometric resolution of each link, expressed in how many radial segments to divide the cylinder. Higher values yield smoother cylinders. Applicable only to links with positive width. | 6 | | ||
| <b>linkCurvature</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a numeric constant for the curvature radius of the link line. Only applicable to links using [ThreeJS Line](https://threejs.org/docs/#api/objects/Line) (`0` width). Curved lines are represented as 3D bezier curves, and any numeric value is accepted. A value of `0` renders a straight line. `1` indicates a radius equal to half of the line length, causing the curve to approximate a semi-circle. For self-referencing links (`source` equal to `target`) the curve is represented as a loop around the node, with length proportional to the curvature value. Lines are curved clockwise for positive values, and counter-clockwise for negative values. Note that rendering curved lines is purely a visual effect and does not affect the behavior of the underlying forces. | 0 | | ||
| <b>linkCurveRotation</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a numeric constant for the rotation along the line axis to apply to the curve. Has no effect on straight lines. At `0` rotation, the curve is oriented in the direction of the intersection with the `XY` plane. The rotation angle (in radians) will rotate the curved line clockwise around the "start-to-end" axis from this reference orientation. | 0 | | ||
| <b>linkMaterial</b>([<i>Material</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function or attribute for specifying a custom material to style the graph links with. Should return an instance of [ThreeJS Material](https://threejs.org/docs/#api/materials/Material). If a <i>falsy</i> value is returned, the default material will be used instead for that link. | *default link material is [MeshLambertMaterial](https://threejs.org/docs/#api/materials/MeshLambertMaterial) styled according to `color` and `opacity`.* | | ||
| <b>linkThreeObject</b>([<i>Object3d</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function or attribute for generating a custom 3d object to render as graph links. Should return an instance of [ThreeJS Object3d](https://threejs.org/docs/index.html#api/core/Object3D). If a <i>falsy</i> value is returned, the default 3d object type will be used instead for that link. | *default link object is a line or cylinder, sized according to `width` and styled according to `material`.* | | ||
| <b>linkPositionUpdate</b>([<i>fn(linkObject, { start, end }, link)</i>]) | Getter/setter for the custom function to call for updating the position of links at every render iteration. It receives the respective link `ThreeJS Object3d`, the `start` and `end` coordinates of the link (`{x,y,z}` each), and the link's `data`. If the function returns a truthy value, the regular position update function will not run for that link. | | | ||
| <b>linkDirectionalArrowLength</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a numeric constant for the length of the arrow head indicating the link directionality. The arrow is displayed directly over the link line, and points in the direction of `source` > `target`. A value of `0` hides the arrow. | 0 | | ||
| <b>linkDirectionalArrowColor</b>([<i>str</i> or <i>fn</i>]) | Link object accessor function or attribute for the color of the arrow head. | `color` | | ||
| <b>linkDirectionalArrowRelPos</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a numeric constant for the longitudinal position of the arrow head along the link line, expressed as a ratio between `0` and `1`, where `0` indicates immediately next to the `source` node, `1` next to the `target` node, and `0.5` right in the middle. | 0.5 | | ||
| <b>linkDirectionalArrowResolution</b>([<i>num</i>]) | Getter/setter for the geometric resolution of the arrow head, expressed in how many slice segments to divide the cone base circumference. Higher values yield smoother arrows. | 8 | | ||
| <b>linkDirectionalParticles</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a numeric constant for the number of particles (small spheres) to display over the link line. The particles are distributed equi-spaced along the line, travel in the direction `source` > `target`, and can be used to indicate link directionality. | 0 | | ||
| <b>linkDirectionalParticleSpeed</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a numeric constant for the directional particles speed, expressed as the ratio of the link length to travel per frame. Values above `0.5` are discouraged. | 0.01 | | ||
| <b>linkDirectionalParticleWidth</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Link object accessor function, attribute or a numeric constant for the directional particles width. Values are rounded to the nearest decimal for indexing purposes. | 0.5 | | ||
| <b>linkDirectionalParticleColor</b>([<i>str</i> or <i>fn</i>]) | Link object accessor function or attribute for the directional particles color. | `color` | | ||
| <b>linkDirectionalParticleResolution</b>([<i>num</i>]) | Getter/setter for the geometric resolution of each directional particle, expressed in how many slice segments to divide the circumference. Higher values yield smoother particles. | 4 | | ||
| <b>forceEngine</b>([<i>str</i>]) | Getter/setter for which force-simulation engine to use ([*d3*](https://github.com/vasturiano/d3-force-3d) or [*ngraph*](https://github.com/anvaka/ngraph.forcelayout)). | `d3` | | ||
| <b>d3AlphaDecay</b>([<i>num</i>]) | Getter/setter for the [simulation intensity decay](https://github.com/vasturiano/d3-force-3d#simulation_alphaDecay) parameter, only applicable if using the d3 simulation engine. | `0.0228` | | ||
| <b>d3VelocityDecay</b>([<i>num</i>]) | Getter/setter for the nodes' [velocity decay](https://github.com/vasturiano/d3-force-3d#simulation_velocityDecay) that simulates the medium resistance, only applicable if using the d3 simulation engine. | `0.4` | | ||
| <b>d3Force</b>(<i>str</i>, [<i>fn</i>]) | Getter/setter for the internal forces that control the d3 simulation engine. Follows the same interface as `d3-force-3d`'s [simulation.force](https://github.com/vasturiano/d3-force-3d#simulation_force). Three forces are included by default: `'link'` (based on [forceLink](https://github.com/vasturiano/d3-force-3d#forceLink)), `'charge'` (based on [forceManyBody](https://github.com/vasturiano/d3-force-3d#forceManyBody)) and `'center'` (based on [forceCenter](https://github.com/vasturiano/d3-force-3d#forceCenter)). Each of these forces can be reconfigured, or new forces can be added to the system. This method is only applicable if using the d3 simulation engine. | | | ||
| <b>warmupTicks</b>([<i>int</i>]) | Getter/setter for number of layout engine cycles to dry-run at ignition before starting to render. | 0 | | ||
| <b>cooldownTicks</b>([<i>int</i>]) | Getter/setter for how many build-in frames to render before stopping and freezing the layout engine. | Infinity | | ||
| <b>cooldownTime</b>([<i>num</i>]) | Getter/setter for how long (ms) to render for before stopping and freezing the layout engine. | 15000 | | ||
| <b>onEngineTick</b>(<i>fn</i>) | Callback function invoked at every tick of the simulation engine. | - | | ||
| <b>onEngineStop</b>(<i>fn</i>) | Callback function invoked when the simulation engine stops and the layout is frozen. | - | | ||
| <b>onLoading</b>(<i>fn</i>) | Callback function for notification that data is being loaded, and the simulation engine is temporarily paused. | - | | ||
| <b>onFinishLoading</b>(<i>fn</i>) | Callback function for notification that the component has finished loading data and iterating through the warmup phase, and the simulation engine has been resumed. | - | | ||
| <b>tickFrame()</b> | This method should be called on each cycle of the global renderer to iterate the underlying force simulation engine and update the nodes/links objects' positions. || | ||
| <b>resetProps()</b> | Reset all object properties to their default value. || | ||
### Input JSON syntax | ||
``` | ||
{ | ||
"nodes": [ | ||
{ | ||
"id": "id1", | ||
"name": "name1", | ||
"val": 1 | ||
}, | ||
{ | ||
"id": "id2", | ||
"name": "name2", | ||
"val": 10 | ||
}, | ||
(...) | ||
], | ||
"links": [ | ||
{ | ||
"source": "id1", | ||
"target": "id2" | ||
}, | ||
(...) | ||
] | ||
} | ||
``` | ||
| <b>globeImageUrl</b>([<i>string</i>]) | Getter/setter for the URL of the image used in the material that wraps the globe. If no image is provided, the globe is represented as a black sphere. | `null` | | ||
| <b>pointsData</b>([<i>array</i>]) | Getter/setter for the list of points to represent in the points map layer. Each point is displayed as a cylindrical 3D object rising perpendicular from the surface of the globe. | `[]` | | ||
| <b>pointLat</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Point object accessor function, attribute or a numeric constant for the cylinder's center latitude coordinate. | `lat` | | ||
| <b>pointLng</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Point object accessor function, attribute or a numeric constant for the cylinder's center longitude coordinate. | `lat` | | ||
| <b>pointColor</b>([<i>str</i> or <i>fn</i>]) | Point object accessor function or attribute for the cylinder color. | `() => '#ffffaa'` | | ||
| <b>pointHeight</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Point object accessor function, attribute or a numeric constant for the cylinder's altitude in terms of globe radius units (`0` = 0 altitude (flat circle), `1` = globe radius). | `0.1` | | ||
| <b>pointRadius</b>([<i>num</i>, <i>str</i> or <i>fn</i>]) | Point object accessor function, attribute or a numeric constant for the cylinder's radius, in angular degrees. | `0.25` | | ||
| <b>pointResolution</b>([<i>num</i>]) | Getter/setter for the radial geometric resolution of each cylinder, expressed in how many slice segments to divide the circumference. Higher values yield smoother cylinders. | 12 | | ||
| <b>pointsMerge</b>([<i>boolean</i>]) | Getter/setter for whether to merge all the point meshes into a single ThreeJS object, for improved rendering performance. Visually both options are equivalent, setting this option only affects the internal organization of the ThreeJS objects. | `false` | | ||
| <b>customLayerData</b>([<i>array</i>]) | Getter/setter for the list of items to represent in the custom map layer. Each item is rendered according to the `customThreeObject` method. | `[]` | | ||
| <b>customThreeObject</b>([<i>Object3d</i>, <i>str</i> or <i>fn</i>]) | Object accessor function or attribute for generating a custom 3d object to render as part of the custom map layer. Should return an instance of [ThreeJS Object3d](https://threejs.org/docs/index.html#api/core/Object3D). | `null` | |
@@ -125,3 +125,3 @@ import { | ||
customLayerData: { default: [], onChange(_, state) { state.customLayerNeedsRepopulating = true }}, | ||
customThreeObject: { default: [], onChange(_, state) { state.customLayerNeedsRepopulating = true }} | ||
customThreeObject: { onChange(_, state) { state.customLayerNeedsRepopulating = true }} | ||
}, | ||
@@ -307,8 +307,8 @@ | ||
} | ||
} | ||
obj.__globeObjType = 'custom'; // Add object type | ||
obj.__data = d; // Attach point data | ||
obj.__globeObjType = 'custom'; // Add object type | ||
obj.__data = d; // Attach point data | ||
state.customLayerG.add(d.__threeObj = obj); | ||
state.customLayerG.add(d.__threeObj = obj); | ||
} | ||
}); | ||
@@ -315,0 +315,0 @@ } |
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
435119
14
1
1212
49