├── .gitignore
├── README.markdown
├── bower.json
├── docs
├── CanvasLoader.html
├── assets
│ ├── ac-js
│ ├── api-js
│ ├── api.css
│ ├── bg_hd.gif
│ ├── heartcode-logo.png
│ ├── reset-fonts-grids-min.css
│ └── yui.png
├── classmap.js
├── heartcode-canvasloader.js.html
├── index.html
├── index.json
├── module_canvasloader.html
└── raw.json
├── heartcode-canvasloader.html
└── js
├── heartcode-canvasloader-min.js
└── heartcode-canvasloader.js
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # Heartcode CanvasLoader
2 | Heartcode CanvasLoader is a JavaScript UI library, which uses the HTML canvas element to draw and animate circular preloaders.
3 | The library is currently in beta, some minor changes and improvements might be done to it in the near future.
4 |
5 | ##Tools
6 | I created a tool that can help with generating and previewing loaders with copy/paste code snippets and instructions: http://heartcode.robertpataki.com/canvasloader
7 |
8 | ##Documentation
9 | The latest documentation can be found here: http://heartcode.robertpataki.com/canvasloader/docs/CanvasLoader.html
10 |
11 | ## Contribution
12 | Please contribute :) I am quite new to JavaScript and I am pretty sure that there are million ways of making the library better, cleaner and smaller. Any constructive contribution is welcome and appriciated.
13 |
14 | You can also add your website / web app link to the Wiki, so the community can see how others use CanvasLoader.
15 |
16 | ## License
17 | **(The MIT License)**
18 |
19 | Copyright (c) 2011 Róbert Pataki heartcode@robertpataki.com;
20 |
21 | Permission is hereby granted, free of charge, to any person obtaining
22 | a copy of this software and associated documentation files (the
23 | 'Software'), to deal in the Software without restriction, including
24 | without limitation the rights to use, copy, modify, merge, publish,
25 | distribute, sublicense, and/or sell copies of the Software, and to
26 | permit persons to whom the Software is furnished to do so, subject to
27 | the following conditions:
28 |
29 | The above copyright notice and this permission notice shall be
30 | included in all copies or substantial portions of the Software.
31 |
32 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
33 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
35 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
36 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
37 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
38 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 |
40 | ## Credits
41 | Heartcode CanvasLoader was created by Róbert Pataki.
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "CanvasLoader",
3 | "version": "0.9.1",
4 | "homepage": "https://github.com/heartcode/CanvasLoader",
5 | "repository": {
6 | "type": "git",
7 | "url": "git://github.com/heartcode/CanvasLoader.git"
8 | },
9 | "authors": [
10 | "Róbert Pataki"
11 | ],
12 | "description": "Heartcode CanvasLoader is a lightweight JavaScript UI library, which uses the HTML canvas element to draw and animate circular preloaders. The library is currently in beta, some minor changes and improvements might be done to it in the near future.",
13 | "main": "js/heartcode-canvasloader.js",
14 | "moduleType": [
15 | "globals"
16 | ],
17 | "keywords": [
18 | "loader",
19 | "spinner",
20 | "canvas",
21 | "animation"
22 | ],
23 | "license": "MIT"
24 | }
25 |
--------------------------------------------------------------------------------
/docs/CanvasLoader.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 | CanvasLoader is a JavaScript UI library that draws and animates circular preloaders using the Canvas HTML object.
63 | A CanvasLoader instance creates two canvas elements which are placed into a placeholder div (the id of the div has to be passed in the constructor). The second canvas is invisible and used for caching purposes only.
64 | If no id is passed in the constructor, the canvas objects are paced in the document directly.
65 |
safeVML (Boolean): If set to true, the amount of CanvasLoader shapes are limited in VML mode. It prevents CPU overkilling when rendering loaders with high density. The default value is true.
832 | Possible values of optional parameters:
833 |
834 |
id (String): The id of the CanvasLoader instance
835 |
safeVML (Boolean): If set to true, the amount of CanvasLoader shapes are limited in VML mode. It prevents CPU overkilling when rendering loaders with high density. The default value is true.
1212 | Sets the rendering frequency.
1213 | This value tells the loader how many times to refresh and modify the canvas in 1 second.
1214 | Using the right combination of the setSpeed and the setFPS methods allows the users to optimize the CPU usage of the loader whilst keeping the animation on a visually pleasing level.
1215 |
1216 |
1217 |
1218 |
1219 |
1220 |
Parameters:
1221 |
1222 | fps
1223 | <Number>
1224 |
1225 | The default value is 24
1226 |
1258 | Sets the amount of the modified shapes in percent.
1259 | With this value the user can set what range of the shapes should be scaled and/or faded. The shapes that are out of this range will be scaled and/or faded with a minimum amount only.
1260 | This minimum amount is 0.1 which means every shape which is out of the range is scaled and/or faded to 10% of the original values.
1261 | The visually acceptable range value should be between 0.4 and 1.5.
1262 |
1263 |
1264 |
1265 |
1266 |
1267 |
Parameters:
1268 |
1269 | range
1270 | <Number>
1271 |
1272 | The default value is 1.3
1273 |
1357 | Sets the speed of the loader animation.
1358 | This value tells the loader how many shapes to skip by each tick.
1359 | Using the right combination of the setFPS and the setSpeed methods allows the users to optimize the CPU usage of the loader whilst keeping the animation on a visually pleasing level.
1360 |
1361 |
1362 |
1363 |
1364 |
1365 |
Parameters:
1366 |
1367 | speed
1368 | <Number>
1369 |
1370 | The default value is 2
1371 |
53 | CanvasLoader uses the HTML5 canvas element in modern browsers and VML in IE6/7/8 to create and animate the most popular preloader shapes (oval, spiral, rectangle, square and rounded rectangle).
54 | It is important to note that CanvasLoader doesn't show up and starts rendering automatically on instantiation. To start rendering and display the loader use the show() method.
55 |
safeVML (Boolean): If set to true, the amount of CanvasLoader shapes are limited in VML mode. It prevents CPU overkilling when rendering loaders with high density. The default value is true.
"}], "description": "CanvasLoader is a JavaScript UI library that draws and animates circular preloaders using the Canvas HTML object.
\r\nA CanvasLoader instance creates two canvas elements which are placed into a placeholder div (the id of the div has to be passed in the constructor). The second canvas is invisible and used for caching purposes only.
\r\nIf no id is passed in the constructor, the canvas objects are paced in the document directly."}], "namespace": "", "module": "CanvasLoader", "guessedname": "CanvasLoader", "methods": {"getRange": {"public": "", "return": {"type": "Number", "description": ""}, "description": "Returns the modified shape range in percent", "guessedname": "getRange", "guessedtype": "function"}, "show": {"description": "Shows the rendering of the loader animation", "public": "", "guessedname": "show", "guessedtype": "function"}, "setDensity": {"public": "", "params": [{"type": "Number", "name": "density", "description": " The default value is 40"}], "description": "Sets the number of shapes drawn on the loader canvas", "guessedname": "setDensity", "guessedtype": "function"}, "getDiameter": {"public": "", "return": {"type": "Number", "description": ""}, "description": "Returns the diameter of the loader.", "guessedname": "getDiameter", "guessedtype": "function"}, "kill": {"description": "Removes the CanvasLoader instance and all its references", "public": "", "guessedname": "kill", "guessedtype": "function"}, "tick": {"protected": "", "description": "Renders the loader animation", "guessedname": "tick", "guessedtype": "function"}, "hide": {"description": "Stops the rendering of the loader animation and hides the loader", "public": "", "guessedname": "hide", "guessedtype": "function"}, "addEl": {"return": {"type": "Object", "description": "The DOM element"}, "description": "Creates a new element with the tag and applies the passed properties on it", "protected": "", "params": [{"type": "String", "name": "tag", "description": " The tag to be created"}, {"type": "String", "name": "par", "description": " The DOM element the new element will be appended to"}, {"type": "Object", "name": "opt", "description": " Additional properties passed to the new DOM element"}], "guessedname": "addEl", "guessedtype": "function"}, "init": {"protected": "", "params": [{"type": "String", "name": "id", "description": " The id of the placeholder div, where the loader will be nested into"}, {"type": "Object", "name": "opt", "description": " Optional parameters
\r\nPossible values of optional parameters: \r\n
\r\n
id (String): The id of the CanvasLoader instance
\r\n
safeVML (Boolean): If set to true, the amount of CanvasLoader shapes are limited in VML mode. It prevents CPU overkilling when rendering loaders with high density. The default value is true.
"}], "description": "Initialization method", "guessedname": "init", "guessedtype": "function"}, "setRange": {"public": "", "params": [{"type": "Number", "name": "range", "description": " The default value is 1.3"}], "description": "Sets the amount of the modified shapes in percent. \r\nWith this value the user can set what range of the shapes should be scaled and/or faded. The shapes that are out of this range will be scaled and/or faded with a minimum amount only. \r\nThis minimum amount is 0.1 which means every shape which is out of the range is scaled and/or faded to 10% of the original values. \r\nThe visually acceptable range value should be between 0.4 and 1.5.", "guessedname": "setRange", "guessedtype": "function"}, "getFPS": {"public": "", "return": {"type": "Number", "description": ""}, "description": "Returns the fps of the loader", "guessedname": "getFPS", "guessedtype": "function"}, "draw": {"protected": "", "description": "Draw the shapes on the canvas", "guessedname": "draw", "guessedtype": "function"}, "setAttr": {"return": {"type": "Object", "description": "The DOM element"}, "description": "Sets the attributes on the element", "protected": "", "params": [{"type": "Object", "name": "el", "description": " The DOM element to add the attributes to"}, {"type": "Object", "name": "opt", "description": " The attributes"}], "guessedname": "setAttr", "guessedtype": "function"}, "getColor": {"public": "", "return": {"type": "String", "description": ""}, "description": "Returns the loader color in a hexadecimal form", "guessedname": "getColor", "guessedtype": "function"}, "setFPS": {"public": "", "params": [{"type": "Number", "name": "fps", "description": " The default value is 24"}], "description": "Sets the rendering frequency. \r\nThis value tells the loader how many times to refresh and modify the canvas in 1 second. \r\nUsing the right combination of the setSpeed and the setFPS methods allows the users to optimize the CPU usage of the loader whilst keeping the animation on a visually pleasing level.", "guessedname": "setFPS", "guessedtype": "function"}, "getDensity": {"public": "", "return": {"type": "Number", "description": ""}, "description": "Returns the number of shapes drawn on the loader canvas", "guessedname": "getDensity", "guessedtype": "function"}, "setCSS": {"return": {"type": "Object", "description": "The DOM element"}, "description": "Sets the css properties on the element", "protected": "", "params": [{"type": "Object", "name": "el", "description": " The DOM element to be styled"}, {"type": "Object", "name": "opt", "description": " The style properties"}], "guessedname": "setCSS", "guessedtype": "function"}, "getSpeed": {"public": "", "return": {"type": "Number", "description": ""}, "description": "Returns the speed of the loader animation", "guessedname": "getSpeed", "guessedtype": "function"}, "reset": {"protected": "", "description": "Resets the timer", "guessedname": "reset", "guessedtype": "function"}, "setDiameter": {"public": "", "params": [{"type": "Number", "name": "diameter", "description": " The default value is 40"}], "description": "Sets the diameter of the loader", "guessedname": "setDiameter", "guessedtype": "function"}, "setColor": {"public": "", "params": [{"type": "String", "name": "color", "description": " The default value is '#000000'"}], "description": "Sets hexadecimal color of the loader", "guessedname": "setColor", "guessedtype": "function"}, "transCon": {"protected": "", "params": [{"type": "Object", "name": "x", "description": " The canvas context to be transformed"}, {"type": "Number", "name": "x", "description": " x translation"}, {"type": "Number", "name": "y", "description": " y translation"}, {"type": "Number", "name": "r", "description": " Rotation radians"}], "description": "Transforms the cache canvas before drawing", "guessedname": "transCon", "guessedtype": "function"}, "getRGB": {"protected": "", "params": [{"type": "String", "name": "color", "description": " The HEX color value to be converted to RGB"}], "description": "Return the RGB values of the passed color", "guessedname": "getRGB", "guessedtype": "function"}, "setSpeed": {"public": "", "params": [{"type": "Number", "name": "speed", "description": " The default value is 2"}], "description": "Sets the speed of the loader animation. \r\nThis value tells the loader how many shapes to skip by each tick. \r\nUsing the right combination of the setFPS and the setSpeed methods allows the users to optimize the CPU usage of the loader whilst keeping the animation on a visually pleasing level.", "guessedname": "setSpeed", "guessedtype": "function"}, "getShape": {"public": "", "return": {"type": "String", "description": ""}, "description": "Returns the type of the loader shapes", "guessedname": "getShape", "guessedtype": "function"}, "clean": {"protected": "", "description": "Cleans the canvas", "guessedname": "clean", "guessedtype": "function"}, "redraw": {"protected": "", "description": "Redraws the canvas", "guessedname": "redraw", "guessedtype": "function"}, "setShape": {"public": "", "params": [{"type": "String", "name": "shape", "description": " The default value is 'oval'"}], "description": "Sets the type of the loader shapes. \r\n The acceptable values are:\r\n
\r\n
'oval'
\r\n
'spiral'
\r\n
'square'
\r\n
'rect'
\r\n
'roundRect'
\r\n
", "guessedname": "setShape", "guessedtype": "function"}}, "file": "heartcode-canvasloader.js", "guessedtype": "function", "shortname": "CanvasLoader", "properties": {"diameter": {"description": "The diameter of the loader", "default": "40", "protected": "", "guessedname": "diameter", "guessedtype": "property", "type": "Number"}, "cont": {"protected": "", "type": "Object", "description": "The div we place the canvas object into", "guessedname": "cont", "guessedtype": "property"}, "density": {"description": "The number of shapes drawn on the loader canvas", "default": "40", "protected": "", "guessedname": "density", "guessedtype": "property", "type": "Number"}, "color": {"description": "The color of the loader shapes in HEX", "default": "\"#000000\"", "protected": "", "guessedname": "color", "guessedtype": "property", "type": "String"}, "activeId": {"protected": "", "type": "Number", "description": "The active shape id for rendering", "guessedname": "activeId", "guessedtype": "property"}, "range": {"protected": "", "type": "Number", "description": "The amount of the modified shapes in percent.", "guessedname": "range", "guessedtype": "property"}, "timer": {"protected": "", "type": "Boolean", "description": "Adds a timer for the rendering", "guessedname": "timer", "guessedtype": "property"}, "cRGB": {"protected": "", "type": "Object", "description": "The color of the loader shapes in RGB", "guessedname": "cRGB", "guessedtype": "property"}, "shape": {"description": "The type of the loader shapes", "default": "\"oval\"", "protected": "", "guessedname": "shape", "guessedtype": "property", "type": "String"}, "can": {"protected": "", "type": "Object", "description": "The div we draw the shapes into", "guessedname": "can", "guessedtype": "property"}, "fps": {"protected": "", "type": "Number", "description": "The FPS value of the loader animation rendering", "guessedname": "fps", "guessedtype": "property"}, "cCan": {"protected": "", "type": "Object", "description": "The canvas we use for caching", "guessedname": "cCan", "guessedtype": "property"}, "ready": {"protected": "", "type": "Boolean", "description": "Tells if the canvas and its context is ready", "guessedname": "ready", "guessedtype": "property"}, "cCon": {"protected": "", "type": "Object", "description": "The context of the cache canvas", "guessedname": "cCon", "guessedtype": "property"}, "speed": {"protected": "", "type": "Number", "description": "The speed of the loader animation", "guessedname": "speed", "guessedtype": "property"}, "con": {"protected": "", "type": "Object", "description": "The canvas context", "guessedname": "con", "guessedtype": "property"}}, "description": "CanvasLoader is a JavaScript UI library that draws and animates circular preloaders using the Canvas HTML object.
\r\nA CanvasLoader instance creates two canvas elements which are placed into a placeholder div (the id of the div has to be passed in the constructor). The second canvas is invisible and used for caching purposes only.
\r\nIf no id is passed in the constructor, the canvas objects are paced in the document directly."}}, "version": "0.9.0", "modules": {"CanvasLoader": {"description": "CanvasLoader uses the HTML5 canvas element in modern browsers and VML in IE6/7/8 to create and animate the most popular preloader shapes (oval, spiral, rectangle, square and rounded rectangle).
\r\nIt is important to note that CanvasLoader doesn't show up and starts rendering automatically on instantiation. To start rendering and display the loader use the show() method.", "submodules": [], "classlist": ["CanvasLoader"], "filelist": ["heartcode-canvasloader.js"], "subdata": {}, "name": "CanvasLoader"}}, "filemap": {"heartcode-canvasloader.js": {"classlist": ["CanvasLoader"], "name": "heartcode-canvasloader.js", "module": "CanvasLoader"}}}
--------------------------------------------------------------------------------
/heartcode-canvasloader.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
34 | Heartcode CanvasLoader test
35 |
36 |
37 |
38 |
39 |
40 |
55 |
56 |
57 |
58 |
75 |
91 |
106 |
121 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/js/heartcode-canvasloader-min.js:
--------------------------------------------------------------------------------
1 | (function(w){var k=function(b,c){typeof c=="undefined"&&(c={});this.init(b,c)},a=k.prototype,o,p=["canvas","vml"],f=["oval","spiral","square","rect","roundRect"],x=/^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,v=navigator.appVersion.indexOf("MSIE")!==-1&&parseFloat(navigator.appVersion.split("MSIE")[1])===8?true:false,y=!!document.createElement("canvas").getContext,q=true,n=function(b,c,a){var b=document.createElement(b),d;for(d in a)b[d]=a[d];typeof c!=="undefined"&&c.appendChild(b);return b},m=function(b,
2 | c){for(var a in c)b.style[a]=c[a];return b},t=function(b,c){for(var a in c)b.setAttribute(a,c[a]);return b},u=function(b,c,a,d){b.save();b.translate(c,a);b.rotate(d);b.translate(-c,-a);b.beginPath()};a.init=function(b,c){if(typeof c.safeVML==="boolean")q=c.safeVML;try{this.mum=document.getElementById(b)!==void 0?document.getElementById(b):document.body}catch(a){this.mum=document.body}c.id=typeof c.id!=="undefined"?c.id:"canvasLoader";this.cont=n("div",this.mum,{id:c.id});if(y)o=p[0],this.can=n("canvas",
3 | this.cont),this.con=this.can.getContext("2d"),this.cCan=m(n("canvas",this.cont),{display:"none"}),this.cCon=this.cCan.getContext("2d");else{o=p[1];if(typeof k.vmlSheet==="undefined"){document.getElementsByTagName("head")[0].appendChild(n("style"));k.vmlSheet=document.styleSheets[document.styleSheets.length-1];var d=["group","oval","roundrect","fill"],e;for(e in d)k.vmlSheet.addRule(d[e],"behavior:url(#default#VML); position:absolute;")}this.vml=n("group",this.cont)}this.setColor(this.color);this.draw();
4 | m(this.cont,{display:"none"})};a.cont={};a.can={};a.con={};a.cCan={};a.cCon={};a.timer={};a.activeId=0;a.diameter=40;a.setDiameter=function(b){this.diameter=Math.round(Math.abs(b));this.redraw()};a.getDiameter=function(){return this.diameter};a.cRGB={};a.color="#000000";a.setColor=function(b){this.color=x.test(b)?b:"#000000";this.cRGB=this.getRGB(this.color);this.redraw()};a.getColor=function(){return this.color};a.shape=f[0];a.setShape=function(b){for(var c in f)if(b===f[c]){this.shape=b;this.redraw();
5 | break}};a.getShape=function(){return this.shape};a.density=40;a.setDensity=function(b){this.density=q&&o===p[1]?Math.round(Math.abs(b))<=40?Math.round(Math.abs(b)):40:Math.round(Math.abs(b));if(this.density>360)this.density=360;this.activeId=0;this.redraw()};a.getDensity=function(){return this.density};a.range=1.3;a.setRange=function(b){this.range=Math.abs(b);this.redraw()};a.getRange=function(){return this.range};a.speed=2;a.setSpeed=function(b){this.speed=Math.round(Math.abs(b))};a.getSpeed=function(){return this.speed};
6 | a.fps=24;a.setFPS=function(b){this.fps=Math.round(Math.abs(b));this.reset()};a.getFPS=function(){return this.fps};a.getRGB=function(b){b=b.charAt(0)==="#"?b.substring(1,7):b;return{r:parseInt(b.substring(0,2),16),g:parseInt(b.substring(2,4),16),b:parseInt(b.substring(4,6),16)}};a.draw=function(){var b=0,c,a,d,e,h,k,j,r=this.density,s=Math.round(r*this.range),l,i,q=0;i=this.cCon;var g=this.diameter;if(o===p[0]){i.clearRect(0,0,1E3,1E3);t(this.can,{width:g,height:g});for(t(this.cCan,{width:g,height:g});b<
7 | r;){l=b<=s?1-1/s*b:l=0;k=270-360/r*b;j=k/180*Math.PI;i.fillStyle="rgba("+this.cRGB.r+","+this.cRGB.g+","+this.cRGB.b+","+l.toString()+")";switch(this.shape){case f[0]:case f[1]:c=g*0.07;e=g*0.47+Math.cos(j)*(g*0.47-c)-g*0.47;h=g*0.47+Math.sin(j)*(g*0.47-c)-g*0.47;i.beginPath();this.shape===f[1]?i.arc(g*0.5+e,g*0.5+h,c*l,0,Math.PI*2,false):i.arc(g*0.5+e,g*0.5+h,c,0,Math.PI*2,false);break;case f[2]:c=g*0.12;e=Math.cos(j)*(g*0.47-c)+g*0.5;h=Math.sin(j)*(g*0.47-c)+g*0.5;u(i,e,h,j);i.fillRect(e,h-c*0.5,
8 | c,c);break;case f[3]:case f[4]:a=g*0.3,d=a*0.27,e=Math.cos(j)*(d+(g-d)*0.13)+g*0.5,h=Math.sin(j)*(d+(g-d)*0.13)+g*0.5,u(i,e,h,j),this.shape===f[3]?i.fillRect(e,h-d*0.5,a,d):(c=d*0.55,i.moveTo(e+c,h-d*0.5),i.lineTo(e+a-c,h-d*0.5),i.quadraticCurveTo(e+a,h-d*0.5,e+a,h-d*0.5+c),i.lineTo(e+a,h-d*0.5+d-c),i.quadraticCurveTo(e+a,h-d*0.5+d,e+a-c,h-d*0.5+d),i.lineTo(e+c,h-d*0.5+d),i.quadraticCurveTo(e,h-d*0.5+d,e,h-d*0.5+d-c),i.lineTo(e,h-d*0.5+c),i.quadraticCurveTo(e,h-d*0.5,e+c,h-d*0.5))}i.closePath();i.fill();
9 | i.restore();++b}}else{m(this.cont,{width:g,height:g});m(this.vml,{width:g,height:g});switch(this.shape){case f[0]:case f[1]:j="oval";c=140;break;case f[2]:j="roundrect";c=120;break;case f[3]:case f[4]:j="roundrect",c=300}a=d=c;e=500-d;for(h=-d*0.5;b=1;)b.removeChild(b.firstChild)}};a.redraw=function(){this.clean();this.draw()};a.reset=function(){typeof this.timer===
11 | "number"&&(this.hide(),this.show())};a.tick=function(b){var a=this.con,f=this.diameter;b||(this.activeId+=360/this.density*this.speed);o===p[0]?(a.clearRect(0,0,f,f),u(a,f*0.5,f*0.5,this.activeId/180*Math.PI),a.drawImage(this.cCan,0,0,f,f),a.restore()):(this.activeId>=360&&(this.activeId-=360),m(this.vml,{rotation:this.activeId}))};a.show=function(){if(typeof this.timer!=="number"){var a=this;this.timer=self.setInterval(function(){a.tick()},Math.round(1E3/this.fps));m(this.cont,{display:"block"})}};
12 | a.hide=function(){typeof this.timer==="number"&&(clearInterval(this.timer),delete this.timer,m(this.cont,{display:"none"}))};a.kill=function(){var a=this.cont;typeof this.timer==="number"&&this.hide();o===p[0]?(a.removeChild(this.can),a.removeChild(this.cCan)):a.removeChild(this.vml);for(var c in this)delete this[c]};w.CanvasLoader=k})(window);
--------------------------------------------------------------------------------
/js/heartcode-canvasloader.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011 Róbert Pataki
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | *
22 | * ----------------------------------------------------------------------------------------
23 | *
24 | * Check out my GitHub: http://github.com/heartcode/
25 | * Send me an email: heartcode@robertpataki.com
26 | * Follow me on Twitter: http://twitter.com/#iHeartcode
27 | * Blog: http://heartcode.robertpataki.com
28 | */
29 |
30 | /**
31 | * CanvasLoader uses the HTML5 canvas element in modern browsers and VML in IE6/7/8 to create and animate the most popular preloader shapes (oval, spiral, rectangle, square and rounded rectangle).
32 | * It is important to note that CanvasLoader doesn't show up and starts rendering automatically on instantiation. To start rendering and display the loader use the show() method.
33 | * @module CanvasLoader
34 | **/
35 | (function (window) {
36 | "use strict";
37 | /**
38 | * CanvasLoader is a JavaScript UI library that draws and animates circular preloaders using the Canvas HTML object.
39 | * A CanvasLoader instance creates two canvas elements which are placed into a placeholder div (the id of the div has to be passed in the constructor). The second canvas is invisible and used for caching purposes only.
40 | * If no id is passed in the constructor, the canvas objects are paced in the document directly.
41 | * @class CanvasLoader
42 | * @constructor
43 | * @param id {String} The id of the placeholder div
44 | * @param opt {Object} Optional parameters
45 | * Possible values of optional parameters:
46 | *
47 | *
id (String): The id of the CanvasLoader instance
48 | *
safeVML (Boolean): If set to true, the amount of CanvasLoader shapes are limited in VML mode. It prevents CPU overkilling when rendering loaders with high density. The default value is true.
49 | **/
50 | var CanvasLoader = function (id, opt) {
51 | if (typeof(opt) == "undefined") { opt = {}; }
52 | this.init(id, opt);
53 | }, p = CanvasLoader.prototype, engine, engines = ["canvas", "vml"], shapes = ["oval", "spiral", "square", "rect", "roundRect"], cRX = /^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/, ie8 = navigator.appVersion.indexOf("MSIE") !== -1 && parseFloat(navigator.appVersion.split("MSIE")[1]) === 8 ? true : false, canSup = !!document.createElement('canvas').getContext, safeDensity = 40, safeVML = true,
54 | /**
55 | * Creates a new element with the tag and applies the passed properties on it
56 | * @method addEl
57 | * @protected
58 | * @param tag {String} The tag to be created
59 | * @param par {String} The DOM element the new element will be appended to
60 | * @param opt {Object} Additional properties passed to the new DOM element
61 | * @return {Object} The DOM element
62 | */
63 | addEl = function (tag, par, opt) {
64 | var el = document.createElement(tag), n;
65 | for (n in opt) { el[n] = opt[n]; }
66 | if(typeof(par) !== "undefined") {
67 | par.appendChild(el);
68 | }
69 | return el;
70 | },
71 | /**
72 | * Sets the css properties on the element
73 | * @method setCSS
74 | * @protected
75 | * @param el {Object} The DOM element to be styled
76 | * @param opt {Object} The style properties
77 | * @return {Object} The DOM element
78 | */
79 | setCSS = function (el, opt) {
80 | for (var n in opt) { el.style[n] = opt[n]; }
81 | return el;
82 | },
83 | /**
84 | * Sets the attributes on the element
85 | * @method setAttr
86 | * @protected
87 | * @param el {Object} The DOM element to add the attributes to
88 | * @param opt {Object} The attributes
89 | * @return {Object} The DOM element
90 | */
91 | setAttr = function (el, opt) {
92 | for (var n in opt) { el.setAttribute(n, opt[n]); }
93 | return el;
94 | },
95 | /**
96 | * Transforms the cache canvas before drawing
97 | * @method transCon
98 | * @protected
99 | * @param x {Object} The canvas context to be transformed
100 | * @param x {Number} x translation
101 | * @param y {Number} y translation
102 | * @param r {Number} Rotation radians
103 | */
104 | transCon = function(c, x, y, r) {
105 | c.save();
106 | c.translate(x, y);
107 | c.rotate(r);
108 | c.translate(-x, -y);
109 | c.beginPath();
110 | };
111 | /**
112 | * Initialization method
113 | * @method init
114 | * @protected
115 | * @param id {String} The id of the placeholder div, where the loader will be nested into
116 | * @param opt {Object} Optional parameters
117 | * Possible values of optional parameters:
118 | *
119 | *
id (String): The id of the CanvasLoader instance
120 | *
safeVML (Boolean): If set to true, the amount of CanvasLoader shapes are limited in VML mode. It prevents CPU overkilling when rendering loaders with high density. The default value is true.
121 | **/
122 | p.init = function (pId, opt) {
123 |
124 | if (typeof(opt.safeVML) === "boolean") { safeVML = opt.safeVML; }
125 |
126 | /*
127 | * Find the containing div by id
128 | * If the container element cannot be found we use the document body itself
129 | */
130 | try {
131 | // Look for the parent element
132 | if (document.getElementById(pId) !== undefined) {
133 | this.mum = document.getElementById(pId);
134 | } else {
135 | this.mum = document.body;
136 | }
137 | } catch (error) {
138 | this.mum = document.body;
139 | }
140 | // Creates the parent div of the loader instance
141 | opt.id = typeof (opt.id) !== "undefined" ? opt.id : "canvasLoader";
142 | this.cont = addEl("div", this.mum, {id: opt.id});
143 | if (canSup) {
144 | // For browsers with Canvas support...
145 | engine = engines[0];
146 | // Create the canvas element
147 | this.can = addEl("canvas", this.cont);
148 | this.con = this.can.getContext("2d");
149 | // Create the cache canvas element
150 | this.cCan = setCSS(addEl("canvas", this.cont), { display: "none" });
151 | this.cCon = this.cCan.getContext("2d");
152 | } else {
153 | // For browsers without Canvas support...
154 | engine = engines[1];
155 | // Adds the VML stylesheet
156 | if (typeof (CanvasLoader.vmlSheet) === "undefined") {
157 | document.getElementsByTagName("head")[0].appendChild(addEl("style"));
158 | CanvasLoader.vmlSheet = document.styleSheets[document.styleSheets.length - 1];
159 | var a = ["group", "oval", "roundrect", "fill"], n;
160 | for ( var n = 0; n < a.length; ++n ) { CanvasLoader.vmlSheet.addRule(a[n], "behavior:url(#default#VML); position:absolute;"); }
161 | }
162 | this.vml = addEl("group", this.cont);
163 | }
164 | // Set the RGB color object
165 | this.setColor(this.color);
166 | // Draws the shapes on the canvas
167 | this.draw();
168 | //Hides the preloader
169 | setCSS(this.cont, {display: "none"});
170 | };
171 | /////////////////////////////////////////////////////////////////////////////////////////////
172 | // Property declarations
173 | /**
174 | * The div we place the canvas object into
175 | * @property cont
176 | * @protected
177 | * @type Object
178 | **/
179 | p.cont = {};
180 | /**
181 | * The div we draw the shapes into
182 | * @property can
183 | * @protected
184 | * @type Object
185 | **/
186 | p.can = {};
187 | /**
188 | * The canvas context
189 | * @property con
190 | * @protected
191 | * @type Object
192 | **/
193 | p.con = {};
194 | /**
195 | * The canvas we use for caching
196 | * @property cCan
197 | * @protected
198 | * @type Object
199 | **/
200 | p.cCan = {};
201 | /**
202 | * The context of the cache canvas
203 | * @property cCon
204 | * @protected
205 | * @type Object
206 | **/
207 | p.cCon = {};
208 | /**
209 | * Adds a timer for the rendering
210 | * @property timer
211 | * @protected
212 | * @type Boolean
213 | **/
214 | p.timer = {};
215 | /**
216 | * The active shape id for rendering
217 | * @property activeId
218 | * @protected
219 | * @type Number
220 | **/
221 | p.activeId = 0;
222 | /**
223 | * The diameter of the loader
224 | * @property diameter
225 | * @protected
226 | * @type Number
227 | * @default 40
228 | **/
229 | p.diameter = 40;
230 | /**
231 | * Sets the diameter of the loader
232 | * @method setDiameter
233 | * @public
234 | * @param diameter {Number} The default value is 40
235 | **/
236 | p.setDiameter = function (diameter) { this.diameter = Math.round(Math.abs(diameter)); this.redraw(); };
237 | /**
238 | * Returns the diameter of the loader.
239 | * @method getDiameter
240 | * @public
241 | * @return {Number}
242 | **/
243 | p.getDiameter = function () { return this.diameter; };
244 | /**
245 | * The color of the loader shapes in RGB
246 | * @property cRGB
247 | * @protected
248 | * @type Object
249 | **/
250 | p.cRGB = {};
251 | /**
252 | * The color of the loader shapes in HEX
253 | * @property color
254 | * @protected
255 | * @type String
256 | * @default "#000000"
257 | **/
258 | p.color = "#000000";
259 | /**
260 | * Sets hexadecimal color of the loader
261 | * @method setColor
262 | * @public
263 | * @param color {String} The default value is '#000000'
264 | **/
265 | p.setColor = function (color) { this.color = cRX.test(color) ? color : "#000000"; this.cRGB = this.getRGB(this.color); this.redraw(); };
266 | /**
267 | * Returns the loader color in a hexadecimal form
268 | * @method getColor
269 | * @public
270 | * @return {String}
271 | **/
272 | p.getColor = function () { return this.color; };
273 | /**
274 | * The type of the loader shapes
275 | * @property shape
276 | * @protected
277 | * @type String
278 | * @default "oval"
279 | **/
280 | p.shape = shapes[0];
281 | /**
282 | * Sets the type of the loader shapes.
283 | * The acceptable values are:
284 | *
285 | *
'oval'
286 | *
'spiral'
287 | *
'square'
288 | *
'rect'
289 | *
'roundRect'
290 | *
291 | * @method setShape
292 | * @public
293 | * @param shape {String} The default value is 'oval'
294 | **/
295 | p.setShape = function (shape) {
296 | var n;
297 | for (n in shapes) {
298 | if (shape === shapes[n]) { this.shape = shape; this.redraw(); break; }
299 | }
300 | };
301 | /**
302 | * Returns the type of the loader shapes
303 | * @method getShape
304 | * @public
305 | * @return {String}
306 | **/
307 | p.getShape = function () { return this.shape; };
308 | /**
309 | * The number of shapes drawn on the loader canvas
310 | * @property density
311 | * @protected
312 | * @type Number
313 | * @default 40
314 | **/
315 | p.density = 40;
316 | /**
317 | * Sets the number of shapes drawn on the loader canvas
318 | * @method setDensity
319 | * @public
320 | * @param density {Number} The default value is 40
321 | **/
322 | p.setDensity = function (density) {
323 | if (safeVML && engine === engines[1]) {
324 | this.density = Math.round(Math.abs(density)) <= safeDensity ? Math.round(Math.abs(density)) : safeDensity;
325 | } else {
326 | this.density = Math.round(Math.abs(density));
327 | }
328 | if (this.density > 360) { this.density = 360; }
329 | this.activeId = 0;
330 | this.redraw();
331 | };
332 | /**
333 | * Returns the number of shapes drawn on the loader canvas
334 | * @method getDensity
335 | * @public
336 | * @return {Number}
337 | **/
338 | p.getDensity = function () { return this.density; };
339 | /**
340 | * The amount of the modified shapes in percent.
341 | * @property range
342 | * @protected
343 | * @type Number
344 | **/
345 | p.range = 1.3;
346 | /**
347 | * Sets the amount of the modified shapes in percent.
348 | * With this value the user can set what range of the shapes should be scaled and/or faded. The shapes that are out of this range will be scaled and/or faded with a minimum amount only.
349 | * This minimum amount is 0.1 which means every shape which is out of the range is scaled and/or faded to 10% of the original values.
350 | * The visually acceptable range value should be between 0.4 and 1.5.
351 | * @method setRange
352 | * @public
353 | * @param range {Number} The default value is 1.3
354 | **/
355 | p.setRange = function (range) { this.range = Math.abs(range); this.redraw(); };
356 | /**
357 | * Returns the modified shape range in percent
358 | * @method getRange
359 | * @public
360 | * @return {Number}
361 | **/
362 | p.getRange = function () { return this.range; };
363 | /**
364 | * The speed of the loader animation
365 | * @property speed
366 | * @protected
367 | * @type Number
368 | **/
369 | p.speed = 2;
370 | /**
371 | * Sets the speed of the loader animation.
372 | * This value tells the loader how many shapes to skip by each tick.
373 | * Using the right combination of the setFPS and the setSpeed methods allows the users to optimize the CPU usage of the loader whilst keeping the animation on a visually pleasing level.
374 | * @method setSpeed
375 | * @public
376 | * @param speed {Number} The default value is 2
377 | **/
378 | p.setSpeed = function (speed) { this.speed = Math.round(Math.abs(speed)); };
379 | /**
380 | * Returns the speed of the loader animation
381 | * @method getSpeed
382 | * @public
383 | * @return {Number}
384 | **/
385 | p.getSpeed = function () { return this.speed; };
386 | /**
387 | * The FPS value of the loader animation rendering
388 | * @property fps
389 | * @protected
390 | * @type Number
391 | **/
392 | p.fps = 24;
393 | /**
394 | * Sets the rendering frequency.
395 | * This value tells the loader how many times to refresh and modify the canvas in 1 second.
396 | * Using the right combination of the setSpeed and the setFPS methods allows the users to optimize the CPU usage of the loader whilst keeping the animation on a visually pleasing level.
397 | * @method setFPS
398 | * @public
399 | * @param fps {Number} The default value is 24
400 | **/
401 | p.setFPS = function (fps) { this.fps = Math.round(Math.abs(fps)); this.reset(); };
402 | /**
403 | * Returns the fps of the loader
404 | * @method getFPS
405 | * @public
406 | * @return {Number}
407 | **/
408 | p.getFPS = function () { return this.fps; };
409 | // End of Property declarations
410 | /////////////////////////////////////////////////////////////////////////////////////////////
411 | /**
412 | * Return the RGB values of the passed color
413 | * @method getRGB
414 | * @protected
415 | * @param color {String} The HEX color value to be converted to RGB
416 | */
417 | p.getRGB = function (c) {
418 | c = c.charAt(0) === "#" ? c.substring(1, 7) : c;
419 | return {r: parseInt(c.substring(0, 2), 16), g: parseInt(c.substring(2, 4), 16), b: parseInt(c.substring(4, 6), 16) };
420 | };
421 | /**
422 | * Draw the shapes on the canvas
423 | * @method draw
424 | * @protected
425 | */
426 | p.draw = function () {
427 | var i = 0, size, w, h, x, y, ang, rads, rad, de = this.density, animBits = Math.round(de * this.range), bitMod, minBitMod = 0, s, g, sh, f, d = 1000, arc = 0, c = this.cCon, di = this.diameter, e = 0.47;
428 | if (engine === engines[0]) {
429 | c.clearRect(0, 0, d, d);
430 | setAttr(this.can, {width: di, height: di});
431 | setAttr(this.cCan, {width: di, height: di});
432 | while (i < de) {
433 | bitMod = i <= animBits ? 1 - ((1 - minBitMod) / animBits * i) : bitMod = minBitMod;
434 | ang = 270 - 360 / de * i;
435 | rads = ang / 180 * Math.PI;
436 | c.fillStyle = "rgba(" + this.cRGB.r + "," + this.cRGB.g + "," + this.cRGB.b + "," + bitMod.toString() + ")";
437 | switch (this.shape) {
438 | case shapes[0]:
439 | case shapes[1]:
440 | size = di * 0.07;
441 | x = di * e + Math.cos(rads) * (di * e - size) - di * e;
442 | y = di * e + Math.sin(rads) * (di * e - size) - di * e;
443 | c.beginPath();
444 | if (this.shape === shapes[1]) { c.arc(di * 0.5 + x, di * 0.5 + y, size * bitMod, 0, Math.PI * 2, false); } else { c.arc(di * 0.5 + x, di * 0.5 + y, size, 0, Math.PI * 2, false); }
445 | break;
446 | case shapes[2]:
447 | size = di * 0.12;
448 | x = Math.cos(rads) * (di * e - size) + di * 0.5;
449 | y = Math.sin(rads) * (di * e - size) + di * 0.5;
450 | transCon(c, x, y, rads);
451 | c.fillRect(x, y - size * 0.5, size, size);
452 | break;
453 | case shapes[3]:
454 | case shapes[4]:
455 | w = di * 0.3;
456 | h = w * 0.27;
457 | x = Math.cos(rads) * (h + (di - h) * 0.13) + di * 0.5;
458 | y = Math.sin(rads) * (h + (di - h) * 0.13) + di * 0.5;
459 | transCon(c, x, y, rads);
460 | if(this.shape === shapes[3]) {
461 | c.fillRect(x, y - h * 0.5, w, h);
462 | } else {
463 | rad = h * 0.55;
464 | c.moveTo(x + rad, y - h * 0.5);
465 | c.lineTo(x + w - rad, y - h * 0.5);
466 | c.quadraticCurveTo(x + w, y - h * 0.5, x + w, y - h * 0.5 + rad);
467 | c.lineTo(x + w, y - h * 0.5 + h - rad);
468 | c.quadraticCurveTo(x + w, y - h * 0.5 + h, x + w - rad, y - h * 0.5 + h);
469 | c.lineTo(x + rad, y - h * 0.5 + h);
470 | c.quadraticCurveTo(x, y - h * 0.5 + h, x, y - h * 0.5 + h - rad);
471 | c.lineTo(x, y - h * 0.5 + rad);
472 | c.quadraticCurveTo(x, y - h * 0.5, x + rad, y - h * 0.5);
473 | }
474 | break;
475 | }
476 | c.closePath();
477 | c.fill();
478 | c.restore();
479 | ++i;
480 | }
481 | } else {
482 | setCSS(this.cont, {width: di, height: di});
483 | setCSS(this.vml, {width: di, height: di});
484 | switch (this.shape) {
485 | case shapes[0]:
486 | case shapes[1]:
487 | sh = "oval";
488 | size = d * 0.14;
489 | break;
490 | case shapes[2]:
491 | sh = "roundrect";
492 | size = d * 0.12;
493 | break;
494 | case shapes[3]:
495 | case shapes[4]:
496 | sh = "roundrect";
497 | size = d * 0.3;
498 | break;
499 | }
500 | w = h = size;
501 | x = d * 0.5 - h;
502 | y = -h * 0.5;
503 | while (i < de) {
504 | bitMod = i <= animBits ? 1 - ((1 - minBitMod) / animBits * i) : bitMod = minBitMod;
505 | ang = 270 - 360 / de * i;
506 | switch (this.shape) {
507 | case shapes[1]:
508 | w = h = size * bitMod;
509 | x = d * 0.5 - size * 0.5 - size * bitMod * 0.5;
510 | y = (size - size * bitMod) * 0.5;
511 | break;
512 | case shapes[0]:
513 | case shapes[2]:
514 | if (ie8) {
515 | y = 0;
516 | if(this.shape === shapes[2]) {
517 | x = d * 0.5 -h * 0.5;
518 | }
519 | }
520 | break;
521 | case shapes[3]:
522 | case shapes[4]:
523 | w = size * 0.95;
524 | h = w * 0.28;
525 | if (ie8) {
526 | x = 0;
527 | y = d * 0.5 - h * 0.5;
528 | } else {
529 | x = d * 0.5 - w;
530 | y = -h * 0.5;
531 | }
532 | arc = this.shape === shapes[4] ? 0.6 : 0;
533 | break;
534 | }
535 | g = setAttr(setCSS(addEl("group", this.vml), {width: d, height: d, rotation: ang}), {coordsize: d + "," + d, coordorigin: -d * 0.5 + "," + (-d * 0.5)});
536 | s = setCSS(addEl(sh, g, {stroked: false, arcSize: arc}), { width: w, height: h, top: y, left: x});
537 | f = addEl("fill", s, {color: this.color, opacity: bitMod});
538 | ++i;
539 | }
540 | }
541 | this.tick(true);
542 | };
543 | /**
544 | * Cleans the canvas
545 | * @method clean
546 | * @protected
547 | */
548 | p.clean = function () {
549 | if (engine === engines[0]) {
550 | this.con.clearRect(0, 0, 1000, 1000);
551 | } else {
552 | var v = this.vml;
553 | if (v.hasChildNodes()) {
554 | while (v.childNodes.length >= 1) {
555 | v.removeChild(v.firstChild);
556 | }
557 | }
558 | }
559 | };
560 | /**
561 | * Redraws the canvas
562 | * @method redraw
563 | * @protected
564 | */
565 | p.redraw = function () {
566 | this.clean();
567 | this.draw();
568 | };
569 | /**
570 | * Resets the timer
571 | * @method reset
572 | * @protected
573 | */
574 | p.reset = function () {
575 | if (typeof (this.timer) === "number") {
576 | this.hide();
577 | this.show();
578 | }
579 | };
580 | /**
581 | * Renders the loader animation
582 | * @method tick
583 | * @protected
584 | */
585 | p.tick = function (init) {
586 | var c = this.con, di = this.diameter;
587 | if (!init) { this.activeId += 360 / this.density * this.speed; }
588 | if (engine === engines[0]) {
589 | c.clearRect(0, 0, di, di);
590 | transCon(c, di * 0.5, di * 0.5, this.activeId / 180 * Math.PI);
591 | c.drawImage(this.cCan, 0, 0, di, di);
592 | c.restore();
593 | } else {
594 | if (this.activeId >= 360) { this.activeId -= 360; }
595 | setCSS(this.vml, {rotation:this.activeId});
596 | }
597 | };
598 | /**
599 | * Shows the rendering of the loader animation
600 | * @method show
601 | * @public
602 | */
603 | p.show = function () {
604 | if (typeof (this.timer) !== "number") {
605 | var t = this;
606 | this.timer = self.setInterval(function () { t.tick(); }, Math.round(1000 / this.fps));
607 | setCSS(this.cont, {display: "block"});
608 | }
609 | };
610 | /**
611 | * Stops the rendering of the loader animation and hides the loader
612 | * @method hide
613 | * @public
614 | */
615 | p.hide = function () {
616 | if (typeof (this.timer) === "number") {
617 | clearInterval(this.timer);
618 | delete this.timer;
619 | setCSS(this.cont, {display: "none"});
620 | }
621 | };
622 | /**
623 | * Removes the CanvasLoader instance and all its references
624 | * @method kill
625 | * @public
626 | */
627 | p.kill = function () {
628 | var c = this.cont;
629 | if (typeof (this.timer) === "number") { this.hide(); }
630 | if (engine === engines[0]) {
631 | c.removeChild(this.can);
632 | c.removeChild(this.cCan);
633 | } else {
634 | c.removeChild(this.vml);
635 | }
636 | var n;
637 | for (n in this) { delete this[n]; }
638 | };
639 | window.CanvasLoader = CanvasLoader;
640 | }(window));
--------------------------------------------------------------------------------