terom@42: //fgnass.github.com/spin.js#v1.2.7 terom@42: !function(window, document, undefined) { terom@42: terom@42: /** terom@42: * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de] terom@42: * Licensed under the MIT license terom@42: */ terom@42: terom@42: var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */ terom@42: , animations = {} /* Animation rules keyed by their name */ terom@42: , useCssAnimations terom@42: terom@42: /** terom@42: * Utility function to create elements. If no tag name is given, terom@42: * a DIV is created. Optionally properties can be passed. terom@42: */ terom@42: function createEl(tag, prop) { terom@42: var el = document.createElement(tag || 'div') terom@42: , n terom@42: terom@42: for(n in prop) el[n] = prop[n] terom@42: return el terom@42: } terom@42: terom@42: /** terom@42: * Appends children and returns the parent. terom@42: */ terom@42: function ins(parent /* child1, child2, ...*/) { terom@42: for (var i=1, n=arguments.length; i> 1) : parseInt(o.left, 10) + mid) + 'px', terom@42: top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px' terom@42: }) terom@42: } terom@42: terom@42: el.setAttribute('aria-role', 'progressbar') terom@42: self.lines(el, self.opts) terom@42: terom@42: if (!useCssAnimations) { terom@42: // No CSS animation support, use setTimeout() instead terom@42: var i = 0 terom@42: , fps = o.fps terom@42: , f = fps/o.speed terom@42: , ostep = (1-o.opacity) / (f*o.trail / 100) terom@42: , astep = f/o.lines terom@42: terom@42: ;(function anim() { terom@42: i++; terom@42: for (var s=o.lines; s; s--) { terom@42: var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity) terom@42: self.opacity(el, o.lines-s, alpha, o) terom@42: } terom@42: self.timeout = self.el && setTimeout(anim, ~~(1000/fps)) terom@42: })() terom@42: } terom@42: return self terom@42: }, terom@42: terom@42: stop: function() { terom@42: var el = this.el terom@42: if (el) { terom@42: clearTimeout(this.timeout) terom@42: if (el.parentNode) el.parentNode.removeChild(el) terom@42: this.el = undefined terom@42: } terom@42: return this terom@42: }, terom@42: terom@42: lines: function(el, o) { terom@42: var i = 0 terom@42: , seg terom@42: terom@42: function fill(color, shadow) { terom@42: return css(createEl(), { terom@42: position: 'absolute', terom@42: width: (o.length+o.width) + 'px', terom@42: height: o.width + 'px', terom@42: background: color, terom@42: boxShadow: shadow, terom@42: transformOrigin: 'left', terom@42: transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)', terom@42: borderRadius: (o.corners * o.width>>1) + 'px' terom@42: }) terom@42: } terom@42: terom@42: for (; i < o.lines; i++) { terom@42: seg = css(createEl(), { terom@42: position: 'absolute', terom@42: top: 1+~(o.width/2) + 'px', terom@42: transform: o.hwaccel ? 'translate3d(0,0,0)' : '', terom@42: opacity: o.opacity, terom@42: animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite' terom@42: }) terom@42: terom@42: if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'})) terom@42: terom@42: ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)'))) terom@42: } terom@42: return el terom@42: }, terom@42: terom@42: opacity: function(el, i, val) { terom@42: if (i < el.childNodes.length) el.childNodes[i].style.opacity = val terom@42: } terom@42: terom@42: }) terom@42: terom@42: ///////////////////////////////////////////////////////////////////////// terom@42: // VML rendering for IE terom@42: ///////////////////////////////////////////////////////////////////////// terom@42: terom@42: /** terom@42: * Check and init VML support terom@42: */ terom@42: ;(function() { terom@42: terom@42: function vml(tag, attr) { terom@42: return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr) terom@42: } terom@42: terom@42: var s = css(createEl('group'), {behavior: 'url(#default#VML)'}) terom@42: terom@42: if (!vendor(s, 'transform') && s.adj) { terom@42: terom@42: // VML support detected. Insert CSS rule ... terom@42: sheet.addRule('.spin-vml', 'behavior:url(#default#VML)') terom@42: terom@42: Spinner.prototype.lines = function(el, o) { terom@42: var r = o.length+o.width terom@42: , s = 2*r terom@42: terom@42: function grp() { terom@42: return css( terom@42: vml('group', { terom@42: coordsize: s + ' ' + s, terom@42: coordorigin: -r + ' ' + -r terom@42: }), terom@42: { width: s, height: s } terom@42: ) terom@42: } terom@42: terom@42: var margin = -(o.width+o.length)*2 + 'px' terom@42: , g = css(grp(), {position: 'absolute', top: margin, left: margin}) terom@42: , i terom@42: terom@42: function seg(i, dx, filter) { terom@42: ins(g, terom@42: ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}), terom@42: ins(css(vml('roundrect', {arcsize: o.corners}), { terom@42: width: r, terom@42: height: o.width, terom@42: left: o.radius, terom@42: top: -o.width>>1, terom@42: filter: filter terom@42: }), terom@42: vml('fill', {color: o.color, opacity: o.opacity}), terom@42: vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change terom@42: ) terom@42: ) terom@42: ) terom@42: } terom@42: terom@42: if (o.shadow) terom@42: for (i = 1; i <= o.lines; i++) terom@42: seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)') terom@42: terom@42: for (i = 1; i <= o.lines; i++) seg(i) terom@42: return ins(el, g) terom@42: } terom@42: terom@42: Spinner.prototype.opacity = function(el, i, val, o) { terom@42: var c = el.firstChild terom@42: o = o.shadow && o.lines || 0 terom@42: if (c && i+o < c.childNodes.length) { terom@42: c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild terom@42: if (c) c.opacity = val terom@42: } terom@42: } terom@42: } terom@42: else terom@42: useCssAnimations = vendor(s, 'animation') terom@42: })() terom@42: terom@42: if (typeof define == 'function' && define.amd) terom@42: define(function() { return Spinner }) terom@42: else terom@42: window.Spinner = Spinner terom@42: terom@42: }(window, document);