/doc/cvi_busy_lib.js

http://jsload.googlecode.com/ · JavaScript · 288 lines · 249 code · 1 blank · 38 comment · 56 complexity · 35d2952bc37236a4ff339c1a1b9e7f7b MD5 · raw file

  1. /**
  2. * cvi_busy_lib.js 1.0 (06-Apr-2008)
  3. * (c) by Christian Effenberger
  4. * All Rights Reserved
  5. * Source: busy.netzgesta.de
  6. * Distributed under Netzgestade Software License Agreement
  7. * http://www.netzgesta.de/cvi/LICENSE.txt
  8. * License permits free of charge
  9. * use on non-commercial and
  10. * private web sites only
  11. * syntax:
  12. Add:
  13. OBJECT = getBusyOverlay(parent[,overlay[,busy]]);
  14. parent == element to add the overlay (e.g. document.getElementById(id))
  15. overlay == OBJECT e.g. {color: 'black', opacity: 0.5, ...}
  16. color == STR 'black' or '#000000' or 'rgb(0,0,0)' Default: 'white'
  17. opacity == FLOAT 0.0 - 1.0 Default: 0.0
  18. text == STR e.g. "loading" Default: ''
  19. style == STR e.g. "color: black;" or "my_text_class" Default: ''
  20. busy == OBJECT e.g. {color: '#fff', size: 48, ...}
  21. color == STR '#000000' - '#ffffff' or '#000' - '#fff' Default: '#000'
  22. size == INT 16 - 512 (pixel) Default: 32
  23. type == STR 'circle|oval|polygon|rectangle|tube' or 'c|o|p|r|t' Default: 'tube'
  24. iradius == INT 6 - 254 (pixel) Default: 8
  25. weight == INT 1 - 254 (pixel) Default: 3
  26. count == INT 5 - 36 (rays) Default: 12
  27. speed == INT 30 - 1000 (millisec) Default: 96
  28. minopac == FLOAT 0.0 - 0.5 Default: 0.25
  29. Remove:
  30. OBJECT.remove();
  31. *
  32. **/
  33. function onIEWinResize(event) {
  34. function parseWidth(val) {return (isNaN(parseInt(val,10))?0:parseInt(val,10));}
  35. if(!event) {event=window.event;} var i,cs,parent=this, div=parent.getElementsByTagName("div");
  36. if(div.length>0) {
  37. if(parent.currentStyle){cs=parent.currentStyle;}else if(document.defaultView&&document.defaultView.getComputedStyle){cs=document.defaultView.getComputedStyle(parent,"");}else{cs=parent.style;}
  38. for(i=0; i<div.length; i++) {
  39. if(div[i].className=='buzy_ele') {
  40. div[i].style.height=(parent.offsetHeight-parseWidth(cs.borderBottomWidth)-parseWidth(cs.borderTopWidth));
  41. div[i].style.width=(parent.offsetWidth-parseWidth(cs.borderLeftWidth)-parseWidth(cs.borderRightWidth));
  42. div[i].firstChild.style.height=div[i].style.height; div[i].firstChild.style.width=div[i].style.width;
  43. break;
  44. }
  45. }
  46. }
  47. }
  48. function getBusyOverlay(parent,overlay,busy) {
  49. if(typeof(parent)==='object' && document.getElementsByTagName) {
  50. function parseWidth(val) {return (isNaN(parseInt(val,10))?0:parseInt(val,10));}
  51. var isIE,isVL,isCV,isWK,isGE,i,b,o,lt,rt,lb,rb,cz,cs,size,inner,outer,string,canvas,context,ctrl,opacity,color,text,styles,waiting=true;
  52. if(parent.currentStyle){cs=parent.currentStyle;}else if(document.defaultView&&document.defaultView.getComputedStyle){cs=document.defaultView.getComputedStyle(parent,"");}else{cs=parent.style;}
  53. while(cs.display.search(/block|inline-block|table|inline-table|list-item/i)<0) {parent=parent.parentNode; if(parent.currentStyle){cs=parent.currentStyle;}else if(document.defaultView&&document.defaultView.getComputedStyle){cs=document.defaultView.getComputedStyle(parent,"");}else{cs=parent.style;} if(parent.tagName.toUpperCase()==='BODY') {parent="";}}
  54. if(typeof(parent)==='object') {
  55. if(!overlay) {overlay=new Object(); overlay['opacity']=0;} if(!busy) {busy=new Object(); busy['size']=32;}
  56. opacity=Math.max(0.0,Math.min(1.0,(typeof overlay['opacity']==='number'?overlay['opacity']:0)||0)); color=(typeof overlay['color']==='string'?overlay['color']:'white');
  57. text=(typeof overlay['text']==='string'?overlay['text']:''); styles=(typeof overlay['style']==='string'?overlay['style']:'');
  58. canvas=document.createElement("canvas"); isCV=canvas.getContext?1:0;
  59. isWK=navigator.userAgent.indexOf('WebKit')>-1?1:0; isGE=navigator.userAgent.indexOf('Gecko')>-1&&window.updateCommands?1:0;
  60. isIE=navigator.appName=='Microsoft Internet Explorer'&&window.navigator.systemLanguage&&!window.opera?1:0;
  61. isVL=document.all&&document.namespaces?1:0; outer=document.createElement('div');
  62. parent.style.position=(cs.position=='static'?'relative':cs.position);
  63. cz=parent.style.zIndex>=0?(parent.style.zIndex-0+2):2;
  64. if(isIE && !cs.hasLayout) {parent.style.zoom=1;}
  65. outer.style.position='absolute'; outer.style.overflow='hidden';
  66. outer.style.display='block'; outer.style.zIndex=cz;
  67. outer.style.left=0+'px'; outer.style.top=0+'px';
  68. outer.style.width='100%'; outer.style.height='100%';
  69. if(isIE) {outer.className='buzy_ele'; outer.style.zoom=1; outer.style.margin='0px'; outer.style.padding='0px'; outer.style.height=(parent.offsetHeight-parseWidth(cs.borderBottomWidth)-parseWidth(cs.borderTopWidth)); outer.style.width=(parent.offsetWidth-parseWidth(cs.borderLeftWidth)-parseWidth(cs.borderRightWidth));}
  70. if(typeof(cs.borderRadius)=="undefined"){
  71. if(typeof(cs.MozBorderRadius)!="undefined"){
  72. lt=parseFloat(cs.MozBorderRadiusTopleft)-Math.min(parseFloat(cs.borderLeftWidth),parseFloat(cs.borderTopWidth));
  73. rt=parseFloat(cs.MozBorderRadiusTopright)-Math.min(parseFloat(cs.borderRightWidth),parseFloat(cs.borderTopWidth));
  74. lb=parseFloat(cs.MozBorderRadiusBottomleft)-Math.min(parseFloat(cs.borderLeftWidth),parseFloat(cs.borderBottomWidth));
  75. rb=parseFloat(cs.MozBorderRadiusBottomright)-Math.min(parseFloat(cs.borderRightWidth),parseFloat(cs.borderBottomWidth));
  76. outer.style.MozBorderRadiusTopleft=lt+"px"; outer.style.MozBorderRadiusTopright=rt+"px"; outer.style.MozBorderRadiusBottomleft=lb+"px"; outer.style.MozBorderRadiusBottomright=rb+"px";
  77. }else if(typeof(cs.WebkitBorderRadius)!="undefined"){
  78. lt=parseFloat(cs.WebkitBorderTopLeftRadius)-Math.min(parseFloat(cs.borderLeftWidth),parseFloat(cs.borderTopWidth));
  79. rt=parseFloat(cs.WebkitBorderTopRightRadius)-Math.min(parseFloat(cs.borderRightWidth),parseFloat(cs.borderTopWidth));
  80. lb=parseFloat(cs.WebkitBorderBottomLeftRadius)-Math.min(parseFloat(cs.borderLeftWidth),parseFloat(cs.borderBottomWidth));
  81. rb=parseFloat(cs.WebkitBorderBottomRightRadius)-Math.min(parseFloat(cs.borderRightWidth),parseFloat(cs.borderBottomWidth));
  82. outer.style.WebkitBorderTopLeftRadius=lt+"px"; outer.style.WebkitBorderTopRightRadius=rt+"px"; outer.style.WebkitBorderBottomLeftRadius=lb+"px"; outer.style.WebkitBorderBottomRightRadius=rb+"px";
  83. }
  84. }else {
  85. lt=parseFloat(cs.borderTopLeftRadius)-Math.min(parseFloat(cs.borderLeftWidth),parseFloat(cs.borderTopWidth));
  86. rt=parseFloat(cs.borderTopRightRadius)-Math.min(parseFloat(cs.borderRightWidth),parseFloat(cs.borderTopWidth));
  87. lb=parseFloat(cs.borderBottomLeftRadius)-Math.min(parseFloat(cs.borderLeftWidth),parseFloat(cs.borderBottomWidth));
  88. rb=parseFloat(cs.borderBottomRightRadius)-Math.min(parseFloat(cs.borderRightWidth),parseFloat(cs.borderBottomWidth));
  89. outer.style.borderTopLeftRadius=lt+"px"; outer.style.borderTopRightRadius=rt+"px"; outer.style.borderBottomLeftRadius=lb+"px"; outer.style.borderBottomRightRadius=rb+"px";
  90. }
  91. parent.appendChild(outer);
  92. inner=document.createElement('div');
  93. inner.style.position='absolute'; inner.style.cursor='progress';
  94. inner.style.display='block'; inner.style.zIndex=(cz-1);
  95. inner.style.left=0+'px'; inner.style.top=0+'px';
  96. inner.style.width=100+'%'; inner.style.height=100+'%';
  97. inner.style.backgroundColor=color;
  98. if(isIE) {inner.style.zoom=1; inner.style.margin='0px'; inner.style.padding='0px'; inner.style.height=outer.style.height; inner.style.width=outer.style.width; }
  99. if(typeof(cs.borderRadius)=="undefined"){
  100. if(typeof(cs.MozBorderRadius)!="undefined"){
  101. inner.style.MozBorderRadiusTopleft=lt+"px"; inner.style.MozBorderRadiusTopright=rt+"px"; inner.style.MozBorderRadiusBottomleft=lb+"px"; inner.style.MozBorderRadiusBottomright=rb+"px";
  102. }else if(typeof(cs.WebkitBorderRadius)!="undefined"){
  103. inner.style.WebkitBorderTopLeftRadius=lt+"px"; inner.style.WebkitBorderTopRightRadius=rt+"px"; inner.style.WebkitBorderBottomLeftRadius=lb+"px"; inner.style.WebkitBorderBottomRightRadius=rb+"px";
  104. }
  105. }else {
  106. inner.style.borderTopLeftRadius=lt+"px"; inner.style.borderTopRightRadius=rt+"px"; inner.style.borderBottomLeftRadius=lb+"px"; inner.style.borderBottomRightRadius=rb+"px";
  107. }
  108. if(isIE) {inner.style.filter="alpha(opacity="+parseInt(opacity*100)+")";}else {inner.style.opacity=opacity;}
  109. outer.appendChild(inner);
  110. size=Math.max(16,Math.min(512,(typeof busy['size']==='number'?(busy['size']==0?32:busy['size']):32)));
  111. if(isVL){if(document.namespaces['v']==null) {var stl = document.createStyleSheet(); stl.addRule("v\\:*", "behavior: url(#default#VML);"); document.namespaces.add("v", "urn:schemas-microsoft-com:vml");}}
  112. if(!isCV){canvas=document.createElement("div");}
  113. canvas.style.position='absolute';
  114. canvas.style.cursor='progress'; canvas.style.zIndex=(cz-0+1);
  115. canvas.style.top='50%'; canvas.style.left='50%';
  116. canvas.style.marginTop='-'+(size/2)+'px';
  117. canvas.style.marginLeft='-'+(size/2)+'px';
  118. canvas.width=size; canvas.height=size;
  119. canvas.style.width=size+"px"; canvas.style.height=size+"px";
  120. outer.appendChild(canvas);
  121. if(typeof(text)!=""){
  122. string=document.createElement('div');
  123. string.style.position='absolute'; string.style.overflow='hidden';
  124. string.style.cursor='progress'; string.style.zIndex=(cz-0+1);
  125. string.style.top='50%'; string.style.left='0px';
  126. string.style.marginTop=2+(size/2)+'px'; string.style.textAlign='center';
  127. string.style.width=100+'%'; string.style.height='auto';
  128. if(typeof(styles)!=""){
  129. string.innerHTML='<span '+(styles.match(/:/i)?'style':'class')+'="'+styles+'">'+text+'</span>';
  130. }else {
  131. string.innerHTML='<span>'+text+'</span>';
  132. } outer.appendChild(string);
  133. }
  134. if(isGE){
  135. outer.style.MozUserSelect="none"; inner.style.MozUserSelect="none"; canvas.style.MozUserSelect="none";
  136. }else if(isWK){
  137. outer.style.KhtmlUserSelect="none"; inner.style.KhtmlUserSelect="none"; canvas.style.KhtmlUserSelect="none";
  138. }else if(isIE){
  139. outer.style.unselectable="on"; inner.style.unselectable="on"; canvas.style.unselectable="on";
  140. }
  141. if(isVL){
  142. ctrl=getBusyVL(canvas,busy['color'],busy['size'],busy['type'],busy['iradius'],busy['weight'],busy['count'],busy['speed'],busy['minopac']); ctrl.start();
  143. }else if(isCV){
  144. ctrl=getBusyCV(canvas.getContext("2d"),busy['color'],busy['size'],busy['type'],busy['iradius'],busy['weight'],busy['count'],busy['speed'],busy['minopac']); ctrl.start();
  145. }else {
  146. ctrl=getBusy(canvas,busy['color'],busy['size'],busy['type'],busy['iradius'],busy['weight'],busy['count'],busy['speed'],busy['minopac']); ctrl.start();
  147. }
  148. if(isIE) { parent.onresize = onIEWinResize; }
  149. return {remove: function (){if(waiting){waiting=false; ctrl.stop(); delete ctrl; parent.removeChild(outer);} } };
  150. }
  151. }
  152. }
  153. function getBusy(obj,cl,sz,tp,ir,w,ct,sp,mo) {
  154. function getHEX(v){
  155. var col=v||'#000000';
  156. if(!col.match(/^#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i)) {
  157. if(v.match(/^#[0-9a-f][0-9a-f][0-9a-f]$/i)) {col='#'+v.substr(1,1)+v.substr(1,1)+v.substr(2,1)+v.substr(2,1)+v.substr(3,1)+v.substr(3,1);}
  158. }return col;
  159. }
  160. var running=false,i=0,os=0,al=0,f=100,c,h,p,t,x,y,v,hp,ph,sh,ele=new Array();;
  161. c=getHEX(cl); tp=tp||"t"; t=(tp.match(/^[coprt]/i)?tp.substr(0,1).toLowerCase():'t');
  162. ct=Math.max(5,Math.min(36,ct||12)); sp=Math.max(30,Math.min(1000,sp||96));
  163. sz=Math.max(16,Math.min(512,sz||32)); ir=Math.max(1,Math.min((sz/2)-2,ir||sz/4));
  164. w=Math.max(1,Math.min((sz/2)-ir,w||sz/10)); mo=Math.max(0,Math.min(0.5,mo||0.25));
  165. al=360/ct; hp=(Math.PI/2)*-1; ph=Math.PI/180; w=(t!='c'?parseInt((w/2)*3):w); v=parseInt((sz/2)-(w/2));
  166. for(i=0;i<ct;i++) {
  167. sh=document.createElement('div');
  168. x=Math.round(v+v*Math.cos(hp+(i+1)*al*ph));
  169. y=Math.round(v+v*Math.sin(hp+(i+1)*al*ph));
  170. sh.style.position='absolute'; sh.style.margin='0px';
  171. sh.style.width=w+'px'; sh.style.height=w+'px';
  172. sh.style.lineHeight='1px'; sh.style.fontSize='0px';
  173. sh.style.top=y+'px'; sh.style.left=x+'px'; sh.style.backgroundColor=c;
  174. if(document.all&&!window.opera) {sh.style.filter="alpha(opacity="+parseInt(Math.min(1,Math.max(mo,1-((ct+1-i)/(ct+1))))*100)+")";
  175. }else {sh.style.opacity=Math.min(1,Math.max(mo,1-((ct+1-i)/(ct+1)))); }
  176. obj.appendChild(sh); ele[i]=sh;
  177. }
  178. function nextLoop(){
  179. if(!running) {return;} os=(os+1)%ct;
  180. if(document.all&&!window.opera) {
  181. for(i=0;i<ct;i++){al=((os+i)%ct); ele[al].style.filter="alpha(opacity="+parseInt(Math.min(1,Math.max(mo,1-((ct+1-i)/(ct+1))))*100)+")";}
  182. }else {
  183. for(i=0;i<ct;i++){al=((os+i)%ct); ele[al].style.opacity=Math.min(1,Math.max(mo,1-((ct+1-i)/(ct+1))));}
  184. } setTimeout(nextLoop,sp);
  185. }
  186. nextLoop(0);
  187. return {
  188. start: function (){if(!running){running=true; nextLoop(0);}},
  189. stop: function (){running=false; for(i=0;i<ct;i++) {if(document.all&&!window.opera) {ele[i].style.filter="alpha(opacity=0)";}else {ele[i].setAttribute('opacity',0);}}},
  190. pause: function (){running=false; }
  191. };
  192. }
  193. function getBusyVL(obj,cl,sz,tp,ir,w,ct,sp,mo) {
  194. function getHEX(v){
  195. var col=v||'#000000';
  196. if(!col.match(/^#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i)) {
  197. if(v.match(/^#[0-9a-f][0-9a-f][0-9a-f]$/i)) {col='#'+v.substr(1,1)+v.substr(1,1)+v.substr(2,1)+v.substr(2,1)+v.substr(3,1)+v.substr(3,1);}
  198. }return col;
  199. }
  200. var running=false,os=0,al=0,f=100,c,i,h,p,t,x,y,hs,qs,hw,qw,rp,sh,fl,ele=new Array();;
  201. c=getHEX(cl); tp=tp||"t"; t=(tp.match(/^[coprt]/i)?tp.substr(0,1).toLowerCase():'t');
  202. ct=Math.max(5,Math.min(36,ct||12)); sp=Math.max(30,Math.min(1000,sp||96));
  203. sz=Math.max(16,Math.min(512,sz||32)); ir=Math.max(1,Math.min((sz/2)-2,ir||sz/4));
  204. w=Math.max(1,Math.min((sz/2)-ir,w||sz/10)); mo=Math.max(0,Math.min(0.5,mo||0.25));
  205. h=(sz/2)-ir; x=sz/2; y=x; al=360/ct; hs=parseInt((sz/2)*f); qs=parseInt(hs/2);
  206. hw=parseInt((w/2)*f); qw=parseInt(hw/2); rp=hs-parseInt(ir*f);
  207. switch(t) {
  208. case "c": p='m '+hs+','+(rp-hw)+' ar '+(hs-hw)+','+(rp-hw-hw)+','+(hs+hw)+','+rp+','+(hs-hw)+','+(rp-hw-hw)+','+(hs-hw)+','+(rp-hw-hw)+' e'; break;
  209. case "p": p='m '+(hs-qw)+',0 l '+(hs-hw)+','+rp+','+(hs+hw)+','+rp+','+(hs+qw)+',0 x e'; break;
  210. case "o": p='m '+hs+','+(rp-qs)+' ar '+(hs-hw)+',0,'+(hs+hw)+','+rp+','+(hs-hw)+',0,'+(hs-hw)+',0 e'; break;
  211. case "t": p='m '+(hs-hw)+','+rp+' l '+(hs-hw)+','+hw+' qy '+hs+',0 qx '+(hs+hw)+','+hw+' l '+(hs+hw)+','+rp+' x e'; break;
  212. default: p='m '+(hs-hw)+',0 l '+(hs-hw)+','+rp+','+(hs+hw)+','+rp+','+(hs+hw)+',0 x e'; break;
  213. }
  214. for(i=0;i<ct;i++) {
  215. sh=document.createElement('v:shape');
  216. sh.setAttribute('filled','t');
  217. sh.setAttribute('stroked','f');
  218. sh.setAttribute('coordorigin','0,0');
  219. sh.setAttribute('coordsize',(sz*f)+','+(sz*f));
  220. sh.setAttribute('path',p);
  221. sh.style.rotation=(i*al);
  222. sh.style.position='absolute'; sh.style.margin='0px';
  223. sh.style.width=sz+'px'; sh.style.height=sz+'px';
  224. sh.style.top='-1px'; sh.style.left='-1px';
  225. obj.appendChild(sh);
  226. fl=document.createElement('v:fill');
  227. fl.setAttribute('color',c);
  228. fl.setAttribute('opacity',Math.min(1,Math.max(mo,1-((ct+1-i)/(ct+1)))));
  229. sh.appendChild(fl);
  230. ele[i]=fl;
  231. }
  232. function nextLoop(){
  233. if(!running) {return;}
  234. os=(os+1)%ct;
  235. for(i=0;i<ct;i++){ al=((os+i)%ct);
  236. ele[al].setAttribute('opacity',Math.min(1,Math.max(mo,1-((ct+1-i)/(ct+1)))));
  237. }setTimeout(nextLoop,sp);
  238. }
  239. nextLoop(0);
  240. return {
  241. start: function (){if(!running){running=true; nextLoop(0);}},
  242. stop: function (){running=false; for(i=0;i<ct;i++) {ele[i].setAttribute('opacity',0);}},
  243. pause: function (){running=false; }
  244. };
  245. }
  246. function getBusyCV(ctx,cl,sz,tp,ir,w,ct,sp,mo) {
  247. function getRGB(v){
  248. function hex2dec(h){return(Math.max(0,Math.min(parseInt(h,16),255)));}
  249. var r=0,g=0,b=0; v = v||'#000'; if(v.match(/^#[0-9a-f][0-9a-f][0-9a-f]$/i)) {
  250. r=hex2dec(v.substr(1,1)+v.substr(1,1)),g=hex2dec(v.substr(2,1)+v.substr(2,1)),b=hex2dec(v.substr(3,1)+v.substr(3,1));
  251. }else if(v.match(/^#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i)) {
  252. r=hex2dec(v.substr(1,2)),g=hex2dec(v.substr(3,2)),b=hex2dec(v.substr(5,2));
  253. } return r+','+g+','+b;
  254. }
  255. function drawOval(ctx,w,h){ctx.beginPath(); ctx.moveTo(-w/2,h/2); ctx.quadraticCurveTo(-w/2,0,0,0); ctx.quadraticCurveTo(w/2,0,w/2,h/2); ctx.quadraticCurveTo(w/2,h,0,h); ctx.quadraticCurveTo(-w/2,h,-w/2,h/2); ctx.fill();}
  256. function drawTube(ctx,w,h){ctx.beginPath(); ctx.moveTo(w/2,0); ctx.lineTo(-w/2,0); ctx.lineTo(-w/2,h-(w/2)); ctx.quadraticCurveTo(-w/2,h,0,h); ctx.quadraticCurveTo(w/2,h,w/2,h-(w/2)); ctx.fill();}
  257. function drawPoly(ctx,w,h){ctx.beginPath(); ctx.moveTo(w/2,0); ctx.lineTo(-w/2,0); ctx.lineTo(-w/4,h); ctx.lineTo(w/4,h); ctx.fill();}
  258. function drawCirc(ctx,r,z){ctx.beginPath(); ctx.arc(r,r,r,0,Math.PI*2,false); ctx.fill();}
  259. var running=false,os=0,al=0,c,i,h,t,x,y;
  260. c=getRGB(cl); tp=tp||"t"; t=(tp.match(/^[coprt]/i)?tp.substr(0,1).toLowerCase():'t');
  261. ct=Math.max(5,Math.min(36,ct||12)); sp=Math.max(30,Math.min(1000,sp||96));
  262. sz=Math.max(16,Math.min(512,sz||32)); ir=Math.max(1,Math.min((sz/2)-2,ir||sz/4));
  263. w=Math.max(1,Math.min((sz/2)-ir,w||sz/10)); mo=Math.max(0,Math.min(0.5,mo||0.25));
  264. h=(sz/2)-ir; x=sz/2; y=x;
  265. function nextLoop(){
  266. if(!running) {return;}
  267. os=(os+1)%ct; ctx.clearRect(0,0,sz,sz); ctx.save(); ctx.translate(x,y);
  268. for(i=0;i<ct;i++){ al=2*((os+i)%ct)*Math.PI/ct;
  269. ctx.save(); ctx.translate(ir*Math.sin(-al),ir*Math.cos(-al)); ctx.rotate(al);
  270. ctx.fillStyle='rgba('+c+','+Math.min(1,Math.max(mo,1-((ct+1-i)/(ct+1))))+')';
  271. switch(t) {case "c": drawCirc(ctx,w/2,h); break; case "o": drawOval(ctx,w,h); break; case "p": drawPoly(ctx,w,h); break; case "t": drawTube(ctx,w,h); break; default: ctx.fillRect(-w/2,0,w,h); break;} ctx.restore();
  272. } ctx.restore();
  273. setTimeout(nextLoop,sp);
  274. }
  275. nextLoop(0);
  276. return {
  277. start: function (){if(!running){running=true; nextLoop(0);}},
  278. stop: function (){running=false; ctx.clearRect(0,0,sz,sz); },
  279. pause: function (){running=false; }
  280. };
  281. }