m |
m |
||
Line 1: | Line 1: | ||
/*! | /*! | ||
− | * igemUCAS JavaScript Library v0.18. | + | * igemUCAS JavaScript Library v0.18.16 |
− | + | ||
− | + | ||
− | + | ||
* Copyright UCAS iGEM team | * Copyright UCAS iGEM team | ||
*/ | */ | ||
− | ( function( global, factory ) { global.iU = factory(global); } ) (window, function( window ) { | + | |
− | var | + | ( function( global, factory ) { var iU = global.iU = factory(global); iU(); } ) (window, function( window ) { |
− | + | var | |
+ | document = window.document, | ||
+ | inspect = (function(){ | ||
+ | var | ||
+ | strErr = "", | ||
+ | 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 ) | ||
+ | alert("No errors, Congrats!") | ||
+ | else | ||
+ | alert( strErr ); | ||
+ | }; | ||
+ | return garrison; | ||
+ | })(), | ||
+ | |||
+ | utils = { | ||
+ | inherit: function( p, e ){ | ||
+ | for(var prop in e) | ||
+ | p[prop] = e[prop]; | ||
+ | return p; | ||
+ | }, | ||
+ | |||
+ | getUid: (function(){ | ||
+ | var now = -1; | ||
+ | return function(){ | ||
+ | now ++; | ||
+ | return (function(n){ | ||
+ | return '_'+n+'_'; | ||
+ | })(now); | ||
+ | }; | ||
+ | })() | ||
+ | }, | ||
+ | |||
+ | schema = { | ||
+ | general: { | ||
+ | "font-family" : "Georgia", | ||
+ | "text-align" : "justify", | ||
+ | "font-size" : "20px" | ||
+ | }, | ||
+ | p: { | ||
+ | |||
+ | } | ||
+ | }; | ||
+ | |||
+ | function Component( node, id ){ | ||
+ | this.elem = (typeof node == "string") ? document.createElement(node) : node; | ||
+ | this.elem.id = id || utils.getUid(); | ||
+ | this.elem.style.visibility = "hidden"; | ||
+ | |||
+ | this.iU_base.appendChild(this.elem); | ||
+ | } | ||
+ | Component.prototype = { | ||
+ | constructor: Component, | ||
+ | setSchema: function( schema ){ | ||
+ | this.css( schema.general ); | ||
+ | for(var i in this.elem.childNodes){ | ||
+ | var | ||
+ | child = this.elem.childNodes[i]; | ||
+ | this.css( schema[ child.tagName || "" ], child ); | ||
+ | } | ||
+ | }, | ||
+ | adaptWidth: function( width ){ | ||
+ | var ratio = this.elem.clientHeight / this.elem.clientWidth; | ||
+ | this.css({ | ||
+ | width: width + "px", | ||
+ | height: width*ratio + "px" | ||
+ | }); | ||
+ | return this.clientHeight; | ||
+ | }, | ||
+ | css: function( styles, elem ){ | ||
+ | elem = this.elem || elem; | ||
+ | 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; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | elem.style[ prop ] = styles[ prop ]; | ||
+ | } | ||
+ | }, | ||
+ | upgradeText: function(){ | ||
+ | for(var i = 0, i_len = this.elem.childNodes.length; i < i_len; i ++){ | ||
+ | var | ||
+ | node = this.elem.childNodes[i]; | ||
+ | if( !node.attributes ){ | ||
+ | var | ||
+ | child = document.createElement("span"); | ||
+ | child.innerHTML = node.textContent; | ||
+ | this.elem.replaceChild(child, node); | ||
+ | } | ||
+ | } | ||
+ | } | ||
}; | }; | ||
− | return | + | |
+ | var | ||
+ | Factory = { | ||
+ | text: function( node ){ | ||
+ | var | ||
+ | comp = new Component( node, node["name"] ); | ||
+ | comp.upgradeText(); | ||
+ | comp.adaptWidth = Factory.textAdapt; | ||
+ | comp.setSchema( schema ); | ||
+ | |||
+ | return comp; | ||
+ | }, | ||
+ | textAdapt: function( width, lineHeight ){ | ||
+ | this.css({ | ||
+ | "width": width + "px", | ||
+ | "line-height": lineHeight + "px", | ||
+ | "font-size": lineHeight*0.7 + "px" | ||
+ | }); | ||
+ | return this.elem.clientHeight; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | function Piece( comp, bounds ){ | ||
+ | this.comp = comp; | ||
+ | this.width = bounds.width; | ||
+ | this.height = bounds.height; | ||
+ | this.LR = bounds.LR; | ||
+ | |||
+ | this.styles = {}; | ||
+ | } | ||
+ | Piece.prototype = { | ||
+ | constructor: Piece, | ||
+ | render: function( offsetX, offsetY ){ | ||
+ | this.comp.css({ | ||
+ | "position": "absolute", | ||
+ | "left": offsetX + (this.left || 0)+"px", | ||
+ | "top": offsetY + (this.top || 0)+"px", | ||
+ | "width": this.width, | ||
+ | "visibility": "visible" | ||
+ | }); | ||
+ | }, | ||
+ | toString: function(){ | ||
+ | return this.comp.elem.tagName.toLowerCase() + ":" + this.comp.elem.innerHTML.substring(0,50)+"\n"; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | |||
+ | function Page(){ | ||
+ | this.oe = 0; | ||
+ | this.pieces = []; | ||
+ | } | ||
+ | Page.prototype = { | ||
+ | constructor: Page, | ||
+ | push: function( piece ){ | ||
+ | this.pieces.push( piece ); | ||
+ | }, | ||
+ | setOE: function( oe ){ | ||
+ | switch(oe){ | ||
+ | case 1: case 2: case 3: case 4: | ||
+ | this.oe = oe; | ||
+ | default: | ||
+ | }; | ||
+ | }, | ||
+ | render: function( conds ){ | ||
+ | var | ||
+ | offsetX = (this.oe==2 || this.oe==4) ? conds.width : 0, | ||
+ | pieces = this.pieces; | ||
+ | |||
+ | for(var i = 0; i < pieces.length; i ++) | ||
+ | pieces[i].render(0,0); | ||
+ | }, | ||
+ | toString: function(){ | ||
+ | var | ||
+ | res = "page:len=" + this.pieces.length +"\n"; | ||
+ | for(var i = 0; i < this.pieces.length; i ++) | ||
+ | res += this.pieces[i].toString(); | ||
+ | return res; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | function Flow( width, spacing ){ | ||
+ | this.width = width; | ||
+ | this.spacing = spacing; | ||
+ | |||
+ | this.buffer = []; | ||
+ | this.remnant = []; | ||
+ | } | ||
+ | Flow.prototype = { | ||
+ | constructor: Flow, | ||
+ | newPiece: function( comp, L, R){ | ||
+ | var | ||
+ | width = Math.round( (R - L)*this.width/12 ), | ||
+ | height= comp.adaptWidth(width); | ||
+ | return new Piece( comp, { | ||
+ | LR:[ L, R], | ||
+ | width:width, | ||
+ | height:height | ||
+ | }); | ||
+ | }, | ||
+ | script: function( node ){ | ||
+ | var | ||
+ | t = this.newPiece( Factory.text(node), node.L, node.R ); | ||
+ | this.buffer.push( t ); | ||
+ | }, | ||
+ | cut: function( maxHeight ){ | ||
+ | var | ||
+ | page = new Page(), | ||
+ | frontier = new Array(12); | ||
+ | |||
+ | for(var i = 0; i < 12; i ++) | ||
+ | frontier[i] = 0; | ||
+ | |||
+ | while( this.buffer.length > 0 ){ | ||
+ | //hr | ||
+ | |||
+ | if( frontier[0] + this.buffer[0].height > maxHeight ){ | ||
+ | alert("max height:" + maxHeight); | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | var | ||
+ | piece = this.buffer.shift(); | ||
+ | piece.top = frontier[0]; | ||
+ | piece.left = piece.LR[0] * this.width / 12; | ||
+ | page.push( piece ); | ||
+ | |||
+ | frontier[0] += piece.height + this.spacing; | ||
+ | } | ||
+ | return page; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | function Book(){ | ||
+ | |||
+ | } | ||
+ | Book.prototype = { | ||
+ | constructor: Book | ||
+ | }; | ||
+ | |||
+ | |||
+ | |||
+ | 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"; | ||
+ | |||
+ | if( overflow ){ | ||
+ | var | ||
+ | webpage = document.getElementsByTagName("html")[0]; | ||
+ | webpage.style.overflowX = "hidden"; | ||
+ | webpage.style.overflowY = "hidden"; | ||
+ | webpage.style.padding = "0px"; | ||
+ | webpage.style.margin = "0px"; | ||
+ | } | ||
+ | |||
+ | 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) | ||
+ | Component.prototype.css({ | ||
+ | "position":"absolute", | ||
+ | "top":"0", | ||
+ | "left":"0", | ||
+ | "z-index":"-90", | ||
+ | "overflow":"hidden", | ||
+ | "visibility":"visible" | ||
+ | }, canvas); | ||
+ | |||
+ | return gl; | ||
+ | }, | ||
+ | initBase: function( iU_root ){ | ||
+ | var | ||
+ | iU_base = document.createElement("div"); | ||
+ | iU_base.id = "iU_base"; | ||
+ | iU_base.style.position = "absolute"; | ||
+ | |||
+ | iU_root.parentNode.appendChild(iU_base); | ||
+ | return iU_base; | ||
+ | }, | ||
+ | |||
+ | root_not_found: function(){ | ||
+ | |||
+ | }, | ||
+ | gl_not_supported: function(){ | ||
+ | |||
+ | }, | ||
+ | defaultConfig: { | ||
+ | overflow: true, | ||
+ | webgl: true | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function igemUCAS(){ | ||
+ | |||
+ | var | ||
+ | iU_root = fn.initRoot( (window.configs||fn.defaultConfig).overflow ); | ||
+ | if( !iU_root ) | ||
+ | return fn.root_not_found(); | ||
+ | |||
+ | var | ||
+ | iU_base = fn.initBase( iU_root ); | ||
+ | Component.prototype.iU_base = iU_base; | ||
+ | |||
+ | var | ||
+ | gl = (window.configs||fn.defaultConfig).webgl || fn.initWebGL( iU_root ); | ||
+ | if( !gl ) | ||
+ | fn.gl_not_supported(); | ||
+ | |||
+ | |||
+ | var | ||
+ | flow = new Flow( window.innerWidth/2, 20 ), | ||
+ | book = new Book(); | ||
+ | |||
+ | while( iU_root.childNodes.length > 0 ){ | ||
+ | var | ||
+ | node = iU_root.childNodes[0]; | ||
+ | |||
+ | node.L = 2; | ||
+ | node.R = 10; | ||
+ | |||
+ | switch( ((node||{}).tagName||"").toLowerCase() ){ | ||
+ | case "figure": | ||
+ | while( node.childNodes.length > 0){ | ||
+ | switch( ((node.childNodes[0]||{}).tagName||"").toLowerCase() ){ | ||
+ | case "p": flow.script(node); break; | ||
+ | } | ||
+ | } | ||
+ | iU_root.removeChild(node); | ||
+ | break; | ||
+ | case "p": flow.script(node); break; | ||
+ | |||
+ | default: iU_root.removeChild(node); break; | ||
+ | } | ||
+ | } | ||
+ | var | ||
+ | page = flow.cut( window.innerHeight ); | ||
+ | |||
+ | console.log(page.toString()); | ||
+ | page.render({width:0}); | ||
+ | } | ||
+ | igemUCAS.displayErrors = inspect.displayErrors; | ||
+ | |||
+ | return igemUCAS; | ||
}); | }); |
Revision as of 11:40, 6 October 2018
/*!
* igemUCAS JavaScript Library v0.18.16 * 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 = "", 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 ) alert("No errors, Congrats!") else alert( strErr ); }; return garrison; })(),
utils = { inherit: function( p, e ){ for(var prop in e) p[prop] = e[prop]; return p; },
getUid: (function(){ var now = -1; return function(){ now ++; return (function(n){ return '_'+n+'_'; })(now); }; })() },
schema = { general: { "font-family" : "Georgia", "text-align" : "justify", "font-size" : "20px" }, p: {
} };
function Component( node, id ){ this.elem = (typeof node == "string") ? document.createElement(node) : node; this.elem.id = id || utils.getUid(); this.elem.style.visibility = "hidden";
this.iU_base.appendChild(this.elem); } Component.prototype = { constructor: Component, setSchema: function( schema ){ this.css( schema.general ); for(var i in this.elem.childNodes){ var child = this.elem.childNodes[i]; this.css( schema[ child.tagName || "" ], child ); } }, adaptWidth: function( width ){ var ratio = this.elem.clientHeight / this.elem.clientWidth; this.css({ width: width + "px", height: width*ratio + "px" }); return this.clientHeight; }, css: function( styles, elem ){ elem = this.elem || elem; 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; } }
elem.style[ prop ] = styles[ prop ]; } }, upgradeText: function(){ for(var i = 0, i_len = this.elem.childNodes.length; i < i_len; i ++){ var node = this.elem.childNodes[i]; if( !node.attributes ){ var child = document.createElement("span"); child.innerHTML = node.textContent; this.elem.replaceChild(child, node); } } } };
var Factory = { text: function( node ){ var comp = new Component( node, node["name"] ); comp.upgradeText(); comp.adaptWidth = Factory.textAdapt; comp.setSchema( schema );
return comp; }, textAdapt: function( width, lineHeight ){ this.css({ "width": width + "px", "line-height": lineHeight + "px", "font-size": lineHeight*0.7 + "px" }); return this.elem.clientHeight; } };
function Piece( comp, bounds ){ this.comp = comp; this.width = bounds.width; this.height = bounds.height; this.LR = bounds.LR;
this.styles = {}; } Piece.prototype = { constructor: Piece, render: function( offsetX, offsetY ){ this.comp.css({ "position": "absolute", "left": offsetX + (this.left || 0)+"px", "top": offsetY + (this.top || 0)+"px", "width": this.width, "visibility": "visible" }); }, toString: function(){ return this.comp.elem.tagName.toLowerCase() + ":" + this.comp.elem.innerHTML.substring(0,50)+"\n"; } };
function Page(){
this.oe = 0;
this.pieces = [];
}
Page.prototype = {
constructor: Page,
push: function( piece ){
this.pieces.push( piece );
},
setOE: function( oe ){
switch(oe){
case 1: case 2: case 3: case 4:
this.oe = oe;
default:
};
},
render: function( conds ){
var
offsetX = (this.oe==2 || this.oe==4) ? conds.width : 0,
pieces = this.pieces;
for(var i = 0; i < pieces.length; i ++) pieces[i].render(0,0); }, toString: function(){ var res = "page:len=" + this.pieces.length +"\n"; for(var i = 0; i < this.pieces.length; i ++) res += this.pieces[i].toString(); return res; } };
function Flow( width, spacing ){ this.width = width; this.spacing = spacing;
this.buffer = []; this.remnant = []; } Flow.prototype = { constructor: Flow, newPiece: function( comp, L, R){ var width = Math.round( (R - L)*this.width/12 ), height= comp.adaptWidth(width); return new Piece( comp, { LR:[ L, R], width:width, height:height }); }, script: function( node ){ var t = this.newPiece( Factory.text(node), node.L, node.R ); this.buffer.push( t ); }, cut: function( maxHeight ){ var page = new Page(), frontier = new Array(12);
for(var i = 0; i < 12; i ++) frontier[i] = 0;
while( this.buffer.length > 0 ){ //hr
if( frontier[0] + this.buffer[0].height > maxHeight ){ alert("max height:" + maxHeight); break; }
var piece = this.buffer.shift(); piece.top = frontier[0]; piece.left = piece.LR[0] * this.width / 12; page.push( piece );
frontier[0] += piece.height + this.spacing; } return page; } };
function Book(){
} Book.prototype = { constructor: Book };
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";
if( overflow ){ var webpage = document.getElementsByTagName("html")[0]; webpage.style.overflowX = "hidden"; webpage.style.overflowY = "hidden"; webpage.style.padding = "0px"; webpage.style.margin = "0px"; }
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) Component.prototype.css({ "position":"absolute", "top":"0", "left":"0", "z-index":"-90", "overflow":"hidden", "visibility":"visible" }, canvas);
return gl; }, initBase: function( iU_root ){ var iU_base = document.createElement("div"); iU_base.id = "iU_base"; iU_base.style.position = "absolute";
iU_root.parentNode.appendChild(iU_base); return iU_base; },
root_not_found: function(){
}, gl_not_supported: function(){
}, defaultConfig: { overflow: true, webgl: true } }
function igemUCAS(){
var iU_root = fn.initRoot( (window.configs||fn.defaultConfig).overflow ); if( !iU_root ) return fn.root_not_found();
var iU_base = fn.initBase( iU_root ); Component.prototype.iU_base = iU_base;
var gl = (window.configs||fn.defaultConfig).webgl || fn.initWebGL( iU_root ); if( !gl ) fn.gl_not_supported();
var
flow = new Flow( window.innerWidth/2, 20 ),
book = new Book();
while( iU_root.childNodes.length > 0 ){ var node = iU_root.childNodes[0];
node.L = 2; node.R = 10;
switch( ((node||{}).tagName||"").toLowerCase() ){ case "figure": while( node.childNodes.length > 0){ switch( ((node.childNodes[0]||{}).tagName||"").toLowerCase() ){ case "p": flow.script(node); break; } } iU_root.removeChild(node); break; case "p": flow.script(node); break;
default: iU_root.removeChild(node); break; } } var page = flow.cut( window.innerHeight );
console.log(page.toString()); page.render({width:0}); } igemUCAS.displayErrors = inspect.displayErrors;
return igemUCAS; });