├── README.md ├── css ├── component.css ├── demo.css └── normalize.css ├── fonts └── codropsicons │ ├── codropsicons.eot │ ├── codropsicons.svg │ ├── codropsicons.ttf │ ├── codropsicons.woff │ └── license.txt ├── index.html └── js ├── classie.js ├── modernizr.custom.js └── uiProgressButton.js /README.md: -------------------------------------------------------------------------------- 1 | Circular Progress Button 2 | ========= 3 | 4 | Implementation of Colin Garvin's [submit button concept](http://dribbble.com/shots/1426764-Submit-Button) 5 | 6 | [Article on Codrops](http://tympanus.net/codrops/?p=18828) 7 | 8 | [Demo](http://tympanus.net/Tutorials/CircularProgressButton/) 9 | 10 | Integrate or build upon it for free in your personal or commercial projects. Don't republish, redistribute or sell "as-is". 11 | 12 | Read more here: [License](http://tympanus.net/codrops/licensing/) 13 | 14 | 15 | [© Codrops 2014](http://www.codrops.com) -------------------------------------------------------------------------------- /css/component.css: -------------------------------------------------------------------------------- 1 | /* Button container */ 2 | .progress-button { 3 | position: relative; 4 | display: inline-block; 5 | text-align: center; 6 | width: 45%; 7 | min-width: 250px; 8 | margin: 10px; 9 | } 10 | 11 | /* Button style */ 12 | .progress-button button { 13 | display: block; 14 | margin: 0 auto; 15 | padding: 0; 16 | width: 250px; 17 | height: 70px; 18 | border: 2px solid #1ECD97; 19 | border-radius: 40px; 20 | background: transparent; 21 | color: #1ECD97; 22 | letter-spacing: 1px; 23 | font-size: 18px; 24 | font-family: 'Montserrat', sans-serif; 25 | -webkit-tap-highlight-color: transparent; 26 | -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s, border-width 0.3s, border-color 0.3s; 27 | transition: background-color 0.3s, color 0.3s, width 0.3s, border-width 0.3s, border-color 0.3s; 28 | } 29 | 30 | .progress-button button:hover { 31 | background-color: #1ECD97; 32 | color: #fff; 33 | } 34 | 35 | .progress-button button:focus { 36 | outline: none; 37 | } 38 | 39 | /* Text (transition for when returning to initial state) */ 40 | .progress-button button span { 41 | -webkit-transition: opacity 0.3s 0.1s; 42 | transition: opacity 0.3s 0.1s; 43 | } 44 | 45 | /* Common style of SVGs */ 46 | .progress-button svg { 47 | position: absolute; 48 | top: 0; 49 | left: 50%; 50 | -webkit-transform: translateX(-50%); 51 | transform: translateX(-50%); 52 | pointer-events: none; 53 | } 54 | 55 | .progress-button svg path { 56 | opacity: 0; 57 | fill: none; 58 | } 59 | 60 | .progress-button svg.progress-circle path { 61 | stroke: #1ECD97; 62 | stroke-width: 5; 63 | } 64 | 65 | .progress-button svg.checkmark path, 66 | .progress-button svg.cross path { 67 | stroke: #fff; 68 | stroke-linecap: round; 69 | stroke-width: 4; 70 | -webkit-transition: opacity 0.1s; 71 | transition: opacity 0.1s; 72 | } 73 | 74 | /* Loading, success and error effects */ 75 | .loading.progress-button button { 76 | width: 70px; /* make a circle */ 77 | border-width: 5px; 78 | border-color: #ddd; 79 | background-color: transparent; 80 | color: #fff; 81 | } 82 | 83 | .loading.progress-button span { 84 | -webkit-transition: opacity 0.15s; 85 | transition: opacity 0.15s; 86 | } 87 | 88 | .loading.progress-button span, 89 | .success.progress-button span, 90 | .error.progress-button span { 91 | opacity: 0; /* keep it hidden in all states */ 92 | } 93 | 94 | .success.progress-button button, 95 | .error.progress-button button { 96 | -webkit-transition: background-color 0.3s, width 0.3s, border-width 0.3s; 97 | transition: background-color 0.3s, width 0.3s, border-width 0.3s; 98 | } 99 | 100 | .success.progress-button button { 101 | border-color: #1ECD97; 102 | background-color: #1ECD97; 103 | } 104 | 105 | .error.progress-button button { 106 | border-color: #FB797E; 107 | background-color: #FB797E; 108 | } 109 | 110 | .loading.progress-button svg.progress-circle path, 111 | .success.progress-button svg.checkmark path, 112 | .error.progress-button svg.cross path { 113 | opacity: 1; 114 | -webkit-transition: stroke-dashoffset 0.3s; 115 | transition: stroke-dashoffset 0.3s; 116 | } 117 | 118 | /* Optional elastic effect for the width of the button */ 119 | .elastic.progress-button button { 120 | -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.25, 0.25, 0.4, 1), border-width 0.3s, border-color 0.3s; 121 | -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.25, 0.25, 0.4, 1.6), border-width 0.3s, border-color 0.3s; 122 | transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.25, 0.25, 0.4, 1.6), border-width 0.3s, border-color 0.3s; 123 | } 124 | 125 | .loading.elastic.progress-button button { 126 | -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.6, 0, 0.75, 0.75), border-width 0.3s, border-color 0.3s; 127 | -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.6, -0.6, 0.75, 0.75), border-width 0.3s, border-color 0.3s; 128 | transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.6, -0.6, 0.75, 0.75), border-width 0.3s, border-color 0.3s; 129 | } 130 | -------------------------------------------------------------------------------- /css/demo.css: -------------------------------------------------------------------------------- 1 | @import url(http://fonts.googleapis.com/css?family=Lato:300,400,700|Montserrat); 2 | @font-face { 3 | font-weight: normal; 4 | font-style: normal; 5 | font-family: 'codropsicons'; 6 | src:url('../fonts/codropsicons/codropsicons.eot'); 7 | src:url('../fonts/codropsicons/codropsicons.eot?#iefix') format('embedded-opentype'), 8 | url('../fonts/codropsicons/codropsicons.woff') format('woff'), 9 | url('../fonts/codropsicons/codropsicons.ttf') format('truetype'), 10 | url('../fonts/codropsicons/codropsicons.svg#codropsicons') format('svg'); 11 | } 12 | 13 | *, *:after, *:before { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } 14 | .clearfix:before, .clearfix:after { content: ''; display: table; } 15 | .clearfix:after { clear: both; } 16 | 17 | body { 18 | background: #f9f9f9; 19 | color: #62706c; 20 | font-size: 100%; 21 | line-height: 1.25; 22 | padding: 25px 0; 23 | border-right: 25px solid #fff; 24 | border-left: 25px solid #fff; 25 | font-family: 'Lato', Arial, sans-serif; 26 | } 27 | 28 | body::before, 29 | body::after { 30 | content: ''; 31 | position: fixed; 32 | left: 0; 33 | top: 0; 34 | width: 100%; 35 | height: 25px; 36 | background: #fff; 37 | z-index: 99; 38 | } 39 | 40 | body::after { 41 | top: auto; 42 | bottom: 0; 43 | } 44 | 45 | a { 46 | color: rgba(0,0,0,0.3); 47 | text-decoration: none; 48 | outline: none; 49 | } 50 | 51 | a:hover, a:focus { 52 | color: rgba(0,0,0,0.6); 53 | } 54 | 55 | .codrops-header { 56 | margin: 0 auto; 57 | padding: 4em 1em; 58 | text-align: center; 59 | } 60 | 61 | .codrops-header h1 { 62 | margin: 0; 63 | font-weight: 300; 64 | font-size: 2.5em; 65 | position: relative; 66 | } 67 | 68 | .codrops-header h1 span { 69 | display: block; 70 | padding: 0 0 0.6em 0.1em; 71 | font-size: 0.6em; 72 | color: #aaa; 73 | } 74 | 75 | .codrops-header a { 76 | color: #1ECD97; 77 | } 78 | 79 | .codrops-header a:hover { 80 | color: #44524e; 81 | } 82 | 83 | /* To Navigation Style */ 84 | .codrops-top { 85 | width: 100%; 86 | top: 0; 87 | left: 0; 88 | text-transform: uppercase; 89 | font-weight: 700; 90 | font-size: 0.69em; 91 | line-height: 2.2; 92 | z-index: 1000; 93 | padding-top: 3px; 94 | } 95 | 96 | .codrops-top a { 97 | display: inline-block; 98 | padding: 0 1em; 99 | text-decoration: none; 100 | letter-spacing: 1px; 101 | } 102 | 103 | .codrops-top span.right { 104 | float: right; 105 | } 106 | 107 | .codrops-top span.right a { 108 | display: block; 109 | float: left; 110 | } 111 | 112 | .codrops-icon:before { 113 | margin: 0 4px; 114 | text-transform: none; 115 | font-weight: normal; 116 | font-style: normal; 117 | font-variant: normal; 118 | font-family: 'codropsicons'; 119 | line-height: 1; 120 | speak: none; 121 | -webkit-font-smoothing: antialiased; 122 | } 123 | 124 | .codrops-icon-drop:before { 125 | content: "\e001"; 126 | } 127 | 128 | .codrops-icon-prev:before { 129 | content: "\e004"; 130 | } 131 | 132 | section { 133 | text-align: center; 134 | position: relative; 135 | } 136 | 137 | section h2 { 138 | color: #ccc; 139 | font-weight: 400; 140 | margin: 2em 0 0; 141 | font-size: 1.15em; 142 | padding: 0 1em; 143 | } 144 | 145 | .box { 146 | width: 100%; 147 | max-width: 720px; 148 | display: inline-block; 149 | padding: 3em 1em; 150 | } 151 | 152 | .box h3 { 153 | color: #aaa; 154 | font-size: 1em; 155 | text-transform: uppercase; 156 | letter-spacing: 1px; 157 | font-weight: 400; 158 | padding: 2em 0; 159 | } 160 | 161 | .related { 162 | padding: 10em 0; 163 | } 164 | 165 | .related p { 166 | font-size: 1.5em; 167 | } 168 | 169 | .related > a { 170 | border: 2px solid rgba(0,0,0,0.3); 171 | display: inline-block; 172 | text-align: center; 173 | margin: 20px 10px; 174 | padding: 25px; 175 | -webkit-transition: color 0.3s, border-color 0.3s; 176 | transition: color 0.3s, border-color 0.3s; 177 | } 178 | 179 | .related a:hover { 180 | border-color: rgba(0,0,0,0.6); 181 | } 182 | 183 | .related a img { 184 | max-width: 100%; 185 | opacity: 0.8; 186 | -webkit-transition: opacity 0.3s; 187 | transition: opacity 0.3s; 188 | } 189 | 190 | .related a:hover img, 191 | .related a:active img { 192 | opacity: 1; 193 | } 194 | 195 | .related a h3 { 196 | margin: 0; 197 | padding: 0.5em 0 0.3em; 198 | max-width: 300px; 199 | text-align: left; 200 | } 201 | 202 | @media screen and (max-width: 26em) { 203 | .codrops-icon span { 204 | display: none; 205 | } 206 | } -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} -------------------------------------------------------------------------------- /fonts/codropsicons/codropsicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CircularProgressButton/3ec3e8c12f5be5085615a5e6f32c6d64d0a0037f/fonts/codropsicons/codropsicons.eot -------------------------------------------------------------------------------- /fonts/codropsicons/codropsicons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG font generated by IcoMoon. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /fonts/codropsicons/codropsicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CircularProgressButton/3ec3e8c12f5be5085615a5e6f32c6d64d0a0037f/fonts/codropsicons/codropsicons.ttf -------------------------------------------------------------------------------- /fonts/codropsicons/codropsicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CircularProgressButton/3ec3e8c12f5be5085615a5e6f32c6d64d0a0037f/fonts/codropsicons/codropsicons.woff -------------------------------------------------------------------------------- /fonts/codropsicons/license.txt: -------------------------------------------------------------------------------- 1 | Icon Set: Font Awesome -- http://fortawesome.github.com/Font-Awesome/ 2 | License: SIL -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 3 | 4 | 5 | Icon Set: Eco Ico -- http://dribbble.com/shots/665585-Eco-Ico 6 | License: CC0 -- http://creativecommons.org/publicdomain/zero/1.0/ -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Circular Progress Button with SVG 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 | Previous Demo 22 | Back to the Codrops Article 23 |
24 |
25 |

Circular Progress Button Implementation of Colin Garvin's Submit Button

26 |
27 |
28 |

Default progress button (success and error)

29 |
30 | 31 |
32 | 33 | 34 | 35 | 36 |
37 | 38 |
39 | 40 | 41 | 42 | 43 |
44 |
45 |

Elastic version, with some easings (success, error)

46 |
47 | 48 |
49 | 50 | 51 | 52 | 53 |
54 | 55 |
56 | 57 | 58 | 59 | 60 |
61 |
62 |
63 | 74 |
75 | 76 | 77 | 95 | 96 | -------------------------------------------------------------------------------- /js/classie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * classie - class helper functions 3 | * from bonzo https://github.com/ded/bonzo 4 | * 5 | * classie.has( elem, 'my-class' ) -> true/false 6 | * classie.add( elem, 'my-new-class' ) 7 | * classie.remove( elem, 'my-unwanted-class' ) 8 | * classie.toggle( elem, 'my-class' ) 9 | */ 10 | 11 | /*jshint browser: true, strict: true, undef: true */ 12 | /*global define: false */ 13 | 14 | ( function( window ) { 15 | 16 | 'use strict'; 17 | 18 | // class helper functions from bonzo https://github.com/ded/bonzo 19 | 20 | function classReg( className ) { 21 | return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); 22 | } 23 | 24 | // classList support for class management 25 | // altho to be fair, the api sucks because it won't accept multiple classes at once 26 | var hasClass, addClass, removeClass; 27 | 28 | if ( 'classList' in document.documentElement ) { 29 | hasClass = function( elem, c ) { 30 | return elem.classList.contains( c ); 31 | }; 32 | addClass = function( elem, c ) { 33 | elem.classList.add( c ); 34 | }; 35 | removeClass = function( elem, c ) { 36 | elem.classList.remove( c ); 37 | }; 38 | } 39 | else { 40 | hasClass = function( elem, c ) { 41 | return classReg( c ).test( elem.className ); 42 | }; 43 | addClass = function( elem, c ) { 44 | if ( !hasClass( elem, c ) ) { 45 | elem.className = elem.className + ' ' + c; 46 | } 47 | }; 48 | removeClass = function( elem, c ) { 49 | elem.className = elem.className.replace( classReg( c ), ' ' ); 50 | }; 51 | } 52 | 53 | function toggleClass( elem, c ) { 54 | var fn = hasClass( elem, c ) ? removeClass : addClass; 55 | fn( elem, c ); 56 | } 57 | 58 | var classie = { 59 | // full names 60 | hasClass: hasClass, 61 | addClass: addClass, 62 | removeClass: removeClass, 63 | toggleClass: toggleClass, 64 | // short names 65 | has: hasClass, 66 | add: addClass, 67 | remove: removeClass, 68 | toggle: toggleClass 69 | }; 70 | 71 | // transport 72 | if ( typeof define === 'function' && define.amd ) { 73 | // AMD 74 | define( classie ); 75 | } else { 76 | // browser global 77 | window.classie = classie; 78 | } 79 | 80 | })( window ); 81 | -------------------------------------------------------------------------------- /js/modernizr.custom.js: -------------------------------------------------------------------------------- 1 | /* Modernizr 2.7.1 (Custom Build) | MIT & BSD 2 | * Build: http://modernizr.com/download/#-csstransitions-shiv-cssclasses-prefixed-testprop-testallprops-domprefixes-load 3 | */ 4 | ;window.Modernizr=function(a,b,c){function x(a){j.cssText=a}function y(a,b){return x(prefixes.join(a+";")+(b||""))}function z(a,b){return typeof a===b}function A(a,b){return!!~(""+a).indexOf(b)}function B(a,b){for(var d in a){var e=a[d];if(!A(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function C(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:z(f,"function")?f.bind(d||b):f}return!1}function D(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+n.join(d+" ")+d).split(" ");return z(b,"string")||z(b,"undefined")?B(e,b):(e=(a+" "+o.join(d+" ")+d).split(" "),C(e,b,c))}var d="2.7.1",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m="Webkit Moz O ms",n=m.split(" "),o=m.toLowerCase().split(" "),p={},q={},r={},s=[],t=s.slice,u,v={}.hasOwnProperty,w;!z(v,"undefined")&&!z(v.call,"undefined")?w=function(a,b){return v.call(a,b)}:w=function(a,b){return b in a&&z(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=t.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(t.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(t.call(arguments)))};return e}),p.csstransitions=function(){return D("transition")};for(var E in p)w(p,E)&&(u=E.toLowerCase(),e[u]=p[E](),s.push((e[u]?"":"no-")+u));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)w(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},x(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._domPrefixes=o,e._cssomPrefixes=n,e.testProp=function(a){return B([a])},e.testAllProps=D,e.prefixed=function(a,b,c){return b?D(a,b,c):D(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+s.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f= 0 ? 'success' : 'error', 134 | statusEl = status >=0 ? self.successEl : self.errorEl; 135 | 136 | // draw stroke of success (checkmark) or error (cross). 137 | statusEl.draw( 1 ); 138 | // add respective class to the element 139 | classie.addClass( self.el, statusClass ); 140 | // after options.statusTime remove status and undraw the respective stroke. Also enable the button. 141 | setTimeout( function() { 142 | classie.remove( self.el, statusClass ); 143 | statusEl.draw(0); 144 | self._enable(); 145 | }, self.options.statusTime ); 146 | } 147 | else { 148 | self._enable(); 149 | } 150 | // finally remove class loading. 151 | classie.removeClass( self.el, 'loading' ); 152 | }; 153 | 154 | // give it a time (ideally the same like the transition time) so that the last progress increment animation is still visible. 155 | setTimeout( endLoading, 300 ); 156 | } 157 | 158 | UIProgressButton.prototype.setProgress = function( val ) { 159 | this.progressEl.draw( val ); 160 | } 161 | 162 | // enable button 163 | UIProgressButton.prototype._enable = function() { 164 | this.button.removeAttribute( 'disabled' ); 165 | } 166 | 167 | // add to global namespace 168 | window.UIProgressButton = UIProgressButton; 169 | 170 | })( window ); --------------------------------------------------------------------------------