Difference between revisions of "Team:UCAS-China/igemUCAS.js"

m
m
Line 1: Line 1:
 
/*!
 
/*!
  * igemUCAS JavaScript Library v0.18.1
+
  * igemUCAS JavaScript Library v0.18.16
*
+
* Includes xxx
+
*
+
 
  * Copyright UCAS iGEM team
 
  * Copyright UCAS iGEM team
 
  */
 
  */
( function( global, factory ) { global.iU = factory(global); } ) (window, function( window ) {
+
 
var iU = function(){
+
( function( global, factory ) { var iU = global.iU = factory(global); iU(); } ) (window, function( window ) {
    return {fn: 1};
+
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 iU;
+
 
 +
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; });