m |
m |
||
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
/*! | /*! | ||
− | * igemUCAS JavaScript Library v0.18. | + | * igemUCAS JavaScript Library v0.18.1 |
* Copyright UCAS iGEM team | * Copyright UCAS iGEM team | ||
*/ | */ | ||
− | (function( | + | |
− | for(var | + | ( function( global, factory ) { var iU = global.iU = factory(global); iU(); } ) (window, function( window ) { |
+ | var | ||
+ | document = window.document, | ||
+ | inspect = (function(){ | ||
+ | var | ||
+ | strErr = "igemUCAS v0.18.19\n", | ||
+ | nextseq = 1, | ||
+ | error = function( location, desc ){ | ||
+ | strErr = strErr.concat(nextseq, " ", location, ": ", desc, '\n'); | ||
+ | nextseq ++; | ||
+ | }, | ||
+ | garrison = function( name ){ | ||
+ | var f = { | ||
+ | string: function( s ){ | ||
+ | if( (!s) || typeof s != 'string' ) | ||
+ | error(name, "parameter should be of ."); | ||
+ | return f; | ||
+ | }, | ||
+ | number: function( s ){ | ||
+ | if( (!s) || typeof s != 'number' ) | ||
+ | error(name, "parameter should be of number type."); | ||
+ | return f; | ||
+ | }, | ||
+ | keyUnused: function(obj, key){ | ||
+ | if( obj[key] ) | ||
+ | error(name, "key "+key+" has been used."); | ||
+ | return f; | ||
+ | }, | ||
+ | assert: function( val, desc ){ | ||
+ | if( !val ) | ||
+ | error(name, desc ); | ||
+ | return f; | ||
+ | } | ||
+ | }; | ||
+ | return f; | ||
+ | }; | ||
+ | |||
+ | garrison.displayErrors = function(){ | ||
+ | if(strErr.length == 0 ) | ||
+ | console.log("No errors, Congrats!") | ||
+ | else | ||
+ | console.log( strErr ); | ||
+ | }; | ||
+ | garrison.root_not_found = function(){ | ||
+ | console.log("DIV igemUCAS does not exist."); | ||
+ | garrison.displayErrors(); | ||
+ | }; | ||
+ | garrison.gl_not_supported = function(){ | ||
+ | console.log("WebGL is not supported."); | ||
+ | } | ||
+ | return garrison; | ||
+ | })(), | ||
+ | |||
+ | getUid = (function(){ | ||
+ | var now = -1; | ||
+ | return function(){ | ||
+ | now ++; | ||
+ | return (function(n){ | ||
+ | return '_'+n+'_'; | ||
+ | })(now); | ||
+ | }; | ||
+ | })(), | ||
+ | |||
+ | configs = { | ||
+ | defSpan: 3, | ||
+ | scriptPadding: 20, | ||
+ | topBlank: 60 | ||
+ | }; | ||
+ | |||
+ | function css( elem, styles ){ | ||
+ | if( !(elem && styles) ) | ||
+ | return ; | ||
+ | |||
+ | for(var prop in styles){ | ||
+ | var | ||
+ | key = "", | ||
+ | change = false; | ||
+ | |||
+ | for(var j = 0; j < prop.length; j ++){ | ||
+ | if( prop[j] == '-' ) | ||
+ | change = true; | ||
+ | else{ | ||
+ | key += change ? prop[j].toUpperCase() : prop[j]; | ||
+ | change = false; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if( typeof styles[ prop ] == "function" ) | ||
+ | elem.addEventListener(key, styles[prop]); | ||
+ | else | ||
+ | elem.style[ key ] = styles[ prop ]; | ||
+ | } | ||
+ | } | ||
+ | function Component( node, cls, width, padding ){ | ||
+ | if( typeof node == "string" ){ | ||
+ | this.elem = document.createElement(node); | ||
+ | this.elem.style.visibility = "hidden"; | ||
+ | this.elem.wait = true; | ||
+ | } | ||
+ | else | ||
+ | this.elem = node; | ||
+ | |||
+ | this.elem.id = getUid(); | ||
+ | Component.prototype.iU_book.appendChild(this.elem); | ||
+ | |||
+ | this.padding = padding || 0; | ||
+ | this.width = width - 2*this.padding; | ||
+ | |||
+ | if(cls) | ||
+ | this.elem.className = cls; | ||
+ | |||
+ | if( this.elem.wait ) | ||
+ | this.state = "wait"; | ||
+ | else | ||
+ | this.loaded(); | ||
+ | } | ||
+ | Component.prototype = { | ||
+ | constructor: Component, | ||
+ | loaded: function(){ | ||
+ | css(this.elem,{"width": this.width+"px"}); | ||
+ | this.height= this.elem.offsetHeight; | ||
+ | this.state = "unused"; | ||
+ | }, | ||
+ | place: function(left, top){ | ||
+ | this.left = left; | ||
+ | this.top = top; | ||
+ | this.state= "used"; | ||
+ | }, | ||
+ | render: function( offsetX ){ | ||
+ | css(this.elem, { | ||
+ | "position": "absolute", | ||
+ | "left": (offsetX+this.left) +"px", | ||
+ | "top": this.top +"px", | ||
+ | "visibility": "visible" | ||
+ | }); | ||
+ | }, | ||
+ | toString: function(){ | ||
+ | return "["+this.elem.tagName.toLowerCase() +"] "+ this.elem.innerHTML.substr(0,50)+"\n"; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | function Flow( seq, width, height, top ){ | ||
+ | this.seq = seq; | ||
+ | |||
+ | this.width = width; | ||
+ | this.height = height; | ||
+ | this.top = top; | ||
+ | |||
+ | this.page = 0; | ||
+ | this.frontier = 0; | ||
+ | this.reserve = 0; | ||
+ | this.usedW = 0; | ||
+ | |||
+ | this.comps = []; | ||
+ | this.buffer = []; | ||
+ | this.isVisible = true; | ||
+ | } | ||
+ | Flow.prototype = { | ||
+ | constructor: Flow, | ||
+ | operate: function(){ | ||
+ | var | ||
+ | pause = false; | ||
+ | while( !pause && this.buffer.length > 0 ){ | ||
+ | switch( this.buffer[0].state ){ | ||
+ | case "dispose": this.buffer.shift(); break; | ||
+ | |||
+ | case "pause": | ||
+ | if( this.buffer[0].state == "wait" ){ | ||
+ | pause = true; | ||
+ | break; | ||
+ | } | ||
+ | case "unused": | ||
+ | var | ||
+ | comp = this.buffer.shift(); | ||
+ | |||
+ | if( this.page == 0 ) | ||
+ | this.page = 1; | ||
+ | else if( this.usedW == 0 || this.usedW + comp.width > this.width ){ | ||
+ | if( this.frontier + comp.height > this.height ){ | ||
+ | this.page += 1; | ||
+ | this.frontier = 0; | ||
+ | } | ||
+ | this.reserve = this.frontier; | ||
+ | this.usedW = 0; | ||
+ | } | ||
+ | |||
+ | comp.place(this.width * (this.page-1) + this.usedW + comp.padding, this.reserve + this.top); | ||
+ | comp.state = "used"; | ||
+ | |||
+ | this.usedW += comp.width; | ||
+ | this.frontier = Math.max( this.frontier, this.reserve+comp.height ); | ||
+ | |||
+ | this.comps.push( comp ); | ||
+ | } | ||
+ | } | ||
+ | }, | ||
+ | hide: function(){ | ||
+ | if( this.isVisible ) | ||
+ | for(var i = 0, i_len = this.comps.length; i < i_len; i ++) | ||
+ | this.comps[ i ].elem.style["visibility"] = "hidden"; | ||
+ | |||
+ | this.isVisible = false; | ||
+ | }, | ||
+ | getBreadth: function(){ | ||
+ | return this.page * this.width; | ||
+ | }, | ||
+ | render: function( offsetX ){ | ||
+ | this.isVisible = true; | ||
+ | this.operate(); | ||
+ | |||
+ | for(var i = 0, i_len = this.comps.length; i < i_len; i ++) | ||
+ | this.comps[ i ].render( offsetX ); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | function Book( iU_root, nav ){ | ||
+ | this.interface = document.createElement("div"); | ||
+ | this.interface.id = "iU_book"; | ||
+ | this.nav = nav; | ||
+ | |||
+ | iU_root.parentNode.appendChild( this.interface ); | ||
+ | Component.prototype.iU_book = this.interface; | ||
+ | |||
+ | this.flows = []; | ||
+ | this.buffer = []; | ||
+ | this.nowFlow = null; | ||
+ | this.counter = 0; | ||
+ | |||
+ | this.nav = undefined; | ||
+ | this.width = 0; | ||
+ | this.height = this.interface.clientHeight; | ||
+ | |||
+ | var | ||
+ | _this = this; | ||
+ | this.offset = 0; | ||
+ | this.scroll = function( ev ){ | ||
+ | ev = ev || window.event; | ||
+ | if( ev.preventDefault ) | ||
+ | ev.preventDefault(); | ||
+ | |||
+ | _this.offset -= ev.wheelDelta || ev.detail || 0; | ||
+ | _this.offset = Math.max(_this.offset, 0); | ||
+ | var | ||
+ | accum = 0; | ||
+ | for(var i = 0; i < _this.flows.length; i ++){ | ||
+ | _this.flows[i].render( accum - _this.offset ); | ||
+ | accum += _this.flows[i].getBreadth(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | Book.prototype = { | ||
+ | constructor: Book, | ||
+ | alloc: function( span ){ | ||
+ | this.buffer.push(new Flow( this.counter++, Math.round(window.innerWidth * span / 9), this.height - configs.topBlank, configs.topBlank ) ); | ||
+ | }, | ||
+ | forward: function(){ | ||
+ | if( this.buffer.length == 0 ) | ||
+ | this.alloc( configs.defSpan ); | ||
+ | this.nowFlow = this.buffer.shift(); | ||
+ | this.flows.push(this.nowFlow); | ||
+ | return this.nowFlow; | ||
+ | }, | ||
+ | append: function( node ){ | ||
+ | switch( ((node||{}).tagName||"").toLowerCase() ){ | ||
+ | case "p": case "span": | ||
+ | this.script(node); break; | ||
+ | case "b": | ||
+ | this.title(node); break; | ||
+ | case "img": case "video": | ||
+ | this.image(node); break; | ||
+ | case "dfn": | ||
+ | this.special(node);break; | ||
+ | case "pre": | ||
+ | this.formula(node); break; | ||
+ | default: node.parentNode.removeChild(node); break; | ||
+ | } | ||
+ | }, | ||
+ | script: function( node ){ | ||
+ | var | ||
+ | target = this.nowFlow || this.forward(); | ||
+ | for(var i = 0, i_len = node.childNodes.length; i < i_len; i ++){ | ||
+ | var | ||
+ | e = node.childNodes[i]; | ||
+ | if( !e.attributes ){ | ||
+ | var | ||
+ | child = document.createElement("span"); | ||
+ | child.className = "script"; | ||
+ | child.innerHTML = e.textContent; | ||
+ | node.replaceChild(child, e); | ||
+ | } | ||
+ | } | ||
+ | target.buffer.push( new Component(node, "script", target.width, configs.scriptPadding )); | ||
+ | }, | ||
+ | title: function( node ){ | ||
+ | var | ||
+ | target = this.forward(); | ||
+ | target.buffer.push( new Component(node, "title", target.width, configs.scriptPadding )); | ||
+ | }, | ||
+ | image: function( node ){ | ||
+ | var | ||
+ | target = this.nowFlow || this.forward(), | ||
+ | box = document.createElement("div"), | ||
+ | comp = new Component(node, "title", target.width, configs.scriptPadding ); | ||
+ | node.comp = comp; | ||
+ | target.buffer.push( comp ); | ||
+ | }, | ||
+ | special:function( node ){ | ||
+ | node.parentNode.removeChild(node); | ||
+ | }, | ||
+ | formula: function( node ){ | ||
+ | node.parentNode.removeChild(node); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | function NaviBar( iU_root, logo, sponsors ){ | ||
+ | this.surface = document.createElement("div"); | ||
+ | iU_root.parentNode.appendChild( this.surface ); | ||
+ | |||
+ | this.headings = []; | ||
+ | this.init(logo, sponsors); | ||
+ | |||
+ | this.fstNow = 0; | ||
+ | this.secNow = 0; | ||
+ | this.subheading= null; | ||
+ | } | ||
+ | NaviBar.prototype = { | ||
+ | constructor: NaviBar, | ||
+ | init: function( logo, sponsors ){ | ||
+ | this.surface.id = "NaviBar"; | ||
+ | this.header = document.createElement("div"); | ||
+ | this.header.id = "header"; | ||
+ | |||
+ | logo.id = "logo"; | ||
+ | this.header.appendChild( logo ); | ||
+ | |||
+ | this.ptrH = document.createElement("div"), | ||
+ | this.ptrH.id = "heading pointer"; | ||
+ | this.ptrH.className = "arrow"; | ||
+ | css(this.ptrH,{ | ||
+ | "visibility": "hidden", | ||
+ | "position": "absolute" | ||
+ | }); | ||
+ | this.header.appendChild( this.ptrH ); | ||
+ | |||
+ | |||
+ | this.ptrS = document.createElement("div"); | ||
+ | this.ptrS.id = "subheading pointer"; | ||
+ | this.ptrS.className = "arrow"; | ||
+ | css(this.ptrS,{ | ||
+ | "visibility": "hidden", | ||
+ | "position": "absolute" | ||
+ | }); | ||
+ | this.header.appendChild( this.ptrS ); | ||
+ | |||
+ | this.surface.appendChild( this.header); | ||
+ | |||
+ | var | ||
+ | footer = document.createElement("div"); | ||
+ | footer.id = "footer"; | ||
+ | this.surface.appendChild(footer); | ||
+ | |||
+ | var | ||
+ | strSponsors = document.createElement("span"); | ||
+ | strSponsors.innerHTML = "Sponsors"; | ||
+ | strSponsors.id = "strSponsors"; | ||
+ | footer.appendChild(strSponsors); | ||
+ | |||
+ | for(var i = 0; i < sponsors.length; i ++){ | ||
+ | sponsors[i].className = "sponsor"; | ||
+ | footer.appendChild(sponsors[i]); | ||
+ | } | ||
+ | }, | ||
+ | jumpTo: function( path ){ | ||
+ | if( !path ) | ||
+ | return false; | ||
+ | |||
+ | var | ||
+ | tarF, tarS; | ||
+ | if( typeof path == "string" ){ | ||
+ | var | ||
+ | sep = path.split(/\s*\.\s*/); | ||
+ | if( !sep[0] ) | ||
+ | return false; | ||
+ | |||
+ | var | ||
+ | fst = sep[0].toUpperCase(), | ||
+ | h = this.headings, | ||
+ | s = null; | ||
+ | |||
+ | for(var i = 0; i < h.length; i ++){ | ||
+ | if( h[i].innerHTML == fst ){ | ||
+ | tarF = i; | ||
+ | s = h[i]._catalog.children; | ||
+ | } | ||
+ | } | ||
+ | if( !s ) | ||
+ | return false; | ||
+ | |||
+ | if(sep[1]){ | ||
+ | var | ||
+ | sec = sep[1].toUpperCase(); | ||
+ | for(var i = 0; i < s.length; i ++) | ||
+ | if( s[i].innerHTML == sec ) | ||
+ | tarS = i; | ||
+ | } | ||
+ | else | ||
+ | tarS = 0; | ||
+ | } | ||
+ | else{ | ||
+ | tarF = path[0]; | ||
+ | tarS = path[1]; | ||
+ | if(!(tarF === +tarF && tarS === +tarS)) | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | var | ||
+ | fstElem = this.headings[ tarF ], | ||
+ | t = fstElem.offsetTop + fstElem.clientHeight - 3, | ||
+ | l = fstElem.offsetLeft + fstElem.clientWidth*0.5 - 5; | ||
+ | |||
+ | css(this.ptrH,{ | ||
+ | "top": Math.round(t) + "px", | ||
+ | "left": Math.round(l) + "px", | ||
+ | "visibility": "visible" | ||
+ | }); | ||
+ | |||
+ | if(this.subheading) | ||
+ | this.subheading.className = "HiddenCatalog"; | ||
+ | |||
+ | this.subheading = h[ tarF ]._catalog; | ||
+ | this.subheading.className = "VisibleCatalog" | ||
+ | |||
+ | return true; | ||
+ | }, | ||
+ | addPath: function( path, jumpFunc ){ | ||
+ | var | ||
+ | sep = path.split(/\s*\.\s*/); | ||
+ | if( !(sep[0] && sep[1]) ) | ||
+ | return false; | ||
+ | |||
+ | var | ||
+ | fst = sep[0].toUpperCase(), | ||
+ | sec = sep[1].toUpperCase(), | ||
+ | _this = this, | ||
+ | h = this.headings, | ||
+ | target = null; | ||
+ | |||
+ | for(var i = 0; i < h.length; i ++) | ||
+ | if( h[i].innerHTML == fst ) | ||
+ | target = h[i]; | ||
+ | |||
+ | if( !target ){ | ||
+ | target = document.createElement("span"); | ||
+ | target.className = "H1"; | ||
+ | target.innerHTML = fst; | ||
+ | |||
+ | target._catalog = document.createElement("div"); | ||
+ | target._catalog.className = "HiddenCatalog"; | ||
+ | this.header.appendChild(target._catalog); | ||
+ | |||
+ | target.addEventListener("mousedown",(function(fst, target){ | ||
+ | return function(){ | ||
+ | _this.jumpTo( fst ); | ||
+ | if(_this.subheading) | ||
+ | _this.subheading.className = "HiddenCatalog"; | ||
+ | |||
+ | _this.subheading = target._catalog; | ||
+ | _this.subheading.className = "VisibleCatalog"; | ||
+ | }; | ||
+ | })(fst, target) ); | ||
+ | |||
+ | this.header.appendChild(target); | ||
+ | this.headings.push(target); | ||
+ | |||
+ | var accum = [ 0 ]; | ||
+ | for(var i = 0; i < this.headings.length; i ++) | ||
+ | accum[i+1] = accum[i] + this.headings[i].clientWidth + 60; | ||
+ | |||
+ | var left = Math.round(window.innerWidth * 0.6 - accum.pop()/2); | ||
+ | for(var i = 0; i < this.headings.length; i ++) | ||
+ | css(this.headings[i],{ | ||
+ | "left": (left + accum[i]) + "px" | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | var | ||
+ | s = target._catalog.children; | ||
+ | for(var i = 0; i < s.length; i ++) | ||
+ | if( s[i].innerHTML == sec ){ | ||
+ | s[i]._jumpFunc = jumpFunc; | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | var | ||
+ | subheading = document.createElement("span"); | ||
+ | subheading.className = "H2"; | ||
+ | subheading.innerHTML = sec; | ||
+ | subheading._jumpFunc = jumpFunc; | ||
+ | subheading.addEventListener("mouseover",function(){ | ||
+ | _this.jumpTo( path ); | ||
+ | }); | ||
+ | target._catalog.appendChild(subheading); | ||
+ | |||
+ | var accum = [ 0 ]; | ||
+ | for(var i = 0; i < s.length; i ++) | ||
+ | accum[i+1] = accum[i] + s[i].clientWidth + 60; | ||
+ | |||
+ | var left = Math.round(window.innerWidth * 0.6 - accum.pop()/2); | ||
+ | for(var i = 0; i < s.length; i ++) | ||
+ | css(s[i],{ | ||
+ | "left": (left + accum[i]) + "px" | ||
+ | }); | ||
+ | return true; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | function Loader( iU_root, cover ){ | ||
+ | this.boot = document.createElement("div"); | ||
+ | this.boot.id = "loader"; | ||
+ | iU_root.parentNode.appendChild( this.boot ); | ||
+ | |||
+ | this.total = 0; | ||
+ | this.loaded = 0; | ||
+ | this.failed = 0; | ||
+ | |||
+ | var | ||
+ | _this = this; | ||
+ | this.load = function( img ){ | ||
+ | if( !img.height ){ | ||
+ | img.onload = function(){ | ||
+ | _this.loaded ++; | ||
+ | if(img.comp) | ||
+ | img.comp.state = "unused"; | ||
+ | }; | ||
+ | img.onerr = function(){ | ||
+ | _this.failed ++; | ||
+ | if(img.comp) | ||
+ | img.comp.state = "dispose"; | ||
+ | }; | ||
+ | img.wait = true; | ||
+ | _this.total ++; | ||
+ | } | ||
+ | }; | ||
+ | } | ||
+ | Loader.prototype.constructor = Loader; | ||
+ | |||
+ | var | ||
+ | fn = { | ||
+ | initRoot: function( overflow ){ | ||
+ | var | ||
+ | iU_root = document.getElementById("igemUCAS"); | ||
+ | |||
+ | if( !iU_root ) | ||
+ | return null; | ||
+ | |||
+ | iU_root.style.visibility = "hidden"; | ||
+ | iU_root.style["z-index"] = "-100"; | ||
+ | |||
+ | |||
+ | inspect("fn.initRoot").assert(iU_root, ""); | ||
+ | return iU_root; | ||
+ | }, | ||
+ | initWebGL: function( iU_root ){ | ||
+ | var | ||
+ | canvas = document.createElement("canvas"); | ||
+ | |||
+ | canvas.id = "bgCanvas"; | ||
+ | canvas.width = window.innerWidth; | ||
+ | canvas.height = window.innerHeight; | ||
+ | iU_root.parentNode.appendChild(canvas); | ||
+ | |||
+ | var | ||
+ | gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); | ||
+ | |||
+ | if(gl) | ||
+ | css(canvas, { | ||
+ | "position":"absolute", | ||
+ | "top":"0", | ||
+ | "left":"0", | ||
+ | "z-index":"-90", | ||
+ | "overflow":"hidden", | ||
+ | "visibility":"visible" | ||
+ | }); | ||
+ | |||
+ | return gl; | ||
+ | }, | ||
+ | initBase: function( iU_root ){ | ||
+ | var | ||
+ | iU_base = document.createElement("div"); | ||
+ | iU_base.id = "UCASigem"; | ||
+ | iU_base.style.position = "absolute"; | ||
+ | |||
+ | iU_root.parentNode.appendChild(iU_base); | ||
+ | return iU_base; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | function igemUCAS(){ | ||
+ | var | ||
+ | iU_root = fn.initRoot(); | ||
+ | if( !iU_root ) | ||
+ | return inspect.root_not_found(); | ||
+ | |||
+ | var | ||
+ | gl = fn.initWebGL( iU_root ); | ||
+ | if( !gl ) | ||
+ | inspect.gl_not_supported(); | ||
+ | |||
+ | var | ||
+ | icons = iU_root.children[0].children; | ||
+ | cover = icons[0], | ||
+ | logo = icons[1], | ||
+ | sponsors = []; | ||
+ | iU_root.removeChild(iU_root.children[0]); | ||
+ | for(var i = 2; i < icons.length; i ++) | ||
+ | sponsors.push( icons[i] ); | ||
+ | |||
+ | var | ||
+ | loader = new Loader ( iU_root, cover ), | ||
+ | nav = new NaviBar( iU_root, logo, sponsors ); | ||
+ | book = new Book( iU_root, nav ); | ||
+ | |||
+ | for(var i = 0; i < icons.length; i ++) | ||
+ | loader.load(icons[i]); | ||
+ | |||
+ | nav.addPath("project.description"); | ||
+ | nav.addPath("project.light to color"); | ||
+ | nav.addPath("project.light to odor"); | ||
+ | nav.addPath("project.sound to light"); | ||
+ | nav.addPath("results.overview"); | ||
+ | nav.addPath("results.the rose!"); | ||
+ | nav.addPath("results.hardware"); | ||
+ | nav.addPath("results.software"); | ||
+ | nav.addPath("results.proof & demonstrate"); | ||
+ | nav.addPath("results.model"); | ||
+ | nav.addPath("results.parts"); | ||
+ | nav.addPath("human practice.gift for the world"); | ||
+ | nav.addPath("human practice.integrated human practice"); | ||
+ | nav.addPath("human practice.public engagement"); | ||
+ | nav.addPath("human practice.expert interviews"); | ||
+ | nav.addPath("human practice.safety & security"); | ||
+ | nav.addPath("human practice.education"); | ||
+ | nav.addPath("human practice.collaborations"); | ||
+ | nav.addPath("people.meet the team"); | ||
+ | nav.addPath("people.arrtibutions"); | ||
+ | nav.addPath("people.medal achievement"); | ||
+ | nav.addPath("people.notebook"); | ||
+ | |||
+ | nav.jumpTo("human practice.safety & security"); | ||
+ | |||
+ | while( iU_root.children.length > 0 ){ | ||
+ | var | ||
+ | node = iU_root.children[0]; | ||
+ | node.style.visibility = "hidden"; | ||
+ | if( (node||{}).tagName == "IMAGE" ) | ||
+ | loader.load(node); | ||
+ | book.append( node ); | ||
+ | } | ||
+ | |||
+ | document.addEventListener("DOMMouseScroll", book.scroll, false); | ||
+ | window.onmousewheel = document.onmousewheel = book.scroll; | ||
+ | book.scroll( {wheelDelta: 0} ); | ||
+ | inspect.displayErrors(); | ||
+ | } | ||
+ | return igemUCAS; | ||
+ | }); |
Latest revision as of 10:32, 14 October 2018
/*!
* igemUCAS JavaScript Library v0.18.1 * Copyright UCAS iGEM team */
( function( global, factory ) { var iU = global.iU = factory(global); iU(); } ) (window, function( window ) { var document = window.document, inspect = (function(){ var strErr = "igemUCAS v0.18.19\n", nextseq = 1, error = function( location, desc ){ strErr = strErr.concat(nextseq, " ", location, ": ", desc, '\n'); nextseq ++; }, garrison = function( name ){ var f = { string: function( s ){ if( (!s) || typeof s != 'string' ) error(name, "parameter should be of ."); return f; }, number: function( s ){ if( (!s) || typeof s != 'number' ) error(name, "parameter should be of number type."); return f; }, keyUnused: function(obj, key){ if( obj[key] ) error(name, "key "+key+" has been used."); return f; }, assert: function( val, desc ){ if( !val ) error(name, desc ); return f; } }; return f; };
garrison.displayErrors = function(){ if(strErr.length == 0 ) console.log("No errors, Congrats!") else console.log( strErr ); }; garrison.root_not_found = function(){ console.log("DIV igemUCAS does not exist."); garrison.displayErrors(); }; garrison.gl_not_supported = function(){ console.log("WebGL is not supported."); } return garrison; })(),
getUid = (function(){ var now = -1; return function(){ now ++; return (function(n){ return '_'+n+'_'; })(now); }; })(),
configs = { defSpan: 3, scriptPadding: 20, topBlank: 60 };
function css( elem, styles ){ if( !(elem && styles) ) return ;
for(var prop in styles){ var key = "", change = false;
for(var j = 0; j < prop.length; j ++){ if( prop[j] == '-' ) change = true; else{ key += change ? prop[j].toUpperCase() : prop[j]; change = false; } }
if( typeof styles[ prop ] == "function" ) elem.addEventListener(key, styles[prop]); else elem.style[ key ] = styles[ prop ]; } } function Component( node, cls, width, padding ){ if( typeof node == "string" ){ this.elem = document.createElement(node); this.elem.style.visibility = "hidden"; this.elem.wait = true; } else this.elem = node;
this.elem.id = getUid(); Component.prototype.iU_book.appendChild(this.elem);
this.padding = padding || 0; this.width = width - 2*this.padding;
if(cls) this.elem.className = cls;
if( this.elem.wait ) this.state = "wait"; else this.loaded(); } Component.prototype = { constructor: Component, loaded: function(){ css(this.elem,{"width": this.width+"px"}); this.height= this.elem.offsetHeight; this.state = "unused"; }, place: function(left, top){ this.left = left; this.top = top; this.state= "used"; }, render: function( offsetX ){ css(this.elem, { "position": "absolute", "left": (offsetX+this.left) +"px", "top": this.top +"px", "visibility": "visible" }); }, toString: function(){ return "["+this.elem.tagName.toLowerCase() +"] "+ this.elem.innerHTML.substr(0,50)+"\n"; } };
function Flow( seq, width, height, top ){ this.seq = seq;
this.width = width; this.height = height; this.top = top;
this.page = 0; this.frontier = 0; this.reserve = 0; this.usedW = 0;
this.comps = []; this.buffer = []; this.isVisible = true; } Flow.prototype = { constructor: Flow, operate: function(){ var pause = false; while( !pause && this.buffer.length > 0 ){ switch( this.buffer[0].state ){ case "dispose": this.buffer.shift(); break;
case "pause": if( this.buffer[0].state == "wait" ){ pause = true; break; } case "unused": var comp = this.buffer.shift();
if( this.page == 0 ) this.page = 1; else if( this.usedW == 0 || this.usedW + comp.width > this.width ){ if( this.frontier + comp.height > this.height ){ this.page += 1; this.frontier = 0; } this.reserve = this.frontier; this.usedW = 0; }
comp.place(this.width * (this.page-1) + this.usedW + comp.padding, this.reserve + this.top); comp.state = "used";
this.usedW += comp.width; this.frontier = Math.max( this.frontier, this.reserve+comp.height );
this.comps.push( comp ); } } }, hide: function(){ if( this.isVisible ) for(var i = 0, i_len = this.comps.length; i < i_len; i ++) this.comps[ i ].elem.style["visibility"] = "hidden";
this.isVisible = false; }, getBreadth: function(){ return this.page * this.width; }, render: function( offsetX ){ this.isVisible = true; this.operate();
for(var i = 0, i_len = this.comps.length; i < i_len; i ++) this.comps[ i ].render( offsetX ); } };
function Book( iU_root, nav ){ this.interface = document.createElement("div"); this.interface.id = "iU_book"; this.nav = nav;
iU_root.parentNode.appendChild( this.interface ); Component.prototype.iU_book = this.interface;
this.flows = []; this.buffer = []; this.nowFlow = null; this.counter = 0;
this.nav = undefined; this.width = 0; this.height = this.interface.clientHeight;
var _this = this; this.offset = 0; this.scroll = function( ev ){ ev = ev || window.event; if( ev.preventDefault ) ev.preventDefault();
_this.offset -= ev.wheelDelta || ev.detail || 0; _this.offset = Math.max(_this.offset, 0); var accum = 0; for(var i = 0; i < _this.flows.length; i ++){ _this.flows[i].render( accum - _this.offset ); accum += _this.flows[i].getBreadth(); } } } Book.prototype = { constructor: Book, alloc: function( span ){ this.buffer.push(new Flow( this.counter++, Math.round(window.innerWidth * span / 9), this.height - configs.topBlank, configs.topBlank ) ); }, forward: function(){ if( this.buffer.length == 0 ) this.alloc( configs.defSpan ); this.nowFlow = this.buffer.shift(); this.flows.push(this.nowFlow); return this.nowFlow; }, append: function( node ){ switch( ((node||{}).tagName||"").toLowerCase() ){ case "p": case "span": this.script(node); break; case "b": this.title(node); break; case "img": case "video": this.image(node); break; case "dfn": this.special(node);break; case "pre": this.formula(node); break; default: node.parentNode.removeChild(node); break; } }, script: function( node ){ var target = this.nowFlow || this.forward(); for(var i = 0, i_len = node.childNodes.length; i < i_len; i ++){ var e = node.childNodes[i]; if( !e.attributes ){ var child = document.createElement("span"); child.className = "script"; child.innerHTML = e.textContent; node.replaceChild(child, e); } } target.buffer.push( new Component(node, "script", target.width, configs.scriptPadding )); }, title: function( node ){ var target = this.forward(); target.buffer.push( new Component(node, "title", target.width, configs.scriptPadding )); }, image: function( node ){ var target = this.nowFlow || this.forward(), box = document.createElement("div"), comp = new Component(node, "title", target.width, configs.scriptPadding ); node.comp = comp; target.buffer.push( comp ); }, special:function( node ){ node.parentNode.removeChild(node); }, formula: function( node ){ node.parentNode.removeChild(node); } };
function NaviBar( iU_root, logo, sponsors ){ this.surface = document.createElement("div"); iU_root.parentNode.appendChild( this.surface );
this.headings = []; this.init(logo, sponsors);
this.fstNow = 0; this.secNow = 0; this.subheading= null; } NaviBar.prototype = { constructor: NaviBar, init: function( logo, sponsors ){ this.surface.id = "NaviBar"; this.header = document.createElement("div"); this.header.id = "header";
logo.id = "logo"; this.header.appendChild( logo );
this.ptrH = document.createElement("div"), this.ptrH.id = "heading pointer"; this.ptrH.className = "arrow"; css(this.ptrH,{ "visibility": "hidden", "position": "absolute" }); this.header.appendChild( this.ptrH );
this.ptrS = document.createElement("div");
this.ptrS.id = "subheading pointer";
this.ptrS.className = "arrow";
css(this.ptrS,{
"visibility": "hidden",
"position": "absolute"
});
this.header.appendChild( this.ptrS );
this.surface.appendChild( this.header);
var footer = document.createElement("div"); footer.id = "footer"; this.surface.appendChild(footer);
var strSponsors = document.createElement("span"); strSponsors.innerHTML = "Sponsors"; strSponsors.id = "strSponsors"; footer.appendChild(strSponsors);
for(var i = 0; i < sponsors.length; i ++){ sponsors[i].className = "sponsor"; footer.appendChild(sponsors[i]); } }, jumpTo: function( path ){ if( !path ) return false;
var tarF, tarS; if( typeof path == "string" ){ var sep = path.split(/\s*\.\s*/); if( !sep[0] ) return false;
var fst = sep[0].toUpperCase(), h = this.headings, s = null;
for(var i = 0; i < h.length; i ++){ if( h[i].innerHTML == fst ){ tarF = i; s = h[i]._catalog.children; } } if( !s ) return false;
if(sep[1]){ var sec = sep[1].toUpperCase(); for(var i = 0; i < s.length; i ++) if( s[i].innerHTML == sec ) tarS = i; } else tarS = 0; } else{ tarF = path[0]; tarS = path[1]; if(!(tarF === +tarF && tarS === +tarS)) return false; }
var fstElem = this.headings[ tarF ], t = fstElem.offsetTop + fstElem.clientHeight - 3, l = fstElem.offsetLeft + fstElem.clientWidth*0.5 - 5;
css(this.ptrH,{ "top": Math.round(t) + "px", "left": Math.round(l) + "px", "visibility": "visible" });
if(this.subheading) this.subheading.className = "HiddenCatalog";
this.subheading = h[ tarF ]._catalog; this.subheading.className = "VisibleCatalog"
return true; }, addPath: function( path, jumpFunc ){ var sep = path.split(/\s*\.\s*/); if( !(sep[0] && sep[1]) ) return false;
var fst = sep[0].toUpperCase(), sec = sep[1].toUpperCase(), _this = this, h = this.headings, target = null;
for(var i = 0; i < h.length; i ++) if( h[i].innerHTML == fst ) target = h[i];
if( !target ){ target = document.createElement("span"); target.className = "H1"; target.innerHTML = fst;
target._catalog = document.createElement("div"); target._catalog.className = "HiddenCatalog"; this.header.appendChild(target._catalog);
target.addEventListener("mousedown",(function(fst, target){ return function(){ _this.jumpTo( fst ); if(_this.subheading) _this.subheading.className = "HiddenCatalog";
_this.subheading = target._catalog; _this.subheading.className = "VisibleCatalog"; }; })(fst, target) );
this.header.appendChild(target); this.headings.push(target);
var accum = [ 0 ]; for(var i = 0; i < this.headings.length; i ++) accum[i+1] = accum[i] + this.headings[i].clientWidth + 60;
var left = Math.round(window.innerWidth * 0.6 - accum.pop()/2); for(var i = 0; i < this.headings.length; i ++) css(this.headings[i],{ "left": (left + accum[i]) + "px" }); }
var s = target._catalog.children; for(var i = 0; i < s.length; i ++) if( s[i].innerHTML == sec ){ s[i]._jumpFunc = jumpFunc; return true; }
var subheading = document.createElement("span"); subheading.className = "H2"; subheading.innerHTML = sec; subheading._jumpFunc = jumpFunc; subheading.addEventListener("mouseover",function(){ _this.jumpTo( path ); }); target._catalog.appendChild(subheading);
var accum = [ 0 ]; for(var i = 0; i < s.length; i ++) accum[i+1] = accum[i] + s[i].clientWidth + 60;
var left = Math.round(window.innerWidth * 0.6 - accum.pop()/2); for(var i = 0; i < s.length; i ++) css(s[i],{ "left": (left + accum[i]) + "px" }); return true; } };
function Loader( iU_root, cover ){ this.boot = document.createElement("div"); this.boot.id = "loader"; iU_root.parentNode.appendChild( this.boot );
this.total = 0; this.loaded = 0; this.failed = 0;
var _this = this; this.load = function( img ){ if( !img.height ){ img.onload = function(){ _this.loaded ++; if(img.comp) img.comp.state = "unused"; }; img.onerr = function(){ _this.failed ++; if(img.comp) img.comp.state = "dispose"; }; img.wait = true; _this.total ++; } }; } Loader.prototype.constructor = Loader;
var fn = { initRoot: function( overflow ){ var iU_root = document.getElementById("igemUCAS");
if( !iU_root ) return null;
iU_root.style.visibility = "hidden"; iU_root.style["z-index"] = "-100";
inspect("fn.initRoot").assert(iU_root, "");
return iU_root;
},
initWebGL: function( iU_root ){
var
canvas = document.createElement("canvas");
canvas.id = "bgCanvas"; canvas.width = window.innerWidth; canvas.height = window.innerHeight; iU_root.parentNode.appendChild(canvas);
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if(gl) css(canvas, { "position":"absolute", "top":"0", "left":"0", "z-index":"-90", "overflow":"hidden", "visibility":"visible" });
return gl; }, initBase: function( iU_root ){ var iU_base = document.createElement("div"); iU_base.id = "UCASigem"; iU_base.style.position = "absolute";
iU_root.parentNode.appendChild(iU_base); return iU_base; } };
function igemUCAS(){ var iU_root = fn.initRoot(); if( !iU_root ) return inspect.root_not_found();
var gl = fn.initWebGL( iU_root ); if( !gl ) inspect.gl_not_supported();
var icons = iU_root.children[0].children; cover = icons[0], logo = icons[1], sponsors = []; iU_root.removeChild(iU_root.children[0]); for(var i = 2; i < icons.length; i ++) sponsors.push( icons[i] );
var loader = new Loader ( iU_root, cover ), nav = new NaviBar( iU_root, logo, sponsors ); book = new Book( iU_root, nav );
for(var i = 0; i < icons.length; i ++) loader.load(icons[i]);
nav.addPath("project.description"); nav.addPath("project.light to color"); nav.addPath("project.light to odor"); nav.addPath("project.sound to light"); nav.addPath("results.overview"); nav.addPath("results.the rose!"); nav.addPath("results.hardware"); nav.addPath("results.software"); nav.addPath("results.proof & demonstrate"); nav.addPath("results.model"); nav.addPath("results.parts"); nav.addPath("human practice.gift for the world"); nav.addPath("human practice.integrated human practice"); nav.addPath("human practice.public engagement"); nav.addPath("human practice.expert interviews"); nav.addPath("human practice.safety & security"); nav.addPath("human practice.education"); nav.addPath("human practice.collaborations"); nav.addPath("people.meet the team"); nav.addPath("people.arrtibutions"); nav.addPath("people.medal achievement"); nav.addPath("people.notebook");
nav.jumpTo("human practice.safety & security");
while( iU_root.children.length > 0 ){ var node = iU_root.children[0]; node.style.visibility = "hidden"; if( (node||{}).tagName == "IMAGE" ) loader.load(node); book.append( node ); }
document.addEventListener("DOMMouseScroll", book.scroll, false); window.onmousewheel = document.onmousewheel = book.scroll; book.scroll( {wheelDelta: 0} ); inspect.displayErrors(); } return igemUCAS; });