// **** gl-matrix-min.js *** /** * @fileoverview gl-matrix - High performance matrix and vector operations * @author Brandon Jones * @author Colin MacKenzie IV * @version 2.2.1 */ /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ (function(e){"use strict";var t={};typeof exports=="undefined"?typeof define=="function"&&typeof define.amd=="object"&&define.amd?(t.exports={},define(function(){return t.exports})):t.exports=typeof window!="undefined"?window:e:t.exports=exports,function(e){if(!t)var t=1e-6;if(!n)var n=typeof Float32Array!="undefined"?Float32Array:Array;if(!r)var r=Math.random;var i={};i.setMatrixArrayType=function(e){n=e},typeof e!="undefined"&&(e.glMatrix=i);var s=Math.PI/180;i.toRadian=function(e){return e*s};var o={};o.create=function(){var e=new n(2);return e[0]=0,e[1]=0,e},o.clone=function(e){var t=new n(2);return t[0]=e[0],t[1]=e[1],t},o.fromValues=function(e,t){var r=new n(2);return r[0]=e,r[1]=t,r},o.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e},o.set=function(e,t,n){return e[0]=t,e[1]=n,e},o.add=function(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e},o.subtract=function(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e},o.sub=o.subtract,o.multiply=function(e,t,n){return e[0]=t[0]*n[0],e[1]=t[1]*n[1],e},o.mul=o.multiply,o.divide=function(e,t,n){return e[0]=t[0]/n[0],e[1]=t[1]/n[1],e},o.div=o.divide,o.min=function(e,t,n){return e[0]=Math.min(t[0],n[0]),e[1]=Math.min(t[1],n[1]),e},o.max=function(e,t,n){return e[0]=Math.max(t[0],n[0]),e[1]=Math.max(t[1],n[1]),e},o.scale=function(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e},o.scaleAndAdd=function(e,t,n,r){return e[0]=t[0]+n[0]*r,e[1]=t[1]+n[1]*r,e},o.distance=function(e,t){var n=t[0]-e[0],r=t[1]-e[1];return Math.sqrt(n*n+r*r)},o.dist=o.distance,o.squaredDistance=function(e,t){var n=t[0]-e[0],r=t[1]-e[1];return n*n+r*r},o.sqrDist=o.squaredDistance,o.length=function(e){var t=e[0],n=e[1];return Math.sqrt(t*t+n*n)},o.len=o.length,o.squaredLength=function(e){var t=e[0],n=e[1];return t*t+n*n},o.sqrLen=o.squaredLength,o.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e},o.normalize=function(e,t){var n=t[0],r=t[1],i=n*n+r*r;return i>0&&(i=1/Math.sqrt(i),e[0]=t[0]*i,e[1]=t[1]*i),e},o.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]},o.cross=function(e,t,n){var r=t[0]*n[1]-t[1]*n[0];return e[0]=e[1]=0,e[2]=r,e},o.lerp=function(e,t,n,r){var i=t[0],s=t[1];return e[0]=i+r*(n[0]-i),e[1]=s+r*(n[1]-s),e},o.random=function(e,t){t=t||1;var n=r()*2*Math.PI;return e[0]=Math.cos(n)*t,e[1]=Math.sin(n)*t,e},o.transformMat2=function(e,t,n){var r=t[0],i=t[1];return e[0]=n[0]*r+n[2]*i,e[1]=n[1]*r+n[3]*i,e},o.transformMat2d=function(e,t,n){var r=t[0],i=t[1];return e[0]=n[0]*r+n[2]*i+n[4],e[1]=n[1]*r+n[3]*i+n[5],e},o.transformMat3=function(e,t,n){var r=t[0],i=t[1];return e[0]=n[0]*r+n[3]*i+n[6],e[1]=n[1]*r+n[4]*i+n[7],e},o.transformMat4=function(e,t,n){var r=t[0],i=t[1];return e[0]=n[0]*r+n[4]*i+n[12],e[1]=n[1]*r+n[5]*i+n[13],e},o.forEach=function(){var e=o.create();return function(t,n,r,i,s,o){var u,a;n||(n=2),r||(r=0),i?a=Math.min(i*n+r,t.length):a=t.length;for(u=r;u0&&(s=1/Math.sqrt(s),e[0]=t[0]*s,e[1]=t[1]*s,e[2]=t[2]*s),e},u.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]},u.cross=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=n[0],u=n[1],a=n[2];return e[0]=i*a-s*u,e[1]=s*o-r*a,e[2]=r*u-i*o,e},u.lerp=function(e,t,n,r){var i=t[0],s=t[1],o=t[2];return e[0]=i+r*(n[0]-i),e[1]=s+r*(n[1]-s),e[2]=o+r*(n[2]-o),e},u.random=function(e,t){t=t||1;var n=r()*2*Math.PI,i=r()*2-1,s=Math.sqrt(1-i*i)*t;return e[0]=Math.cos(n)*s,e[1]=Math.sin(n)*s,e[2]=i*t,e},u.transformMat4=function(e,t,n){var r=t[0],i=t[1],s=t[2];return e[0]=n[0]*r+n[4]*i+n[8]*s+n[12],e[1]=n[1]*r+n[5]*i+n[9]*s+n[13],e[2]=n[2]*r+n[6]*i+n[10]*s+n[14],e},u.transformMat3=function(e,t,n){var r=t[0],i=t[1],s=t[2];return e[0]=r*n[0]+i*n[3]+s*n[6],e[1]=r*n[1]+i*n[4]+s*n[7],e[2]=r*n[2]+i*n[5]+s*n[8],e},u.transformQuat=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=n[0],u=n[1],a=n[2],f=n[3],l=f*r+u*s-a*i,c=f*i+a*r-o*s,h=f*s+o*i-u*r,p=-o*r-u*i-a*s;return e[0]=l*f+p*-o+c*-a-h*-u,e[1]=c*f+p*-u+h*-o-l*-a,e[2]=h*f+p*-a+l*-u-c*-o,e},u.rotateX=function(e,t,n,r){var i=[],s=[];return i[0]=t[0]-n[0],i[1]=t[1]-n[1],i[2]=t[2]-n[2],s[0]=i[0],s[1]=i[1]*Math.cos(r)-i[2]*Math.sin(r),s[2]=i[1]*Math.sin(r)+i[2]*Math.cos(r),e[0]=s[0]+n[0],e[1]=s[1]+n[1],e[2]=s[2]+n[2],e},u.rotateY=function(e,t,n,r){var i=[],s=[];return i[0]=t[0]-n[0],i[1]=t[1]-n[1],i[2]=t[2]-n[2],s[0]=i[2]*Math.sin(r)+i[0]*Math.cos(r),s[1]=i[1],s[2]=i[2]*Math.cos(r)-i[0]*Math.sin(r),e[0]=s[0]+n[0],e[1]=s[1]+n[1],e[2]=s[2]+n[2],e},u.rotateZ=function(e,t,n,r){var i=[],s=[];return i[0]=t[0]-n[0],i[1]=t[1]-n[1],i[2]=t[2]-n[2],s[0]=i[0]*Math.cos(r)-i[1]*Math.sin(r),s[1]=i[0]*Math.sin(r)+i[1]*Math.cos(r),s[2]=i[2],e[0]=s[0]+n[0],e[1]=s[1]+n[1],e[2]=s[2]+n[2],e},u.forEach=function(){var e=u.create();return function(t,n,r,i,s,o){var u,a;n||(n=3),r||(r=0),i?a=Math.min(i*n+r,t.length):a=t.length;for(u=r;u0&&(o=1/Math.sqrt(o),e[0]=t[0]*o,e[1]=t[1]*o,e[2]=t[2]*o,e[3]=t[3]*o),e},a.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]},a.lerp=function(e,t,n,r){var i=t[0],s=t[1],o=t[2],u=t[3];return e[0]=i+r*(n[0]-i),e[1]=s+r*(n[1]-s),e[2]=o+r*(n[2]-o),e[3]=u+r*(n[3]-u),e},a.random=function(e,t){return t=t||1,e[0]=r(),e[1]=r(),e[2]=r(),e[3]=r(),a.normalize(e,e),a.scale(e,e,t),e},a.transformMat4=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=t[3];return e[0]=n[0]*r+n[4]*i+n[8]*s+n[12]*o,e[1]=n[1]*r+n[5]*i+n[9]*s+n[13]*o,e[2]=n[2]*r+n[6]*i+n[10]*s+n[14]*o,e[3]=n[3]*r+n[7]*i+n[11]*s+n[15]*o,e},a.transformQuat=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=n[0],u=n[1],a=n[2],f=n[3],l=f*r+u*s-a*i,c=f*i+a*r-o*s,h=f*s+o*i-u*r,p=-o*r-u*i-a*s;return e[0]=l*f+p*-o+c*-a-h*-u,e[1]=c*f+p*-u+h*-o-l*-a,e[2]=h*f+p*-a+l*-u-c*-o,e},a.forEach=function(){var e=a.create();return function(t,n,r,i,s,o){var u,a;n||(n=4),r||(r=0),i?a=Math.min(i*n+r,t.length):a=t.length;for(u=r;u.999999?(r[0]=0,r[1]=0,r[2]=0,r[3]=1,r):(u.cross(e,i,s),r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=1+o,p.normalize(r,r))}}(),p.setAxes=function(){var e=c.create();return function(t,n,r,i){return e[0]=r[0],e[3]=r[1],e[6]=r[2],e[1]=i[0],e[4]=i[1],e[7]=i[2],e[2]=-n[0],e[5]=-n[1],e[8]=-n[2],p.normalize(t,p.fromMat3(t,e))}}(),p.clone=a.clone,p.fromValues=a.fromValues,p.copy=a.copy,p.set=a.set,p.identity=function(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e},p.setAxisAngle=function(e,t,n){n*=.5;var r=Math.sin(n);return e[0]=r*t[0],e[1]=r*t[1],e[2]=r*t[2],e[3]=Math.cos(n),e},p.add=a.add,p.multiply=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=t[3],u=n[0],a=n[1],f=n[2],l=n[3];return e[0]=r*l+o*u+i*f-s*a,e[1]=i*l+o*a+s*u-r*f,e[2]=s*l+o*f+r*a-i*u,e[3]=o*l-r*u-i*a-s*f,e},p.mul=p.multiply,p.scale=a.scale,p.rotateX=function(e,t,n){n*=.5;var r=t[0],i=t[1],s=t[2],o=t[3],u=Math.sin(n),a=Math.cos(n);return e[0]=r*a+o*u,e[1]=i*a+s*u,e[2]=s*a-i*u,e[3]=o*a-r*u,e},p.rotateY=function(e,t,n){n*=.5;var r=t[0],i=t[1],s=t[2],o=t[3],u=Math.sin(n),a=Math.cos(n);return e[0]=r*a-s*u,e[1]=i*a+o*u,e[2]=s*a+r*u,e[3]=o*a-i*u,e},p.rotateZ=function(e,t,n){n*=.5;var r=t[0],i=t[1],s=t[2],o=t[3],u=Math.sin(n),a=Math.cos(n);return e[0]=r*a+i*u,e[1]=i*a-r*u,e[2]=s*a+o*u,e[3]=o*a-s*u,e},p.calculateW=function(e,t){var n=t[0],r=t[1],i=t[2];return e[0]=n,e[1]=r,e[2]=i,e[3]=-Math.sqrt(Math.abs(1-n*n-r*r-i*i)),e},p.dot=a.dot,p.lerp=a.lerp,p.slerp=function(e,t,n,r){var i=t[0],s=t[1],o=t[2],u=t[3],a=n[0],f=n[1],l=n[2],c=n[3],h,p,d,v,m;return p=i*a+s*f+o*l+u*c,p<0&&(p=-p,a=-a,f=-f,l=-l,c=-c),1-p>1e-6?(h=Math.acos(p),d=Math.sin(h),v=Math.sin((1-r)*h)/d,m=Math.sin(r*h)/d):(v=1-r,m=r),e[0]=v*i+m*a,e[1]=v*s+m*f,e[2]=v*o+m*l,e[3]=v*u+m*c,e},p.invert=function(e,t){var n=t[0],r=t[1],i=t[2],s=t[3],o=n*n+r*r+i*i+s*s,u=o?1/o:0;return e[0]=-n*u,e[1]=-r*u,e[2]=-i*u,e[3]=s*u,e},p.conjugate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e},p.length=a.length,p.len=p.length,p.squaredLength=a.squaredLength,p.sqrLen=p.squaredLength,p.normalize=a.normalize,p.fromMat3=function(e,t){var n=t[0]+t[4]+t[8],r;if(n>0)r=Math.sqrt(n+1),e[3]=.5*r,r=.5/r,e[0]=(t[7]-t[5])*r,e[1]=(t[2]-t[6])*r,e[2]=(t[3]-t[1])*r;else{var i=0;t[4]>t[0]&&(i=1),t[8]>t[i*3+i]&&(i=2);var s=(i+1)%3,o=(i+2)%3;r=Math.sqrt(t[i*3+i]-t[s*3+s]-t[o*3+o]+1),e[i]=.5*r,r=.5/r,e[3]=(t[o*3+s]-t[s*3+o])*r,e[s]=(t[s*3+i]+t[i*3+s])*r,e[o]=(t[o*3+i]+t[i*3+o])*r}return e},p.str=function(e){return"quat("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+")"},typeof e!="undefined"&&(e.quat=p)}(t.exports)})(this); // **** end gl-matrix-min.js *** // **** spin.min.js *** //fgnass.github.com/spin.js#v2.1.0 !function(a,b){"object"==typeof exports?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Spinner=b()}(this,function(){"use strict";function a(a,b){var c,d=document.createElement(a||"div");for(c in b)d[c]=b[c];return d}function b(a){for(var b=1,c=arguments.length;c>b;b++)a.appendChild(arguments[b]);return a}function c(a,b,c,d){var e=["opacity",b,~~(100*a),c,d].join("-"),f=.01+c/d*100,g=Math.max(1-(1-a)/b*(100-f),a),h=j.substring(0,j.indexOf("Animation")).toLowerCase(),i=h&&"-"+h+"-"||"";return m[e]||(k.insertRule("@"+i+"keyframes "+e+"{0%{opacity:"+g+"}"+f+"%{opacity:"+a+"}"+(f+.01)+"%{opacity:1}"+(f+b)%100+"%{opacity:"+a+"}100%{opacity:"+g+"}}",k.cssRules.length),m[e]=1),e}function d(a,b){var c,d,e=a.style;for(b=b.charAt(0).toUpperCase()+b.slice(1),d=0;d',c)}k.addRule(".spin-vml","behavior:url(#default#VML)"),h.prototype.lines=function(a,d){function f(){return e(c("group",{coordsize:k+" "+k,coordorigin:-j+" "+-j}),{width:k,height:k})}function h(a,h,i){b(m,b(e(f(),{rotation:360/d.lines*a+"deg",left:~~h}),b(e(c("roundrect",{arcsize:d.corners}),{width:j,height:d.scale*d.width,left:d.scale*d.radius,top:-d.scale*d.width>>1,filter:i}),c("fill",{color:g(d.color,a),opacity:d.opacity}),c("stroke",{opacity:0}))))}var i,j=d.scale*(d.length+d.width),k=2*d.scale*j,l=-(d.width+d.length)*d.scale*2+"px",m=e(f(),{position:"absolute",top:l,left:l});if(d.shadow)for(i=1;i<=d.lines;i++)h(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=d.lines;i++)h(i);return b(a,m)},h.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d>1)+"px"})}for(var i,k=0,l=(f.lines-1)*(1-f.direction)/2;k=0&&n.splice(r,1),t.className=n.join(" ")}n.add=function(t,e){t.classList?t.classList.add(e):r(t,e)},n.remove=function(t,e){t.classList?t.classList.remove(e):o(t,e)},n.list=function(t){return t.classList?Array.prototype.slice.apply(t.classList):t.className.split(" ")}},{}],3:[function(t,e,n){"use strict";function r(t,e){return window.getComputedStyle(t)[e]}function o(t,e,n){return"number"==typeof n&&(n=n.toString()+"px"),t.style[e]=n,t}function i(t,e){for(var n in e){var r=e[n];"number"==typeof r&&(r=r.toString()+"px"),t.style[n]=r}return t}var l={};l.e=function(t,e){var n=document.createElement(t);return n.className=e,n},l.appendTo=function(t,e){return e.appendChild(t),t},l.css=function(t,e,n){return"object"==typeof e?i(t,e):"undefined"==typeof n?r(t,e):o(t,e,n)},l.matches=function(t,e){return"undefined"!=typeof t.matches?t.matches(e):"undefined"!=typeof t.matchesSelector?t.matchesSelector(e):"undefined"!=typeof t.webkitMatchesSelector?t.webkitMatchesSelector(e):"undefined"!=typeof t.mozMatchesSelector?t.mozMatchesSelector(e):"undefined"!=typeof t.msMatchesSelector?t.msMatchesSelector(e):void 0},l.remove=function(t){"undefined"!=typeof t.remove?t.remove():t.parentNode&&t.parentNode.removeChild(t)},l.queryChildren=function(t,e){return Array.prototype.filter.call(t.childNodes,function(t){return l.matches(t,e)})},e.exports=l},{}],4:[function(t,e,n){"use strict";var r=function(t){this.element=t,this.events={}};r.prototype.bind=function(t,e){"undefined"==typeof this.events[t]&&(this.events[t]=[]),this.events[t].push(e),this.element.addEventListener(t,e,!1)},r.prototype.unbind=function(t,e){var n="undefined"!=typeof e;this.events[t]=this.events[t].filter(function(r){return n&&r!==e?!0:(this.element.removeEventListener(t,r,!1),!1)},this)},r.prototype.unbindAll=function(){for(var t in this.events)this.unbind(t)};var o=function(){this.eventElements=[]};o.prototype.eventElement=function(t){var e=this.eventElements.filter(function(e){return e.element===t})[0];return"undefined"==typeof e&&(e=new r(t),this.eventElements.push(e)),e},o.prototype.bind=function(t,e,n){this.eventElement(t).bind(e,n)},o.prototype.unbind=function(t,e,n){this.eventElement(t).unbind(e,n)},o.prototype.unbindAll=function(){for(var t=0;tu?u=0:u>1&&(u=1),s(t,"top",(e.contentHeight-e.containerHeight)*u),l(t),r.stopPropagation()}),e.settings.stopPropagationOnClick&&e.event.bind(e.scrollbarX,"click",r),e.event.bind(e.scrollbarXRail,"click",function(r){var i=o.toInt(e.scrollbarXWidth/2),a=e.railXRatio*(r.pageX-window.pageXOffset-n(e.scrollbarXRail).left-i),c=e.railXRatio*(e.railXWidth-e.scrollbarXWidth),u=a/c;0>u?u=0:u>1&&(u=1),s(t,"left",(e.contentWidth-e.containerWidth)*u-e.negativeScrollAdjustment),l(t),r.stopPropagation()})}var o=t("../../lib/helper"),i=t("../instances"),l=t("../update-geometry"),s=t("../update-scroll");e.exports=function(t){var e=i.get(t);r(t,e)}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(t,e,n){"use strict";function r(t,e){function n(n){var o=r+n*e.railXRatio,i=Math.max(0,e.scrollbarXRail.getBoundingClientRect().left)+e.railXRatio*(e.railXWidth-e.scrollbarXWidth);0>o?e.scrollbarXLeft=0:o>i?e.scrollbarXLeft=i:e.scrollbarXLeft=o;var s=l.toInt(e.scrollbarXLeft*(e.contentWidth-e.containerWidth)/(e.containerWidth-e.railXRatio*e.scrollbarXWidth))-e.negativeScrollAdjustment;c(t,"left",s)}var r=null,o=null,s=function(e){n(e.pageX-o),a(t),e.stopPropagation(),e.preventDefault()},u=function(){l.stopScrolling(t,"x"),e.event.unbind(e.ownerDocument,"mousemove",s)};e.event.bind(e.scrollbarX,"mousedown",function(n){o=n.pageX,r=l.toInt(i.css(e.scrollbarX,"left"))*e.railXRatio,l.startScrolling(t,"x"),e.event.bind(e.ownerDocument,"mousemove",s),e.event.once(e.ownerDocument,"mouseup",u),n.stopPropagation(),n.preventDefault()})}function o(t,e){function n(n){var o=r+n*e.railYRatio,i=Math.max(0,e.scrollbarYRail.getBoundingClientRect().top)+e.railYRatio*(e.railYHeight-e.scrollbarYHeight);0>o?e.scrollbarYTop=0:o>i?e.scrollbarYTop=i:e.scrollbarYTop=o;var s=l.toInt(e.scrollbarYTop*(e.contentHeight-e.containerHeight)/(e.containerHeight-e.railYRatio*e.scrollbarYHeight));c(t,"top",s)}var r=null,o=null,s=function(e){n(e.pageY-o),a(t),e.stopPropagation(),e.preventDefault()},u=function(){l.stopScrolling(t,"y"),e.event.unbind(e.ownerDocument,"mousemove",s)};e.event.bind(e.scrollbarY,"mousedown",function(n){o=n.pageY,r=l.toInt(i.css(e.scrollbarY,"top"))*e.railYRatio,l.startScrolling(t,"y"),e.event.bind(e.ownerDocument,"mousemove",s),e.event.once(e.ownerDocument,"mouseup",u),n.stopPropagation(),n.preventDefault()})}var i=t("../../lib/dom"),l=t("../../lib/helper"),s=t("../instances"),a=t("../update-geometry"),c=t("../update-scroll");e.exports=function(t){var e=s.get(t);r(t,e),o(t,e)}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(t,e,n){"use strict";function r(t,e){function n(n,r){var o=t.scrollTop;if(0===n){if(!e.scrollbarYActive)return!1;if(0===o&&r>0||o>=e.contentHeight-e.containerHeight&&0>r)return!e.settings.wheelPropagation}var i=t.scrollLeft;if(0===r){if(!e.scrollbarXActive)return!1;if(0===i&&0>n||i>=e.contentWidth-e.containerWidth&&n>0)return!e.settings.wheelPropagation}return!0}var r=!1;e.event.bind(t,"mouseenter",function(){r=!0}),e.event.bind(t,"mouseleave",function(){r=!1});var i=!1;e.event.bind(e.ownerDocument,"keydown",function(a){if((!a.isDefaultPrevented||!a.isDefaultPrevented())&&r){var c=document.activeElement?document.activeElement:e.ownerDocument.activeElement;if(c){for(;c.shadowRoot;)c=c.shadowRoot.activeElement;if(o.isEditable(c))return}var u=0,d=0;switch(a.which){case 37:u=-30;break;case 38:d=30;break;case 39:u=30;break;case 40:d=-30;break;case 33:d=90;break;case 32:d=a.shiftKey?90:-90;break;case 34:d=-90;break;case 35:d=a.ctrlKey?-e.contentHeight:-e.containerHeight;break;case 36:d=a.ctrlKey?t.scrollTop:e.containerHeight;break;default:return}s(t,"top",t.scrollTop-d),s(t,"left",t.scrollLeft+u),l(t),i=n(u,d),i&&a.preventDefault()}})}var o=t("../../lib/helper"),i=t("../instances"),l=t("../update-geometry"),s=t("../update-scroll");e.exports=function(t){var e=i.get(t);r(t,e)}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(t,e,n){"use strict";function r(t,e){function n(n,r){var o=t.scrollTop;if(0===n){if(!e.scrollbarYActive)return!1;if(0===o&&r>0||o>=e.contentHeight-e.containerHeight&&0>r)return!e.settings.wheelPropagation}var i=t.scrollLeft;if(0===r){if(!e.scrollbarXActive)return!1;if(0===i&&0>n||i>=e.contentWidth-e.containerWidth&&n>0)return!e.settings.wheelPropagation}return!0}function r(t){var e=t.deltaX,n=-1*t.deltaY;return("undefined"==typeof e||"undefined"==typeof n)&&(e=-1*t.wheelDeltaX/6,n=t.wheelDeltaY/6),t.deltaMode&&1===t.deltaMode&&(e*=10,n*=10),e!==e&&n!==n&&(e=0,n=t.wheelDelta),[e,n]}function o(e,n){var r=t.querySelector("textarea:hover");if(r){var o=r.scrollHeight-r.clientHeight;if(o>0&&!(0===r.scrollTop&&n>0||r.scrollTop===o&&0>n))return!0;var i=r.scrollLeft-r.clientWidth;if(i>0&&!(0===r.scrollLeft&&0>e||r.scrollLeft===i&&e>0))return!0}return!1}function s(s){var c=r(s),u=c[0],d=c[1];o(u,d)||(a=!1,e.settings.useBothWheelAxes?e.scrollbarYActive&&!e.scrollbarXActive?(d?l(t,"top",t.scrollTop-d*e.settings.wheelSpeed):l(t,"top",t.scrollTop+u*e.settings.wheelSpeed),a=!0):e.scrollbarXActive&&!e.scrollbarYActive&&(u?l(t,"left",t.scrollLeft+u*e.settings.wheelSpeed):l(t,"left",t.scrollLeft-d*e.settings.wheelSpeed),a=!0):(l(t,"top",t.scrollTop-d*e.settings.wheelSpeed),l(t,"left",t.scrollLeft+u*e.settings.wheelSpeed)),i(t),a=a||n(u,d),a&&(s.stopPropagation(),s.preventDefault()))}var a=!1;"undefined"!=typeof window.onwheel?e.event.bind(t,"wheel",s):"undefined"!=typeof window.onmousewheel&&e.event.bind(t,"mousewheel",s)}var o=t("../instances"),i=t("../update-geometry"),l=t("../update-scroll");e.exports=function(t){var e=o.get(t);r(t,e)}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(t,e,n){"use strict";function r(t,e){e.event.bind(t,"scroll",function(){i(t)})}var o=t("../instances"),i=t("../update-geometry");e.exports=function(t){var e=o.get(t);r(t,e)}},{"../instances":18,"../update-geometry":19}],15:[function(t,e,n){"use strict";function r(t,e){function n(){var t=window.getSelection?window.getSelection():document.getSelection?document.getSelection():"";return 0===t.toString().length?null:t.getRangeAt(0).commonAncestorContainer}function r(){c||(c=setInterval(function(){return i.get(t)?(s(t,"top",t.scrollTop+u.top),s(t,"left",t.scrollLeft+u.left),void l(t)):void clearInterval(c)},50))}function a(){c&&(clearInterval(c),c=null),o.stopScrolling(t)}var c=null,u={top:0,left:0},d=!1;e.event.bind(e.ownerDocument,"selectionchange",function(){t.contains(n())?d=!0:(d=!1,a())}),e.event.bind(window,"mouseup",function(){d&&(d=!1,a())}),e.event.bind(window,"mousemove",function(e){if(d){var n={x:e.pageX,y:e.pageY},i={left:t.offsetLeft,right:t.offsetLeft+t.offsetWidth,top:t.offsetTop,bottom:t.offsetTop+t.offsetHeight};n.xi.right-3?(u.left=5,o.startScrolling(t,"x")):u.left=0,n.yi.bottom-3?(n.y-i.bottom+3<5?u.top=5:u.top=20,o.startScrolling(t,"y")):u.top=0,0===u.top&&0===u.left?a():r()}})}var o=t("../../lib/helper"),i=t("../instances"),l=t("../update-geometry"),s=t("../update-scroll");e.exports=function(t){var e=i.get(t);r(t,e)}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(t,e,n){"use strict";function r(t,e,n,r){function s(n,r){var o=t.scrollTop,i=t.scrollLeft,l=Math.abs(n),s=Math.abs(r);if(s>l){if(0>r&&o===e.contentHeight-e.containerHeight||r>0&&0===o)return!e.settings.swipePropagation}else if(l>s&&(0>n&&i===e.contentWidth-e.containerWidth||n>0&&0===i))return!e.settings.swipePropagation;return!0}function a(e,n){l(t,"top",t.scrollTop-n),l(t,"left",t.scrollLeft-e),i(t)}function c(){Y=!0}function u(){Y=!1}function d(t){return t.targetTouches?t.targetTouches[0]:t}function p(t){return t.targetTouches&&1===t.targetTouches.length?!0:t.pointerType&&"mouse"!==t.pointerType&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE?!0:!1}function f(t){if(p(t)){w=!0;var e=d(t);b.pageX=e.pageX,b.pageY=e.pageY,g=(new Date).getTime(),null!==y&&clearInterval(y),t.stopPropagation()}}function h(t){if(!Y&&w&&p(t)){var e=d(t),n={pageX:e.pageX,pageY:e.pageY},r=n.pageX-b.pageX,o=n.pageY-b.pageY;a(r,o),b=n;var i=(new Date).getTime(),l=i-g;l>0&&(m.x=r/l,m.y=o/l,g=i),s(r,o)&&(t.stopPropagation(),t.preventDefault())}}function v(){!Y&&w&&(w=!1,clearInterval(y),y=setInterval(function(){return o.get(t)?Math.abs(m.x)<.01&&Math.abs(m.y)<.01?void clearInterval(y):(a(30*m.x,30*m.y),m.x*=.8,void(m.y*=.8)):void clearInterval(y)},10))}var b={},g=0,m={},y=null,Y=!1,w=!1;n&&(e.event.bind(window,"touchstart",c),e.event.bind(window,"touchend",u),e.event.bind(t,"touchstart",f),e.event.bind(t,"touchmove",h),e.event.bind(t,"touchend",v)),r&&(window.PointerEvent?(e.event.bind(window,"pointerdown",c),e.event.bind(window,"pointerup",u),e.event.bind(t,"pointerdown",f),e.event.bind(t,"pointermove",h),e.event.bind(t,"pointerup",v)):window.MSPointerEvent&&(e.event.bind(window,"MSPointerDown",c),e.event.bind(window,"MSPointerUp",u),e.event.bind(t,"MSPointerDown",f),e.event.bind(t,"MSPointerMove",h),e.event.bind(t,"MSPointerUp",v)))}var o=t("../instances"),i=t("../update-geometry"),l=t("../update-scroll");e.exports=function(t,e,n){var i=o.get(t);r(t,i,e,n)}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(t,e,n){"use strict";var r=t("../lib/class"),o=t("../lib/helper"),i=t("./instances"),l=t("./update-geometry"),s=t("./handler/click-rail"),a=t("./handler/drag-scrollbar"),c=t("./handler/keyboard"),u=t("./handler/mouse-wheel"),d=t("./handler/native-scroll"),p=t("./handler/selection"),f=t("./handler/touch");e.exports=function(t,e){e="object"==typeof e?e:{},r.add(t,"ps-container");var n=i.add(t);n.settings=o.extend(n.settings,e),s(t),a(t),u(t),d(t),n.settings.useSelectionScroll&&p(t),(o.env.supportsTouch||o.env.supportsIePointer)&&f(t,o.env.supportsTouch,o.env.supportsIePointer),n.settings.useKeyboard&&c(t),l(t)}},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(t,e,n){"use strict";function r(t){var e=this;e.settings=d.clone(a),e.containerWidth=null,e.containerHeight=null,e.contentWidth=null,e.contentHeight=null,e.isRtl="rtl"===s.css(t,"direction"),e.isNegativeScroll=function(){var e=t.scrollLeft,n=null;return t.scrollLeft=-1,n=t.scrollLeft<0,t.scrollLeft=e,n}(),e.negativeScrollAdjustment=e.isNegativeScroll?t.scrollWidth-t.clientWidth:0,e.event=new c,e.ownerDocument=t.ownerDocument||document,e.scrollbarXRail=s.appendTo(s.e("div","ps-scrollbar-x-rail"),t),e.scrollbarX=s.appendTo(s.e("div","ps-scrollbar-x"),e.scrollbarXRail),e.scrollbarX.setAttribute("tabindex",0),e.scrollbarXActive=null,e.scrollbarXWidth=null,e.scrollbarXLeft=null,e.scrollbarXBottom=d.toInt(s.css(e.scrollbarXRail,"bottom")),e.isScrollbarXUsingBottom=e.scrollbarXBottom===e.scrollbarXBottom,e.scrollbarXTop=e.isScrollbarXUsingBottom?null:d.toInt(s.css(e.scrollbarXRail,"top")),e.railBorderXWidth=d.toInt(s.css(e.scrollbarXRail,"borderLeftWidth"))+d.toInt(s.css(e.scrollbarXRail,"borderRightWidth")),s.css(e.scrollbarXRail,"display","block"),e.railXMarginWidth=d.toInt(s.css(e.scrollbarXRail,"marginLeft"))+d.toInt(s.css(e.scrollbarXRail,"marginRight")),s.css(e.scrollbarXRail,"display",""),e.railXWidth=null,e.railXRatio=null,e.scrollbarYRail=s.appendTo(s.e("div","ps-scrollbar-y-rail"),t),e.scrollbarY=s.appendTo(s.e("div","ps-scrollbar-y"),e.scrollbarYRail),e.scrollbarY.setAttribute("tabindex",0),e.scrollbarYActive=null,e.scrollbarYHeight=null,e.scrollbarYTop=null,e.scrollbarYRight=d.toInt(s.css(e.scrollbarYRail,"right")),e.isScrollbarYUsingRight=e.scrollbarYRight===e.scrollbarYRight,e.scrollbarYLeft=e.isScrollbarYUsingRight?null:d.toInt(s.css(e.scrollbarYRail,"left")),e.scrollbarYOuterWidth=e.isRtl?d.outerWidth(e.scrollbarY):null,e.railBorderYWidth=d.toInt(s.css(e.scrollbarYRail,"borderTopWidth"))+d.toInt(s.css(e.scrollbarYRail,"borderBottomWidth")),s.css(e.scrollbarYRail,"display","block"),e.railYMarginHeight=d.toInt(s.css(e.scrollbarYRail,"marginTop"))+d.toInt(s.css(e.scrollbarYRail,"marginBottom")),s.css(e.scrollbarYRail,"display",""),e.railYHeight=null,e.railYRatio=null}function o(t){return"undefined"==typeof t.dataset?t.getAttribute("data-ps-id"):t.dataset.psId}function i(t,e){"undefined"==typeof t.dataset?t.setAttribute("data-ps-id",e):t.dataset.psId=e}function l(t){"undefined"==typeof t.dataset?t.removeAttribute("data-ps-id"):delete t.dataset.psId}var s=t("../lib/dom"),a=t("./default-setting"),c=t("../lib/event-manager"),u=t("../lib/guid"),d=t("../lib/helper"),p={};n.add=function(t){var e=u();return i(t,e),p[e]=new r(t),p[e]},n.remove=function(t){delete p[o(t)],l(t)},n.get=function(t){return p[o(t)]}},{"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(t,e,n){"use strict";function r(t,e){return t.settings.minScrollbarLength&&(e=Math.max(e,t.settings.minScrollbarLength)),t.settings.maxScrollbarLength&&(e=Math.min(e,t.settings.maxScrollbarLength)),e}function o(t,e){var n={width:e.railXWidth};e.isRtl?n.left=e.negativeScrollAdjustment+t.scrollLeft+e.containerWidth-e.contentWidth:n.left=t.scrollLeft,e.isScrollbarXUsingBottom?n.bottom=e.scrollbarXBottom-t.scrollTop:n.top=e.scrollbarXTop+t.scrollTop,l.css(e.scrollbarXRail,n);var r={top:t.scrollTop,height:e.railYHeight};e.isScrollbarYUsingRight?e.isRtl?r.right=e.contentWidth-(e.negativeScrollAdjustment+t.scrollLeft)-e.scrollbarYRight-e.scrollbarYOuterWidth:r.right=e.scrollbarYRight-t.scrollLeft:e.isRtl?r.left=e.negativeScrollAdjustment+t.scrollLeft+2*e.containerWidth-e.contentWidth-e.scrollbarYLeft-e.scrollbarYOuterWidth:r.left=e.scrollbarYLeft+t.scrollLeft,l.css(e.scrollbarYRail,r),l.css(e.scrollbarX,{left:e.scrollbarXLeft,width:e.scrollbarXWidth-e.railBorderXWidth}),l.css(e.scrollbarY,{top:e.scrollbarYTop,height:e.scrollbarYHeight-e.railBorderYWidth})}var i=t("../lib/class"),l=t("../lib/dom"),s=t("../lib/helper"),a=t("./instances"),c=t("./update-scroll");e.exports=function(t){var e=a.get(t);e.containerWidth=t.clientWidth,e.containerHeight=t.clientHeight,e.contentWidth=t.scrollWidth,e.contentHeight=t.scrollHeight;var n;t.contains(e.scrollbarXRail)||(n=l.queryChildren(t,".ps-scrollbar-x-rail"),n.length>0&&n.forEach(function(t){l.remove(t)}),l.appendTo(e.scrollbarXRail,t)),t.contains(e.scrollbarYRail)||(n=l.queryChildren(t,".ps-scrollbar-y-rail"),n.length>0&&n.forEach(function(t){l.remove(t)}),l.appendTo(e.scrollbarYRail,t)),!e.settings.suppressScrollX&&e.containerWidth+e.settings.scrollXMarginOffset=e.railXWidth-e.scrollbarXWidth&&(e.scrollbarXLeft=e.railXWidth-e.scrollbarXWidth),e.scrollbarYTop>=e.railYHeight-e.scrollbarYHeight&&(e.scrollbarYTop=e.railYHeight-e.scrollbarYHeight),o(t,e),e.scrollbarXActive?i.add(t,"ps-active-x"):(i.remove(t,"ps-active-x"),e.scrollbarXWidth=0,e.scrollbarXLeft=0,c(t,"left",0)),e.scrollbarYActive?i.add(t,"ps-active-y"):(i.remove(t,"ps-active-y"),e.scrollbarYHeight=0,e.scrollbarYTop=0,c(t,"top",0))}},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(t,e,n){"use strict";var r,o,i=t("./instances"),l=document.createEvent("Event"),s=document.createEvent("Event"),a=document.createEvent("Event"),c=document.createEvent("Event"),u=document.createEvent("Event"),d=document.createEvent("Event"),p=document.createEvent("Event"),f=document.createEvent("Event"),h=document.createEvent("Event"),v=document.createEvent("Event");l.initEvent("ps-scroll-up",!0,!0),s.initEvent("ps-scroll-down",!0,!0),a.initEvent("ps-scroll-left",!0,!0),c.initEvent("ps-scroll-right",!0,!0),u.initEvent("ps-scroll-y",!0,!0),d.initEvent("ps-scroll-x",!0,!0),p.initEvent("ps-x-reach-start",!0,!0),f.initEvent("ps-x-reach-end",!0,!0),h.initEvent("ps-y-reach-start",!0,!0),v.initEvent("ps-y-reach-end",!0,!0),e.exports=function(t,e,n){if("undefined"==typeof t)throw"You must provide an element to the update-scroll function";if("undefined"==typeof e)throw"You must provide an axis to the update-scroll function";if("undefined"==typeof n)throw"You must provide a value to the update-scroll function";if("top"===e&&0>=n)return t.scrollTop=0,void t.dispatchEvent(h);if("left"===e&&0>=n)return t.scrollLeft=0,void t.dispatchEvent(p);var b=i.get(t);return"top"===e&&n>=b.contentHeight-b.containerHeight?(t.scrollTop=b.contentHeight-b.containerHeight,void t.dispatchEvent(v)):"left"===e&&n>=b.contentWidth-b.containerWidth?(t.scrollLeft=b.contentWidth-b.containerWidth,void t.dispatchEvent(f)):(r||(r=t.scrollTop),o||(o=t.scrollLeft),"top"===e&&r>n&&t.dispatchEvent(l),"top"===e&&n>r&&t.dispatchEvent(s),"left"===e&&o>n&&t.dispatchEvent(a),"left"===e&&n>o&&t.dispatchEvent(c),"top"===e&&(t.scrollTop=r=n,t.dispatchEvent(u)),void("left"===e&&(t.scrollLeft=o=n,t.dispatchEvent(d))))}},{"./instances":18}],21:[function(t,e,n){"use strict";var r=t("../lib/dom"),o=t("../lib/helper"),i=t("./instances"),l=t("./update-geometry"),s=t("./update-scroll");e.exports=function(t){var e=i.get(t);e&&(e.negativeScrollAdjustment=e.isNegativeScroll?t.scrollWidth-t.clientWidth:0,r.css(e.scrollbarXRail,"display","block"),r.css(e.scrollbarYRail,"display","block"),e.railXMarginWidth=o.toInt(r.css(e.scrollbarXRail,"marginLeft"))+o.toInt(r.css(e.scrollbarXRail,"marginRight")),e.railYMarginHeight=o.toInt(r.css(e.scrollbarYRail,"marginTop"))+o.toInt(r.css(e.scrollbarYRail,"marginBottom")),r.css(e.scrollbarXRail,"display","none"),r.css(e.scrollbarYRail,"display","none"),l(t),s(t,"top",t.scrollTop),s(t,"left",t.scrollLeft),r.css(e.scrollbarXRail,"display",""),r.css(e.scrollbarYRail,"display",""))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]); // **** end perfect-scrollbar.jquery.min.js *** // **** shader-loader.js *** (function() { var shaderLoader = {}; shaderLoader.getShaderCode = function(name) { for(var i=0; ili').mouseover(function () { clicked = false; var groupName = $(this).data('group'); if (groupName === '') { groups.clearSelect(); } else { if (!groups[groupName]) return groups.selectGroup(groups[groupName]); } }); $('#groups-display>li').click(function () { clicked = true; var groupName = $(this).data('group'); if (groupName === '') { groups.clearSelect(); $('#menu-groups .menu-title').text('分组'); $(this).css('display', 'none'); } else { if (!groups[groupName]) return selectSat(-1); //clear selected sat groups.selectGroup(groups[groupName]); searchBox.fillResultBox(groups[groupName].sats, ''); $('#menu-groups .clear-option').css({ display: 'block' }); $('#menu-groups .menu-title').text('分组 (' + $(this).text() + ')'); } $('#groups-display').css({ display: 'none' }); }); groups.StarlinkGroup = new SatGroup('nameRegex', /STARLINK/); groups.BeidouGroup = new SatGroup('nameRegex', /BEIDOU/); groups.GPSGroup = new SatGroup("intlDes", [ "2000-025A", "2000-071A", "2003-005A", "2003-010A", "2004-009A", "2004-045A", "2005-038A", "2006-042A", "2006-052A", "2007-047A", "2007-062A", "2008-012A", "2009-043A", "2010-022A", "2011-036A", "2012-053A", "2013-023A", "2014-008A", "2014-026A", "2014-045A", "2014-068A", "2015-013A", "2015-033A", "2015-062A", "2016-007A", "2018-109A", "2019-056A", "2020-041A", "2020-078A", "2021-054A", ]); groups.JiLiGroup = new SatGroup("intlDes", [ "2022-058A", "2022-058B", "2022-058C", "2022-058D", "2022-058E", "2022-058F", "2022-058G", "2022-058H", "2022-058J", "2024-023A", "2024-023B", "2024-023C", "2024-023D", "2024-023E", "2024-023F", "2024-023G", "2024-023H", "2024-023J", "2024-023K", "2024-023L", "2024-159A", "2024-159B", "2024-159C", "2024-159D", "2024-159E", "2024-159F", "2024-159G", "2024-159H", "2024-159J", "2024-159K", ]); groups.GlonassGroup = new SatGroup('nameRegex', /GLONASS/); groups.GalileoGroup = new SatGroup('nameRegex', /GALILEO/); groups.IridiumGroup = new SatGroup('nameRegex', /IRIDIUM(?!.*DEB)/); groups.Iridium33DebrisGroup = new SatGroup('nameRegex', /(COSMOS 2251|IRIDIUM 33) DEB/); groups.FunGroup = new SatGroup('nameRegex', /SYLDA/); groups.WestfordNeedlesGroup = new SatGroup('nameRegex', /WESTFORD NEEDLES/); groups.SpaceXGroup = new SatGroup('nameRegex', /FALCON [19]/); console.log('groups init: ' + (performance.now() - start) + ' ms'); }; window.groups = groups; })(); // **** end groups.js *** // **** search-box.js *** (function () { var searchBox = {}; var SEARCH_LIMIT = 5000; var satData; var hovering = false; var hoverSatId = -1; var resultsOpen = false; var lastResultGroup; searchBox.isResultBoxOpen = function () { return resultsOpen; }; searchBox.getLastResultGroup = function () { return lastResultGroup; }; searchBox.getCurrentSearch = function () { if (resultsOpen) { return $('#search').val(); } else { return null; } }; searchBox.isHovering = function () { return hovering; }; searchBox.getHoverSat = function () { return hoverSatId; }; searchBox.hideResults = function () { var sr = $('#search-results'); sr.slideUp(); groups.clearSelect(); resultsOpen = false; }; searchBox.doSearch = function (str) { selectSat(-1); if (str.length === 0) { searchBox.hideResults(); return; } var searchStart = performance.now(); str = str.toUpperCase(); var results = []; for (var i = 0; i < satData.length; i++) { if (satData[i].OBJECT_NAME.indexOf(str) !== -1) { results.push({ isIntlDes: false, strIndex: satData[i].OBJECT_NAME.indexOf(str), satId: i }); } if (satData[i].intlDes.indexOf(str) !== -1) { results.push({ isIntlDes: true, strIndex: satData[i].intlDes.indexOf(str), satId: i }); } } results.reverse(); if (results.length > SEARCH_LIMIT) { results.length = SEARCH_LIMIT; } //make a group to hilight results var idList = []; for (var i = 0; i < results.length; i++) { idList.push(results[i].satId); } var dispGroup = new groups.SatGroup('idList', idList); lastResultGroup = dispGroup; groups.selectGroup(dispGroup); searchBox.fillResultBox(results, str); updateUrl(); }; searchBox.fillResultBox = function (results, searchStr) { // results: // [ // { sat: { id: , } } // ] var resultBox = $('#search-results'); var html = ''; for (var i = 0; i < results.length; i++) { var sat = satData[results[i].satId]; html += '
'; if (results[i].isIntlDes) { html += sat.OBJECT_NAME; } else { html += sat.OBJECT_NAME.substring(0, results[i].strIndex); html += ''; html += sat.OBJECT_NAME.substring(results[i].strIndex, results[i].strIndex + searchStr.length); html += ''; html += sat.OBJECT_NAME.substring(results[i].strIndex + searchStr.length); } html += '
'; if (results[i].isIntlDes) { html += sat.intlDes.substring(0, results[i].strIndex); html += ''; html += sat.intlDes.substring(results[i].strIndex, results[i].strIndex + searchStr.length); html += ''; html += sat.intlDes.substring(results[i].strIndex + searchStr.length); } else { html += sat.intlDes; } html += '
'; } var resultStart = performance.now(); // resultBox.append(html); resultBox[0].innerHTML = html; resultBox.slideDown(); resultsOpen = true; }; searchBox.init = function (_satData) { satData = _satData; $('#search-results').on('click', '.search-result', function (evt) { var satId = $(this).data('sat-id'); selectSat(satId); // hideResults(); }); $('#search-results').on('mouseover', '.search-result', function (evt) { var satId = $(this).data('sat-id'); orbitDisplay.setHoverOrbit(satId); satSet.setHover(satId); hovering = true; hoverSatId = satId; }); $('#search-results').mouseout(function () { orbitDisplay.clearHoverOrbit(); satSet.setHover(-1); // hoverBoxOnSat(-1); hovering = false; }); $('#search').on('input', function () { var initStart = performance.now(); var searchStr = $('#search').val() searchBox.doSearch(searchStr); }); $('#all-objects-link').click(function () { var intldes = satSet.getSat(selectedSat).intlDes; var searchStr = intldes.slice(0, 8); searchBox.doSearch(searchStr); $('#search').val(searchStr); }); }; window.searchBox = searchBox; })(); // **** end search-box.js *** // **** orbit-display.js *** /* global groups */ /* global satSet */ /* global mat4 */ /* global shaderLoader */ /* global gl */ (function () { var NUM_SEGS = 255; var glBuffers = []; var inProgress = []; var orbitDisplay = {}; var pathShader; var selectOrbitBuf; var hoverOrbitBuf; var currentHoverId = -1; var currentSelectId = -1; var orbitMvMat = mat4.create(); var orbitWorker = new Worker('/scripts/orbit-calculation-worker.js'); var initialized = false; var selectColor = [0.0, 1.0, 0.0, 1.0]; var hoverColor = [0.5, 0.5, 1.0, 1.0]; var groupColor = [0.3, 0.5, 1.0, 0.4]; orbitDisplay.init = function () { var startTime = performance.now(); var vs = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vs, shaderLoader.getShaderCode('path-vertex.glsl')); gl.compileShader(vs); var fs = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fs, shaderLoader.getShaderCode('path-fragment.glsl')); gl.compileShader(fs); pathShader = gl.createProgram(); gl.attachShader(pathShader, vs); gl.attachShader(pathShader, fs); gl.linkProgram(pathShader); pathShader.aPos = gl.getAttribLocation(pathShader, 'aPos'); pathShader.uMvMatrix = gl.getUniformLocation(pathShader, 'uMvMatrix'); pathShader.uCamMatrix = gl.getUniformLocation(pathShader, 'uCamMatrix'); pathShader.uPMatrix = gl.getUniformLocation(pathShader, 'uPMatrix'); pathShader.uColor = gl.getUniformLocation(pathShader, 'uColor'); selectOrbitBuf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, selectOrbitBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array((NUM_SEGS + 1) * 3), gl.STATIC_DRAW); hoverOrbitBuf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, hoverOrbitBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array((NUM_SEGS + 1) * 3), gl.STATIC_DRAW); for (var i = 0; i < satSet.numSats; i++) { glBuffers.push(allocateBuffer()); } orbitWorker.postMessage({ isInit: true, satData: satSet.satDataString, numSegs: NUM_SEGS }); initialized = true; var time = performance.now() - startTime; console.log('orbitDisplay init: ' + time + ' ms'); }; orbitDisplay.updateOrbitBuffer = function (satId) { if (!inProgress[satId]) { orbitWorker.postMessage({ isInit: false, satId: satId }); inProgress[satId] = true; } }; orbitWorker.onmessage = function (m) { var satId = m.data.satId; var pointsOut = new Float32Array(m.data.pointsOut); gl.bindBuffer(gl.ARRAY_BUFFER, glBuffers[satId]); gl.bufferData(gl.ARRAY_BUFFER, pointsOut, gl.DYNAMIC_DRAW); inProgress[satId] = false; }; /*orbitDisplay.setOrbit = function(satId) { var sat = satSet.getSat(satId); mat4.identity(orbitMvMat); //apply steps in reverse order because matrix multiplication // (last multiplied in is first applied to vertex) //step 5. rotate to RAAN mat4.rotateZ(orbitMvMat, orbitMvMat, sat.raan + Math.PI/2); //step 4. incline the plane mat4.rotateY(orbitMvMat, orbitMvMat, -sat.inclination); //step 3. rotate to argument of periapsis mat4.rotateZ(orbitMvMat, orbitMvMat, sat.argPe - Math.PI/2); //step 2. put earth at the focus mat4.translate(orbitMvMat, orbitMvMat, [sat.semiMajorAxis - sat.apogee - 6371, 0, 0]); //step 1. stretch to ellipse mat4.scale(orbitMvMat, orbitMvMat, [sat.semiMajorAxis, sat.semiMinorAxis, 0]); }; orbitDisplay.clearOrbit = function() { mat4.identity(orbitMvMat); }*/ orbitDisplay.setSelectOrbit = function (satId) { // var start = performance.now(); currentSelectId = satId; orbitDisplay.updateOrbitBuffer(satId); // console.log('setOrbit(): ' + (performance.now() - start) + ' ms'); }; orbitDisplay.clearSelectOrbit = function () { currentSelectId = -1; gl.bindBuffer(gl.ARRAY_BUFFER, selectOrbitBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array((NUM_SEGS + 1) * 3), gl.DYNAMIC_DRAW); }; orbitDisplay.setHoverOrbit = function (satId) { if (satId === currentHoverId) return; currentHoverId = satId; orbitDisplay.updateOrbitBuffer(satId); }; orbitDisplay.clearHoverOrbit = function (satId) { if (currentHoverId === -1) return; currentHoverId = -1; gl.bindBuffer(gl.ARRAY_BUFFER, hoverOrbitBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array((NUM_SEGS + 1) * 3), gl.DYNAMIC_DRAW); }; orbitDisplay.draw = function (pMatrix, camMatrix) { //lol what do I do here if (!initialized) return; gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.useProgram(pathShader); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.enable(gl.BLEND); // gl.depthMask(false); gl.uniformMatrix4fv(pathShader.uMvMatrix, false, orbitMvMat); gl.uniformMatrix4fv(pathShader.uCamMatrix, false, camMatrix); gl.uniformMatrix4fv(pathShader.uPMatrix, false, pMatrix); if (currentSelectId !== -1) { gl.uniform4fv(pathShader.uColor, selectColor); gl.bindBuffer(gl.ARRAY_BUFFER, glBuffers[currentSelectId]); gl.vertexAttribPointer(pathShader.aPos, 3, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.LINE_STRIP, 0, NUM_SEGS + 1); } if (currentHoverId !== -1 && currentHoverId !== currentSelectId) { //avoid z-fighting gl.uniform4fv(pathShader.uColor, hoverColor); gl.bindBuffer(gl.ARRAY_BUFFER, glBuffers[currentHoverId]); gl.vertexAttribPointer(pathShader.aPos, 3, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.LINE_STRIP, 0, NUM_SEGS + 1); } if (groups.selectedGroup !== null) { gl.uniform4fv(pathShader.uColor, groupColor); groups.selectedGroup.forEach(function (id) { gl.bindBuffer(gl.ARRAY_BUFFER, glBuffers[id]); gl.vertexAttribPointer(pathShader.aPos, 3, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.LINE_STRIP, 0, NUM_SEGS + 1); }); } // gl.depthMask(true); gl.disable(gl.BLEND); }; function allocateBuffer() { var buf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array((NUM_SEGS + 1) * 3), gl.STATIC_DRAW); return buf; } orbitDisplay.getPathShader = function () { return pathShader; }; window.orbitDisplay = orbitDisplay; })(); // **** end orbit-display.js *** // **** line.js *** /* global orbitDisplay */ (function () { function Line() { this.vertBuf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(6), gl.STREAM_DRAW); } Line.prototype.set = function (pt1, pt2) { var buf = []; buf.push(pt1[0]); buf.push(pt1[1]); buf.push(pt1[2]); buf.push(pt2[0]); buf.push(pt2[1]); buf.push(pt2[2]); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(buf), gl.STREAM_DRAW); }; Line.prototype.draw = function () { var shader = orbitDisplay.getPathShader(); gl.useProgram(shader); gl.uniform4fv(shader.uColor, [0.1, 0.0, 1.0, 0.1]); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertBuf); gl.vertexAttribPointer(shader.aPos, 3, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.LINES, 0, 2); }; window.Line = Line; })(); // **** end line.js *** // **** earth.js *** /* global satellite */ //earth.js (function() { var earth = {}; var R2D = 180 / Math.PI; var D2R = Math.PI / 180; var NUM_LAT_SEGS = 64; var NUM_LON_SEGS = 64; var pos = [3.0, 0.0, 1.0]; var radius = 6371.0; var vertPosBuf, vertNormBuf, texCoordBuf, vertIndexBuf; //GPU mem buffers, data and stuff? var vertCount; var earthShader; earth.pos = [0, 0, 0]; var texture, nightTexture; var texLoaded = false, nightLoaded = false; var loaded = false; function onImageLoaded() { if (texLoaded && nightLoaded) { loaded = true; $('#loader-text').text('系统加载中.....'); } } earth.init = function() { var startTime = new Date().getTime(); var fragShader = gl.createShader(gl.FRAGMENT_SHADER); var fragCode = shaderLoader.getShaderCode('earth-fragment.glsl'); gl.shaderSource(fragShader, fragCode); gl.compileShader(fragShader); var vertShader = gl.createShader(gl.VERTEX_SHADER); var vertCode = shaderLoader.getShaderCode('earth-vertex.glsl'); gl.shaderSource(vertShader, vertCode); gl.compileShader(vertShader); earthShader = gl.createProgram(); gl.attachShader(earthShader, vertShader); gl.attachShader(earthShader, fragShader); gl.linkProgram(earthShader); earthShader.aVertexPosition = gl.getAttribLocation(earthShader, 'aVertexPosition'); earthShader.aTexCoord = gl.getAttribLocation(earthShader, 'aTexCoord'); earthShader.aVertexNormal = gl.getAttribLocation(earthShader, 'aVertexNormal'); earthShader.uPMatrix = gl.getUniformLocation(earthShader, 'uPMatrix'); earthShader.uCamMatrix = gl.getUniformLocation(earthShader, 'uCamMatrix'); earthShader.uMvMatrix = gl.getUniformLocation(earthShader, 'uMvMatrix'); earthShader.uNormalMatrix = gl.getUniformLocation(earthShader, 'uNormalMatrix'); earthShader.uLightDirection = gl.getUniformLocation(earthShader, 'uLightDirection'); earthShader.uAmbientLightColor = gl.getUniformLocation(earthShader, 'uAmbientLightColor'); earthShader.uDirectionalLightColor = gl.getUniformLocation(earthShader, 'uDirectionalLightColor'); earthShader.uSampler = gl.getUniformLocation(earthShader, 'uSampler'); earthShader.uNightSampler = gl.getUniformLocation(earthShader, 'uNightSampler'); texture = gl.createTexture(); var img = new Image(); img.onload = function() { gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); console.log('earth.js loaded texture'); texLoaded = true; onImageLoaded(); }; img.src = '../mercator-tex.jpg'; // img.src = '/mercator-tex-512.jpg'; nightTexture = gl.createTexture(); var nightImg = new Image(); nightImg.onload = function() { gl.bindTexture(gl.TEXTURE_2D, nightTexture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nightImg); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); console.log('earth.js loaded nightearth'); nightLoaded = true; onImageLoaded(); }; nightImg.src = '../nightearth-4096.png'; // nightImg.src = '/nightearth-512.jpg'; //generate a uvsphere bottom up, CCW order var vertPos = []; var vertNorm = []; var texCoord = []; var i = 0; for (var lat = 0; lat <= NUM_LAT_SEGS; lat++) { var latAngle = (Math.PI / NUM_LAT_SEGS) * lat - (Math.PI / 2); var diskRadius = Math.cos(Math.abs(latAngle)); var z = Math.sin(latAngle); // console.log('LAT: ' + latAngle * R2D + ' , Z: ' + z); for (var lon = 0; lon <= NUM_LON_SEGS; lon++) { //add an extra vertex for texture funness var lonAngle = (Math.PI * 2 / NUM_LON_SEGS) * lon; var x = Math.cos(lonAngle) * diskRadius; var y = Math.sin(lonAngle) * diskRadius; // console.log('i: ' + i + ' LON: ' + lonAngle * R2D + ' X: ' + x + ' Y: ' + y) //mercator cylindrical projection (simple angle interpolation) var v = 1 - (lat / NUM_LAT_SEGS); var u = 0.5 + (lon / NUM_LON_SEGS); //may need to change to move map // console.log('u: ' + u + ' v: ' + v); //normals: should just be a vector from center to point (aka the point itself! vertPos.push(x * radius); vertPos.push(y * radius); vertPos.push(z * radius); texCoord.push(u); texCoord.push(v); vertNorm.push(x); vertNorm.push(y); vertNorm.push(z); i++; } } //ok let's calculate vertex draw orders.... indiv triangles var vertIndex = []; for (var lat = 0; lat < NUM_LAT_SEGS; lat++) { //this is for each QUAD, not each vertex, so < for (var lon = 0; lon < NUM_LON_SEGS; lon++) { var blVert = lat * (NUM_LON_SEGS + 1) + lon; //there's NUM_LON_SEGS + 1 verts in each horizontal band var brVert = blVert + 1; var tlVert = (lat + 1) * (NUM_LON_SEGS + 1) + lon; var trVert = tlVert + 1; // console.log('bl: ' + blVert + ' br: ' + brVert + ' tl: ' + tlVert + ' tr: ' + trVert); vertIndex.push(blVert); vertIndex.push(brVert); vertIndex.push(tlVert); vertIndex.push(tlVert); vertIndex.push(trVert); vertIndex.push(brVert); } } vertCount = vertIndex.length; vertPosBuf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertPosBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertPos), gl.STATIC_DRAW); vertNormBuf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertNormBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertNorm), gl.STATIC_DRAW); texCoordBuf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoord), gl.STATIC_DRAW); vertIndexBuf = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertIndexBuf); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertIndex), gl.STATIC_DRAW); var end = new Date().getTime() - startTime; console.log('earth init: ' + end + ' ms'); }; earth.draw = function(pMatrix, camMatrix) { if (!loaded) return; var now = new Date(); var j = jday(now.getUTCFullYear(), now.getUTCMonth() + 1, // Note, this function requires months in range 1-12. now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds()); j += now.getUTCMilliseconds() * 1.15741e-8; //days per millisecond var era = satellite.gstime_from_jday(j); var lightDirection = sun.currentDirection(); vec3.normalize(lightDirection, lightDirection); var mvMatrix = mat4.create(); mat4.identity(mvMatrix); mat4.rotateZ(mvMatrix, mvMatrix, era); mat4.translate(mvMatrix, mvMatrix, earth.pos); var nMatrix = mat3.create(); mat3.normalFromMat4(nMatrix, mvMatrix); gl.useProgram(earthShader); gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.uniformMatrix3fv(earthShader.uNormalMatrix, false, nMatrix); gl.uniformMatrix4fv(earthShader.uMvMatrix, false, mvMatrix); gl.uniformMatrix4fv(earthShader.uPMatrix, false, pMatrix); gl.uniformMatrix4fv(earthShader.uCamMatrix, false, camMatrix); gl.uniform3fv(earthShader.uLightDirection, lightDirection); gl.uniform3fv(earthShader.uAmbientLightColor, [0.03, 0.03, 0.03]); //RGB ambient light gl.uniform3fv(earthShader.uDirectionalLightColor, [1, 1, 0.9]); //RGB directional light gl.uniform1i(earthShader.uSampler, 0); //point sampler to TEXTURE0 gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture); //bind texture to TEXTURE0 gl.uniform1i(earthShader.uNightSampler, 1); //point sampler to TEXTURE1 gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, nightTexture); //bind tex to TEXTURE1 gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuf); gl.enableVertexAttribArray(earthShader.aTexCoord); gl.vertexAttribPointer(earthShader.aTexCoord, 2, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, vertPosBuf); gl.enableVertexAttribArray(earthShader.aVertexPosition); gl.vertexAttribPointer(earthShader.aVertexPosition, 3, gl.FLOAT, false, 0, 0); gl.vertexAttribPointer(gl.pickShaderProgram.aPos, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, vertNormBuf); gl.enableVertexAttribArray(earthShader.aVertexNormal); gl.vertexAttribPointer(earthShader.aVertexNormal, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertIndexBuf); gl.drawElements(gl.TRIANGLES, vertCount, gl.UNSIGNED_SHORT, 0); gl.useProgram(gl.pickShaderProgram); gl.bindFramebuffer(gl.FRAMEBUFFER, gl.pickFb); // gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.uniformMatrix4fv(gl.pickShaderProgram.uMvMatrix, false, mvMatrix); //set up picking gl.disableVertexAttribArray(gl.pickShaderProgram.aColor); gl.enableVertexAttribArray(gl.pickShaderProgram.aPos); gl.drawElements(gl.TRIANGLES, vertCount, gl.UNSIGNED_SHORT, 0); } function jday(year, mon, day, hr, minute, sec) { //from satellite.js 'use strict'; return (367.0 * year - Math.floor((7 * (year + Math.floor((mon + 9) / 12.0))) * 0.25) + Math.floor(275 * mon / 9.0) + day + 1721013.5 + ((sec / 60.0 + minute) / 60.0 + hr) / 24.0 // ut in days //# - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5; ); } window.earth = earth; })(); // **** end earth.js *** // **** sun.js *** (function() { var D2R = Math.PI / 180.0; function currentDirection() { var now = new Date(); var j = jday(now.getUTCFullYear(), now.getUTCMonth() + 1, // Note, this function requires months in range 1-12. now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds()); j += now.getUTCMilliseconds() * 1.15741e-8; //days per millisecond return getDirection(j); } function getDirection(jd) { var n = jd - 2451545; var L = (280.460) + (0.9856474 * n); //mean longitude of sun var g = (357.528) + (0.9856003 * n); //mean anomaly L = L % 360.0; g = g % 360.0; var ecLon = L + 1.915 * Math.sin(g * D2R) + 0.020 * Math.sin(2 * g * D2R); var ob = getObliquity(jd); var x = Math.cos(ecLon * D2R); var y = Math.cos(ob * D2R) * Math.sin(ecLon * D2R); var z = Math.sin(ob * D2R) * Math.sin(ecLon * D2R); return [x, y, z]; //return [1, 0, 0]; } function getObliquity(jd) { var t = (jd - 2451545) / 3652500; var ob = //arcseconds 84381.448 - 4680.93 * t - 1.55 * Math.pow(t, 2) + 1999.25 * Math.pow(t, 3) - 51.38 * Math.pow(t, 4) - 249.67 * Math.pow(t, 5) - 39.05 * Math.pow(t, 6) + 7.12 * Math.pow(t, 7) + 27.87 * Math.pow(t, 8) + 5.79 * Math.pow(t, 9) + 2.45 * Math.pow(t, 10); return ob / 3600.0; } function jday(year, mon, day, hr, minute, sec){ //from satellite.js 'use strict'; return (367.0 * year - Math.floor((7 * (year + Math.floor((mon + 9) / 12.0))) * 0.25) + Math.floor( 275 * mon / 9.0 ) + day + 1721013.5 + ((sec / 60.0 + minute) / 60.0 + hr) / 24.0 // ut in days //# - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5; ); } window.sun = { getDirection: getDirection, currentDirection: currentDirection }; })(); // **** end sun.js *** // **** sat.js *** /* global browserUnsupported */ /* global satellite */ /* global mat4 */ /* global shaderLoader */ /* global gl */ /* global ColorScheme */ /* global $ */ (function () { var satSet = {}; var dotShader; var satPosBuf; var satColorBuf; var pickColorBuf; var pickableBuf; var currentColorScheme; var shadersReady = false; var satPos; var satVel; var satAlt; var satData; var satExtraData; var hoveringSat = -1; var selectedSat = -1; try { var satCruncher = new Worker('/scripts/sat-cruncher.js'); } catch (E) { browserUnsupported(); } var cruncherReady = false; var lastDrawTime = 0; var cruncherReadyCallback; var gotExtraData = false; satCruncher.onmessage = function (m) { if (!gotExtraData) { // store extra data that comes from crunching var start = performance.now(); satExtraData = JSON.parse(m.data.extraData); for (var i = 0; i < satSet.numSats; i++) { satData[i].inclination = satExtraData[i].inclination; satData[i].eccentricity = satExtraData[i].eccentricity; satData[i].raan = satExtraData[i].raan; satData[i].argPe = satExtraData[i].argPe; satData[i].meanMotion = satExtraData[i].meanMotion; satData[i].semiMajorAxis = satExtraData[i].semiMajorAxis; satData[i].semiMinorAxis = satExtraData[i].semiMinorAxis; satData[i].apogee = satExtraData[i].apogee; satData[i].perigee = satExtraData[i].perigee; satData[i].period = satExtraData[i].period; } console.log('sat.js copied extra data in ' + (performance.now() - start) + ' ms'); gotExtraData = true; return; } satPos = new Float32Array(m.data.satPos); satVel = new Float32Array(m.data.satVel); satAlt = new Float32Array(m.data.satAlt); if (!cruncherReady) { $('#load-cover').fadeOut(); satSet.setColorScheme(currentColorScheme); //force color recalc cruncherReady = true; if (cruncherReadyCallback) { cruncherReadyCallback(satData); } } }; satSet.init = function (satsReadyCallback) { dotShader = gl.createProgram(); var vertShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertShader, shaderLoader.getShaderCode('dot-vertex.glsl')); gl.compileShader(vertShader); var fragShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragShader, shaderLoader.getShaderCode('dot-fragment.glsl')); gl.compileShader(fragShader); gl.attachShader(dotShader, vertShader); gl.attachShader(dotShader, fragShader); gl.linkProgram(dotShader); dotShader.aPos = gl.getAttribLocation(dotShader, 'aPos'); dotShader.aColor = gl.getAttribLocation(dotShader, 'aColor'); dotShader.uMvMatrix = gl.getUniformLocation(dotShader, 'uMvMatrix'); dotShader.uCamMatrix = gl.getUniformLocation(dotShader, 'uCamMatrix'); dotShader.uPMatrix = gl.getUniformLocation(dotShader, 'uPMatrix'); $.get('/TLE.json?fakeparameter=to_avoid_browser_cache2', function (resp) { var startTime = new Date().getTime(); console.log('sat.js downloaded data'); $('#loader-text').text('Crunching numbers...'); satData = resp; satSet.satDataString = JSON.stringify(satData); var postStart = performance.now(); satCruncher.postMessage(satSet.satDataString); //kick off satCruncher var postEnd = performance.now(); //do some processing on our satData response for (var i = 0; i < satData.length; i++) { if (satData[i].INTLDES !== null) { var year = satData[i].INTLDES.substring(0, 2); //clean up intl des for display // var prefix = (year > 50) ? '19' : '20'; // year = prefix + year; var rest = satData[i].INTLDES.substring(2); satData[i].intlDes = year + rest; } else { satData[i].intlDes = '(unknown)'; } satData[i].id = i; } //populate GPU mem buffers, now that we know how many sats there are satPosBuf = gl.createBuffer(); satPos = new Float32Array(satData.length * 3); var pickColorData = []; pickColorBuf = gl.createBuffer(); for (var i = 0; i < satData.length; i++) { var byteR = (i + 1) & 0xff; var byteG = ((i + 1) & 0xff00) >> 8; var byteB = ((i + 1) & 0xff0000) >> 16; pickColorData.push(byteR / 255.0); pickColorData.push(byteG / 255.0); pickColorData.push(byteB / 255.0); } gl.bindBuffer(gl.ARRAY_BUFFER, pickColorBuf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pickColorData), gl.STATIC_DRAW); satSet.numSats = satData.length; satSet.setColorScheme(ColorScheme.default); // satSet.setColorScheme(ColorScheme.apogee); // satSet.setColorScheme(ColorScheme.velocity); var end = new Date().getTime(); console.log('sat.js init: ' + (end - startTime) + ' ms (incl post: ' + (postEnd - postStart) + ' ms)'); shadersReady = true; if (satsReadyCallback) { satsReadyCallback(satData); } }); }; satSet.setColorScheme = function (scheme) { currentColorScheme = scheme; var buffers = scheme.calculateColorBuffers(); satColorBuf = buffers.colorBuf; pickableBuf = buffers.pickableBuf; }; satSet.draw = function (pMatrix, camMatrix) { if (!shadersReady || !cruncherReady) return; var now = Date.now(); var dt = Math.min((now - lastDrawTime) / 1000.0, 1.0); for (var i = 0; i < (satData.length * 3); i++) { satPos[i] += satVel[i] * dt; } gl.useProgram(dotShader); gl.bindFramebuffer(gl.FRAMEBUFFER, null); // gl.bindFramebuffer(gl.FRAMEBUFFER, gl.pickFb); gl.uniformMatrix4fv(dotShader.uMvMatrix, false, mat4.create()); gl.uniformMatrix4fv(dotShader.uCamMatrix, false, camMatrix); gl.uniformMatrix4fv(dotShader.uPMatrix, false, pMatrix); gl.bindBuffer(gl.ARRAY_BUFFER, satPosBuf); gl.bufferData(gl.ARRAY_BUFFER, satPos, gl.STREAM_DRAW); gl.vertexAttribPointer(dotShader.aPos, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, satColorBuf); gl.enableVertexAttribArray(dotShader.aColor); gl.vertexAttribPointer(dotShader.aColor, 4, gl.FLOAT, false, 0, 0); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.enable(gl.BLEND); gl.depthMask(false); gl.drawArrays(gl.POINTS, 0, satData.length); gl.depthMask(true); gl.disable(gl.BLEND); // now pickbuffer stuff...... gl.useProgram(gl.pickShaderProgram); gl.bindFramebuffer(gl.FRAMEBUFFER, gl.pickFb); // gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.uniformMatrix4fv(gl.pickShaderProgram.uMvMatrix, false, mat4.create()); gl.uniformMatrix4fv(gl.pickShaderProgram.uCamMatrix, false, camMatrix); gl.uniformMatrix4fv(gl.pickShaderProgram.uPMatrix, false, pMatrix); gl.bindBuffer(gl.ARRAY_BUFFER, satPosBuf); gl.enableVertexAttribArray(gl.pickShaderProgram.aPos); gl.vertexAttribPointer(gl.pickShaderProgram.aPos, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(gl.pickShaderProgram.aColor); gl.bindBuffer(gl.ARRAY_BUFFER, pickColorBuf); gl.vertexAttribPointer(gl.pickShaderProgram.aColor, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, pickableBuf); gl.enableVertexAttribArray(gl.pickShaderProgram.aPickable); gl.vertexAttribPointer(gl.pickShaderProgram.aPickable, 1, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.POINTS, 0, satData.length); //draw pick lastDrawTime = now; }; satSet.getSat = function (i) { if (!satData) return null; var ret = satData[i]; if (!ret) return null; if (gotExtraData) { ret.altitude = satAlt[i]; ret.velocity = Math.sqrt( satVel[i * 3] * satVel[i * 3] + satVel[i * 3 + 1] * satVel[i * 3 + 1] + satVel[i * 3 + 2] * satVel[i * 3 + 2] ); ret.position = { x: satPos[i * 3], y: satPos[i * 3 + 1], z: satPos[i * 3 + 2] }; } return ret; }; satSet.getIdFromIntlDes = function (intlDes) { for (var i = 0; i < satData.length; i++) { if (satData[i].INTLDES === intlDes || satData[i].intlDes === intlDes) { return i; } } return null; }; satSet.getScreenCoords = function (i, pMatrix, camMatrix) { var pos = satSet.getSat(i).position; var posVec4 = vec4.fromValues(pos.x, pos.y, pos.z, 1); var transform = mat4.create(); vec4.transformMat4(posVec4, posVec4, camMatrix); vec4.transformMat4(posVec4, posVec4, pMatrix); var glScreenPos = { x: (posVec4[0] / posVec4[3]), y: (posVec4[1] / posVec4[3]), z: (posVec4[2] / posVec4[3]), }; return { x: (glScreenPos.x + 1) * 0.5 * window.innerWidth, y: (-glScreenPos.y + 1) * 0.5 * window.innerHeight, }; } satSet.searchNameRegex = function (regex) { var res = []; for (var i = 0; i < satData.length; i++) { if (regex.test(satData[i].OBJECT_NAME)) { res.push(i); } } return res; }; satSet.setHover = function (i) { if (i === hoveringSat) return; gl.bindBuffer(gl.ARRAY_BUFFER, satColorBuf); if (hoveringSat != -1 && hoveringSat != selectedSat) { gl.bufferSubData(gl.ARRAY_BUFFER, hoveringSat * 4 * 4, new Float32Array(currentColorScheme.colorizer(hoveringSat).color)); } if (i != -1) { var sat = satSet.getSat(i); var hoverColor = window.getSatelliteColor(sat); gl.bufferSubData(gl.ARRAY_BUFFER, i * 4 * 4, new Float32Array(hoverColor)); } hoveringSat = i; }; satSet.selectSat = function (i) { if (i === selectedSat) return; gl.bindBuffer(gl.ARRAY_BUFFER, satColorBuf); if (selectedSat != -1) { gl.bufferSubData(gl.ARRAY_BUFFER, selectedSat * 4 * 4, new Float32Array(currentColorScheme.colorizer(selectedSat).color)); } if (i != -1) { var sat = satSet.getSat(i); var selectedColor = window.getSatelliteColor(sat); gl.bufferSubData(gl.ARRAY_BUFFER, i * 4 * 4, new Float32Array(selectedColor)); } selectedSat = i; }; satSet.onCruncherReady = function (cb) { cruncherReadyCallback = cb; if (cruncherReady) cb; } window.satSet = satSet; })(); // **** end sat.js *** // **** main.js *** /* global groups */ /* global ColorScheme */ /* global satSet */ /* global $ */ /* global shaderLoader */ /* global Line */ /* global vec4 */ /* global mat4 */ /* global vec3 */ /* global mat3 */ /* global earth */ /* global searchBox */ /* global Spinner */ /* global sun */ /* global orbitDisplay */ var gl; var cubeVertIndexBuffer; var R2D = 180 / Math.PI; var camYaw = 0; var camPitch = 0.5; var camYawTarget = 0; var camPitchTarget = 0; var camSnapMode = false; var camZoomSnappedOnSat = false; var camAngleSnappedOnSat = false; var camDistTarget = 10000; var zoomLevel = 0.5; var zoomTarget = 0.5; var ZOOM_EXP = 3; var DIST_MIN = 6400; var DIST_MAX = 200000; var camPitchSpeed = 0; var camYawSpeed = 0; var pickFb, pickTex; var pickColorBuf; var pMatrix = mat4.create(), camMatrix = mat4.create(); var selectedSat = -1; var mouseX = 0, mouseY = 0, mouseSat = -1; var dragPoint = [0, 0, 0]; var screenDragPoint = [0, 0]; var dragStartPitch = 0; var dragStartYaw = 0; var isDragging = false; var dragHasMoved = false; var initialRotation = true; var initialRotSpeed = 0.000075; var debugContext, debugImageData; var debugLine, debugLine2, debugLine3; var spinner; var typeList = [ { name: '人造卫星', switchFlag: true, srcUrl: 1, Num: 0, srcName: 'PAYLOAD', // background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(19,252,1,1) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(255, 51, 0, 1) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, boxShadow: `0 0 10px 4px #ff3300`, // boxShadow: `0 0 10px 4px #00ff59`, }, { name: '火箭残骸', switchFlag: true, srcUrl: 2, Num: 0, srcName: 'ROCKETBODY', // background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(1,56,252,1) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(51, 128, 255, 0.85) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, boxShadow: `0 0 10px 4px #3380ff`, // boxShadow: `0 0 10px 4px #4000ff`, }, { name: '空间碎片', switchFlag: true, srcUrl: 3, Num: 0, srcName: 'DEBRIS', // background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(252,13,1,1) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(128, 128, 128, 0.85) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, boxShadow: `0 0 10px 4px #808080`, // boxShadow: `0 0 10px 4px #ff0c00`, }, // { // name: '待定目标', // switchFlag: true, // srcUrl: 4, // Num: 0, // srcName: 'TBA', // background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(119,129,131,1) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, // boxShadow: `0 0 10px 4px #828086`, // }, { name: '待定目标', switchFlag: true, srcUrl: 5, Num: 0, srcName: 'UNKNOWN', // background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(255,158,0,1) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, background: `linear-gradient(294deg, rgba(255,255,255,0.3701855742296919) 0%, rgba(255, 255, 0, 1) 47%, rgba(255,255,255,0.4542191876750701) 100%)`, // boxShadow: `0 0 10px 4px #ff9e00`, boxShadow: `0 0 10px 4px #ffff00`, }, ] $(document).ready(function () { var opts = { lines: 11, // The number of lines to draw length: 8, // The length of each line width: 5, // The line thickness radius: 8, // The radius of the inner circle corners: 1, // Corner roundness (0..1) rotate: 0, // The rotation offset direction: 1, // 1: clockwise, -1: counterclockwise color: '#fff', // #rgb or #rrggbb or array of colors speed: 1, // Rounds per second trail: 50, // Afterglow percentage shadow: false, // Whether to render a shadow hwaccel: false, // Whether to use hardware acceleration className: 'spinner', // The CSS class to assign to the spinner zIndex: 2e9, // The z-index (defaults to 2000000000) top: '50%', // Top position relative to parent left: '50%' // Left position relative to parent }; var target = document.getElementById('spinner'); spinner = new Spinner(opts).spin(target); $('#search-results').perfectScrollbar(); // 渲染类型列表 renderTypeList(); var resizing = false; setTimeout(() => { initialRotation = true }, 30000); $(window).resize(function () { if (!resizing) { window.setTimeout(function () { resizing = false; webGlInit(); }, 500); } resizing = true; }); webGlInit(); earth.init(); ColorScheme.init(); satSet.init(function (satData) { orbitDisplay.init(); groups.init(); searchBox.init(satData); debugLine = new Line(); debugLine2 = new Line(); debugLine3 = new Line(); }); satSet.onCruncherReady(function (satData) { //do querystring stuff var queryStr = window.location.search.substring(1); var params = queryStr.split('&'); for (var i = 0; i < params.length; i++) { var key = params[i].split('=')[0]; var val = params[i].split('=')[1]; if (key === 'intldes') { var urlSatId = satSet.getIdFromIntlDes(val.toUpperCase()); if (urlSatId !== null) { selectSat(urlSatId); } } else if (key === 'search') { searchBox.doSearch(val); $('#search').val(val); } } searchBox.init(satData); }); $('#canvas').on('touchmove', function (evt) { evt.preventDefault(); if (isDragging) { dragHasMoved = true; camAngleSnappedOnSat = false; camZoomSnappedOnSat = false; } mouseX = evt.originalEvent.touches[0].clientX; mouseY = evt.originalEvent.touches[0].clientY; }); $('#canvas').mousemove(function (evt) { if (isDragging) { dragHasMoved = true; camAngleSnappedOnSat = false; camZoomSnappedOnSat = false; } mouseX = evt.clientX; mouseY = evt.clientY; }); $('#canvas').on('wheel', function (evt) { var delta = evt.originalEvent.deltaY; if (evt.originalEvent.deltaMode === 1) { delta *= 33.3333333; } zoomTarget += delta * 0.0002; if (zoomTarget > 1) zoomTarget = 1; if (zoomTarget < 0) zoomTarget = 0; initialRotation = false; camZoomSnappedOnSat = false; }); $('#canvas').click(function (evt) { }); $('#canvas').contextmenu(function () { return false; //stop right-click menu }); $('#canvas').mousedown(function (evt) { // if(evt.which === 3) {//RMB dragPoint = getEarthScreenPoint(evt.clientX, evt.clientY); screenDragPoint = [evt.clientX, evt.clientY]; dragStartPitch = camPitch; dragStartYaw = camYaw; // debugLine.set(dragPoint, getCamPos()); isDragging = true; camSnapMode = false; initialRotation = false; // } }); $('#canvas').on('touchstart', function (evt) { var x = evt.originalEvent.touches[0].clientX; var y = evt.originalEvent.touches[0].clientY; dragPoint = getEarthScreenPoint(x, y); screenDragPoint = [x, y]; dragStartPitch = camPitch; dragStartYaw = camYaw; // debugLine.set(dragPoint, getCamPos()); isDragging = true; camSnapMode = false; initialRotation = false; }); $('#canvas').mouseup(function (evt) { // if(evt.which === 3) {//RMB if (!dragHasMoved) { var clickedSat = getSatIdFromCoord(evt.clientX, evt.clientY); if (clickedSat === -1) searchBox.hideResults(); selectSat(clickedSat); } dragHasMoved = false; isDragging = false; initialRotation = false; // } }); $('#canvas').on('touchend', function (evt) { dragHasMoved = false; isDragging = false; initialRotation = false; }); $('.menu-item').mouseover(function (evt) { $(this).children('.submenu').css({ display: 'block' }); }); $('.menu-item').mouseout(function (evt) { $(this).children('.submenu').css({ display: 'none' }); }); $('#zoom-in').click(function () { zoomTarget -= 0.04; if (zoomTarget < 0) zoomTarget = 0; initialRotation = false; camZoomSnappedOnSat = false; }); $('#zoom-out').click(function () { zoomTarget += 0.04; if (zoomTarget > 1) zoomTarget = 1; initialRotation = false; camZoomSnappedOnSat = false; }); // debugContext = $('#debug-canvas')[0].getContext('2d'); // debugImageData = debugContext.createImageData(debugContext.canvas.width, debugContext.canvas.height); drawLoop(); //kick off the animationFrame()s }); function selectSat(satId) { selectedSat = satId; if (satId === -1) { $('#sat-infobox').fadeOut(); orbitDisplay.clearSelectOrbit(); } else { camZoomSnappedOnSat = true; camAngleSnappedOnSat = true; satSet.selectSat(satId); // camSnapToSat(satId); var sat = satSet.getSat(satId); if (!sat) return; orbitDisplay.setSelectOrbit(satId); $('#sat-infobox').fadeIn(); $('#sat-info-title').html(sat.OBJECT_NAME); $('#sat-intl-des').html(sat.intlDes); $('#sat-type').html(sat.OBJECT_TYPE); $('#sat-apogee').html(sat.apogee.toFixed(0) + ' km'); $('#sat-perigee').html(sat.perigee.toFixed(0) + ' km'); $('#sat-inclination').html((sat.inclination * R2D).toFixed(2) + '°'); $('#sat-period').html(sat.period.toFixed(2) + ' min'); } updateUrl(); } function browserUnsupported() { $('#canvas-holder').hide(); $('#no-webgl').css('display', 'block'); } function webGlInit() { var can = $('#canvas')[0]; can.width = window.innerWidth; can.height = window.innerHeight; var gl = can.getContext('webgl', { alpha: false }) || can.getContext('experimental-webgl', { alpha: false }); if (!gl) { browserUnsupported(); } gl.viewport(0, 0, can.width, can.height); gl.enable(gl.DEPTH_TEST); gl.enable(0x8642); //enable point sprites(?!) This might get browsers with // underlying OpenGL to behave //although it's not technically a part of the WebGL standard var pFragShader = gl.createShader(gl.FRAGMENT_SHADER); var pFragCode = shaderLoader.getShaderCode('pick-fragment.glsl'); gl.shaderSource(pFragShader, pFragCode); gl.compileShader(pFragShader); var pVertShader = gl.createShader(gl.VERTEX_SHADER); var pVertCode = shaderLoader.getShaderCode('pick-vertex.glsl'); gl.shaderSource(pVertShader, pVertCode); gl.compileShader(pVertShader); var pickShaderProgram = gl.createProgram(); gl.attachShader(pickShaderProgram, pVertShader); gl.attachShader(pickShaderProgram, pFragShader); gl.linkProgram(pickShaderProgram); pickShaderProgram.aPos = gl.getAttribLocation(pickShaderProgram, 'aPos'); pickShaderProgram.aColor = gl.getAttribLocation(pickShaderProgram, 'aColor'); pickShaderProgram.aPickable = gl.getAttribLocation(pickShaderProgram, 'aPickable'); pickShaderProgram.uCamMatrix = gl.getUniformLocation(pickShaderProgram, 'uCamMatrix'); pickShaderProgram.uMvMatrix = gl.getUniformLocation(pickShaderProgram, 'uMvMatrix'); pickShaderProgram.uPMatrix = gl.getUniformLocation(pickShaderProgram, 'uPMatrix'); gl.pickShaderProgram = pickShaderProgram; pickFb = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, pickFb); pickTex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, pickTex); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); //makes clearing work gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); var rb = gl.createRenderbuffer(); //create RB to store the depth buffer gl.bindRenderbuffer(gl.RENDERBUFFER, rb); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, gl.drawingBufferWidth, gl.drawingBufferHeight); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, pickTex, 0); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb); gl.pickFb = pickFb; pickColorBuf = new Uint8Array(4); pMatrix = mat4.create(); mat4.perspective(pMatrix, 1.01, gl.drawingBufferWidth / gl.drawingBufferHeight, 20.0, 600000.0); var eciToOpenGlMat = [ 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1 ]; mat4.mul(pMatrix, pMatrix, eciToOpenGlMat); //pMat = pMat * ecioglMat window.gl = gl; } function getCamPos() { var r = getCamDist(); var z = r * Math.sin(camPitch); var rYaw = r * Math.cos(camPitch); var x = rYaw * Math.sin(camYaw); var y = rYaw * Math.cos(camYaw) * -1; return [x, y, z]; } function unProject(mx, my) { var glScreenX = (mx / gl.drawingBufferWidth * 2) - 1.0; var glScreenY = 1.0 - (my / gl.drawingBufferHeight * 2); var screenVec = [glScreenX, glScreenY, -0.01, 1.0]; //gl screen coords var comboPMat = mat4.create(); mat4.mul(comboPMat, pMatrix, camMatrix); var invMat = mat4.create(); mat4.invert(invMat, comboPMat); var worldVec = vec4.create(); vec4.transformMat4(worldVec, screenVec, invMat); return [worldVec[0] / worldVec[3], worldVec[1] / worldVec[3], worldVec[2] / worldVec[3]]; } function getEarthScreenPoint(x, y) { // var start = performance.now(); var rayOrigin = getCamPos(); var ptThru = unProject(x, y); var rayDir = vec3.create(); vec3.subtract(rayDir, ptThru, rayOrigin); //rayDir = ptThru - rayOrigin vec3.normalize(rayDir, rayDir); var toCenterVec = vec3.create(); vec3.scale(toCenterVec, rayOrigin, -1); //toCenter is just -camera pos because center is at [0,0,0] var dParallel = vec3.dot(rayDir, toCenterVec); var longDir = vec3.create(); vec3.scale(longDir, rayDir, dParallel); //longDir = rayDir * distParallel vec3.add(ptThru, rayOrigin, longDir); //ptThru is now on the plane going through the center of sphere var dPerp = vec3.len(ptThru); var dSubSurf = Math.sqrt(6371 * 6371 - dPerp * dPerp); var dSurf = dParallel - dSubSurf; var ptSurf = vec3.create(); vec3.scale(ptSurf, rayDir, dSurf); vec3.add(ptSurf, ptSurf, rayOrigin); return ptSurf; } function getCamDist() { return Math.pow(zoomLevel, ZOOM_EXP) * (DIST_MAX - DIST_MIN) + DIST_MIN; } function camSnapToSat(satId) { /* this function runs every frame that a satellite is seleected. However, the user might have broken out of the zoom snap or angle snap. If so, don't change those targets. */ var sat = satSet.getSat(satId); if (camAngleSnappedOnSat) { var pos = sat.position; var r = Math.sqrt(pos.x * pos.x + pos.y * pos.y); var yaw = Math.atan2(pos.y, pos.x) + Math.PI / 2; var pitch = Math.atan2(pos.z, r); camSnap(pitch, yaw); } if (camZoomSnappedOnSat) { var camDistTarget = sat.altitude + 6371 + 2000; zoomTarget = Math.pow((camDistTarget - DIST_MIN) / (DIST_MAX - DIST_MIN), 1 / ZOOM_EXP); } } function camSnap(pitch, yaw) { camPitchTarget = pitch; camYawTarget = normalizeAngle(yaw); camSnapMode = true; } function normalizeAngle(angle) { angle %= Math.PI * 2; if (angle > Math.PI) angle -= Math.PI * 2; if (angle < -Math.PI) angle += Math.PI * 2; return angle; } var oldT = new Date(); function drawLoop() { var newT = new Date(); var dt = Math.min(newT - oldT, 1000); oldT = newT; var dragTarget = getEarthScreenPoint(mouseX, mouseY); if (isDragging) { if (isNaN(dragTarget[0]) || isNaN(dragTarget[1]) || isNaN(dragTarget[2]) || isNaN(dragPoint[0]) || isNaN(dragPoint[1]) || isNaN(dragPoint[2])) { //random screen drag var xDif = screenDragPoint[0] - mouseX; var yDif = screenDragPoint[1] - mouseY; var yawTarget = dragStartYaw + xDif * 0.005; var pitchTarget = dragStartPitch + yDif * -0.005; camPitchSpeed = normalizeAngle(camPitch - pitchTarget) * -0.005; camYawSpeed = normalizeAngle(camYaw - yawTarget) * -0.005; } else { //earth surface point drag var dragPointR = Math.sqrt(dragPoint[0] * dragPoint[0] + dragPoint[1] * dragPoint[1]); var dragTargetR = Math.sqrt(dragTarget[0] * dragTarget[0] + dragTarget[1] * dragTarget[1]); var dragPointLon = Math.atan2(dragPoint[1], dragPoint[0]); var dragTargetLon = Math.atan2(dragTarget[1], dragTarget[0]); var dragPointLat = Math.atan2(dragPoint[2], dragPointR); var dragTargetLat = Math.atan2(dragTarget[2], dragTargetR); var pitchDif = dragPointLat - dragTargetLat; var yawDif = normalizeAngle(dragPointLon - dragTargetLon); camPitchSpeed = pitchDif * 0.015; camYawSpeed = yawDif * 0.015; } camSnapMode = false; } else { camPitchSpeed -= (camPitchSpeed * dt * 0.005); //decay speeds when globe is "thrown" camYawSpeed -= (camYawSpeed * dt * 0.005); } camPitch += camPitchSpeed * dt; camYaw += camYawSpeed * dt; if (initialRotation) { camYaw += initialRotSpeed * dt; } if (camSnapMode) { camPitch += (camPitchTarget - camPitch) * 0.003 * dt; var yawErr = normalizeAngle(camYawTarget - camYaw); camYaw += yawErr * 0.003 * dt; /* if(Math.abs(camPitchTarget - camPitch) < 0.002 && Math.abs(camYawTarget - camYaw) < 0.002 && Math.abs(zoomTarget - zoomLevel) < 0.002) { camSnapMode = false; Stay in camSnapMode forever. Is this a good idea? dunno.... }*/ zoomLevel = zoomLevel + (zoomTarget - zoomLevel) * dt * 0.0025; } else { zoomLevel = zoomLevel + (zoomTarget - zoomLevel) * dt * 0.0075; } if (camPitch > Math.PI / 2) camPitch = Math.PI / 2; if (camPitch < -Math.PI / 2) camPitch = -Math.PI / 2; // camYaw = (camYaw % (Math.PI*2)); camYaw = normalizeAngle(camYaw); if (selectedSat !== -1) { var sat = satSet.getSat(selectedSat); debugLine.set(sat, [0, 0, 0]); camSnapToSat(selectedSat); } drawScene(); updateHover(); updateSelectBox(); requestAnimationFrame(drawLoop); } function drawScene() { gl.bindFramebuffer(gl.FRAMEBUFFER, gl.pickFb); // gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.bindFramebuffer(gl.FRAMEBUFFER, null); // gl.bindFramebuffer(gl.FRAMEBUFFER, gl.pickFb); camMatrix = mat4.create(); mat4.identity(camMatrix); mat4.translate(camMatrix, camMatrix, [0, getCamDist(), 0]); mat4.rotateX(camMatrix, camMatrix, camPitch); mat4.rotateZ(camMatrix, camMatrix, -camYaw); gl.useProgram(gl.pickShaderProgram); gl.uniformMatrix4fv(gl.pickShaderProgram.uPMatrix, false, pMatrix); gl.uniformMatrix4fv(gl.pickShaderProgram.camMatrix, false, camMatrix); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); if (debugLine) debugLine.draw(); if (debugLine2) debugLine2.draw(); if (debugLine3) debugLine3.draw(); earth.draw(pMatrix, camMatrix); satSet.draw(pMatrix, camMatrix); orbitDisplay.draw(pMatrix, camMatrix); /* DEBUG - show the pickbuffer on a canvas */ // debugImageData.data = pickColorMap; /* debugImageData.data.set(pickColorMap); debugContext.putImageData(debugImageData, 0, 0);*/ } function updateSelectBox() { if (selectedSat === -1) return; var satData = satSet.getSat(selectedSat); $('#sat-altitude').html(satData.altitude.toFixed(2) + ' km'); $('#sat-velocity').html(satData.velocity.toFixed(2) + ' km/s'); } function updateHover() { if (searchBox.isHovering()) { var satId = searchBox.getHoverSat(); var satPos = satSet.getScreenCoords(satId, pMatrix, camMatrix); if (!earthHitTest(satPos.x, satPos.y)) { hoverBoxOnSat(satId, satPos.x, satPos.y); } else { hoverBoxOnSat(-1, 0, 0); } } else { mouseSat = getSatIdFromCoord(mouseX, mouseY); if (mouseSat !== -1) { orbitDisplay.setHoverOrbit(mouseSat); } else { orbitDisplay.clearHoverOrbit(); } satSet.setHover(mouseSat); hoverBoxOnSat(mouseSat, mouseX, mouseY); } } /** * @description 动态增加分组 * @param {groupName} 分组名称 * @param {groupCode} 分组编码名称 * @param {type} 类型 nameRegex/intlDes * @property {result} 类型-数据或者检索名称/GLONASS/ */ function creatGroups(groupName, groupCode, type, result) { if (!groups) return if (!groups.SatGroup) return groups[groupCode] = new groups.SatGroup(type, result) const ul = document.getElementById('groups-display'); const li = document.createElement('li'); li.setAttribute('data-group', groupCode); li.textContent = groupName; ul.appendChild(li); } function hoverBoxOnSat(satId, satX, satY) { if (satId === -1) { $('#sat-hoverbox').html('(none)'); $('#sat-hoverbox').css({ display: 'none' }); $('#canvas').css({ cursor: 'default' }); } else { try { $('#sat-hoverbox').html(satSet.getSat(satId).OBJECT_NAME); $('#sat-hoverbox').css({ display: 'block', position: 'absolute', left: satX + 20, top: satY - 10 }); $('#canvas').css({ cursor: 'pointer' }); } catch (e) { } } } function getSatIdFromCoord(x, y) { // var start = performance.now(); gl.bindFramebuffer(gl.FRAMEBUFFER, gl.pickFb); gl.readPixels(x, gl.drawingBufferHeight - y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pickColorBuf); var pickR = pickColorBuf[0]; var pickG = pickColorBuf[1]; var pickB = pickColorBuf[2]; return ((pickB << 16) | (pickG << 8) | (pickR)) - 1; } function earthHitTest(x, y) { gl.bindFramebuffer(gl.FRAMEBUFFER, gl.pickFb); gl.readPixels(x, gl.drawingBufferHeight - y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pickColorBuf); return (pickColorBuf[0] === 0 && pickColorBuf[1] === 0 && pickColorBuf[2] === 0); } function updateUrl() { var url = '/'; var paramSlices = []; if (selectedSat !== -1) { paramSlices.push('intldes=' + satSet.getSat(selectedSat).intlDes); } var currentSearch = searchBox.getCurrentSearch(); if (currentSearch != null) { paramSlices.push('search=' + currentSearch); } if (paramSlices.length > 0) { url += '?' + paramSlices.join('&'); } window.history.replaceState(null, 'Stuff in Space', url); } // 渲染类型列表 function renderTypeList() { var container = document.getElementById('tableNum'); if (!container) return; container.innerHTML = ''; typeList.forEach(function (type) { var li = document.createElement('li'); li.className = 'liNum'; // 创建颜色指示器 var colorActive = document.createElement('div'); colorActive.className = 'colorActive'; // 设置与类型对应的背景和阴影颜色 colorActive.style.background = type.background; colorActive.style.boxShadow = type.boxShadow; // 创建内容容器 var content = document.createElement('div'); content.style.display = 'flex'; content.style.justifyContent = 'space-between'; content.style.alignItems = 'center'; content.innerHTML = ` ${type.name} `; // ${type.Num} 个 // 组合元素 li.appendChild(colorActive); li.appendChild(content); container.appendChild(li); }); } // 根据卫星类型获取颜色的公共函数 function getSatelliteColor(sat) { var color; if (sat.OBJECT_TYPE === 'PAYLOAD') { // color = [0.074, 0.988, 0.004, 1.0]; // 人造卫星 - 绿色【新版】 color = [1.0, 0.2, 0.0, 1.0]; } else if (sat.OBJECT_TYPE === 'ROCKET BODY') { // color = [0.004, 0.220, 0.988, 0.85]; // 空间碎片 - 蓝色【新版】 color = [0.2, 0.5, 1.0, 0.85]; } else if (sat.OBJECT_TYPE === 'DEBRIS') { // color = [0.988, 0.051, 0.004, 0.85]; // 火箭残骸 - 红色【新版】 color = [0.5, 0.5, 0.5, 0.85]; } else if (sat.OBJECT_TYPE === 'TBA' || sat.OBJECT_TYPE === 'UNKNOWN') { // color = [1.0, 0.620, 0.0, 0.85]; // 未知目标 - 橙色【新版】 color = [1.0, 1.0, 0.0, 1.0]; } else { // color = [0.467, 0.506, 0.514, 0.85]; // 其他 - 灰色【新版】 color = [1.0, 1.0, 0.0, 1.0]; } return color; // if (sat.OBJECT_TYPE === 'PAYLOAD') { // color = [1.0, 0.2, 0.0, 1.0]; // } else if (sat.OBJECT_TYPE === 'ROCKET BODY') { // color = [0.2, 0.5, 1.0, 0.85]; // // return [0.6, 0.6, 0.6]; // } else if (sat.OBJECT_TYPE === 'DEBRIS') { // color = [0.5, 0.5, 0.5, 0.85]; // } else { // color = [1.0, 1.0, 0.0, 1.0]; // } } // **** end main.js *** var shaderData = [{"name":"earth-fragment.glsl","code":"precision mediump float;\n\nuniform vec3 uAmbientLightColor;\nuniform vec3 uDirectionalLightColor;\nuniform vec3 uLightDirection;\n\nvarying vec2 texCoord;\nvarying vec3 normal;\n\nuniform sampler2D uSampler;\nuniform sampler2D uNightSampler;\n\n\n\nvoid main(void) {\n float directionalLightAmount = max(dot(normal, uLightDirection), 0.0);\n vec3 lightColor = uAmbientLightColor + (uDirectionalLightColor * directionalLightAmount);\n \n vec3 litTexColor = texture2D(uSampler, texCoord).rgb * lightColor * 2.0;\n \n vec3 nightLightColor = texture2D(uNightSampler, texCoord).rgb * pow(1.0 - directionalLightAmount, 2.0) ;\n\n gl_FragColor = vec4(litTexColor + nightLightColor, 1.0);\n}"},{"name":"earth-vertex.glsl","code":"attribute vec3 aVertexPosition;\n\nattribute vec2 aTexCoord;\nattribute vec3 aVertexNormal;\n\nuniform mat4 uPMatrix;\nuniform mat4 uCamMatrix;\nuniform mat4 uMvMatrix;\nuniform mat3 uNormalMatrix;\n\n\nvarying vec2 texCoord;\nvarying vec3 normal;\nvarying float directionalLightAmount;\n\nvoid main(void) {\n gl_Position = uPMatrix * uCamMatrix * uMvMatrix * vec4(aVertexPosition, 1.0);\n texCoord = aTexCoord;\n \n normal = uNormalMatrix * aVertexNormal;\n}\n"},{"name":"dot-fragment.glsl","code":"precision mediump float;\n\nvarying vec4 vColor;\n\nvoid main(void) {\n vec2 ptCoord = gl_PointCoord * 2.0 - vec2(1.0, 1.0);\n float r = 1.0 - min(abs(length(ptCoord)), 1.0);\n \/\/ r -= abs(ptCoord.x * ptCoord.y * 0.5);\n float alpha = pow(r + 0.1, 3.0);\n alpha = min(alpha, 1.0);\n\/\/ float alpha = r;\n gl_FragColor = vec4(vColor.rgb, vColor.a * alpha);\n}"},{"name":"dot-vertex.glsl","code":"attribute vec3 aPos;\nattribute vec4 aColor;\n\nuniform mat4 uCamMatrix;\nuniform mat4 uMvMatrix;\nuniform mat4 uPMatrix;\n\nvarying vec4 vColor;\n\nvoid main(void) {\n \/\/ gl_PointSize = 16.0;\n vec4 position = uPMatrix * uCamMatrix * uMvMatrix * vec4(aPos, 1.0);\n gl_PointSize = min(max(320000.0 \/ position.w, 7.5), 20.0) * 1.0;\n gl_Position = position;\n vColor = aColor;\n}\n"},{"name":"pick-fragment.glsl","code":"precision mediump float;\n\nvarying vec3 vColor;\n\nvoid main(void) {\n gl_FragColor = vec4(vColor, 1.0);\n}"},{"name":"pick-vertex.glsl","code":"attribute vec3 aPos;\nattribute vec3 aColor;\nattribute float aPickable;\n\nuniform mat4 uCamMatrix;\nuniform mat4 uMvMatrix;\nuniform mat4 uPMatrix;\n\nvarying vec3 vColor;\n\nvoid main(void) {\n float dotSize = 16.0;\n vec4 position = uPMatrix * uCamMatrix * uMvMatrix * vec4(aPos, 1.0);\n gl_Position = position;\n gl_PointSize = dotSize * aPickable;\n vColor = aColor * aPickable;\n}"},{"name":"path-fragment.glsl","code":"precision mediump float;\n\nvarying vec4 vColor;\n\nvoid main(void) {\n gl_FragColor = vColor;\n}"},{"name":"path-vertex.glsl","code":"attribute vec3 aPos;\n\nuniform mat4 uCamMatrix;\nuniform mat4 uMvMatrix;\nuniform mat4 uPMatrix;\nuniform vec4 uColor;\n\nvarying vec4 vColor;\n\nvoid main(void) {\n vec4 position = uPMatrix * uCamMatrix * uMvMatrix * vec4(aPos, 1.0);\n gl_Position = position;\n vColor = uColor;\n}\n"}];