PageSourceSearch

https://www.mysubaru.com/asset/_js/spin.js

js mysubaru.com collected 2026-10-02 15:10:23 UTC 11,792 bytes, 378 lines download raw bytes

1/**
2 * Copyright (c) 2011-2014 Felix Gnass
3 * Licensed under the MIT license
4 * http://spin.js.org/
5 *
6 * Example:
7    var opts = {
8      lines: 12,            // The number of lines to draw
9      length: 7,            // The length of each line
10      width: 5,             // The line thickness
11      radius: 10,           // The radius of the inner circle
12      scale: 1.0,           // Scales overall size of the spinner
13      corners: 1,           // Roundness (0..1)
14      color: '#000',        // #rgb or #rrggbb
15      opacity: 1/4,         // Opacity of the lines
16      rotate: 0,            // Rotation offset
17      direction: 1,         // 1: clockwise, -1: counterclockwise
18      speed: 1,             // Rounds per second
19      trail: 100,           // Afterglow percentage
20      fps: 20,              // Frames per second when using setTimeout()
21      zIndex: 2e9,          // Use a high z-index by default
22      className: 'spinner', // CSS class to assign to the element
23      top: '50%',           // center vertically
24      left: '50%',          // center horizontally
25      shadow: false,        // Whether to render a shadow
26      hwaccel: false,       // Whether to use hardware acceleration (might be buggy)
27      position: 'absolute'  // Element positioning
28    };
29    var target = document.getElementById('foo');
30    var spinner = new Spinner(opts).spin(target);
31 */
32;(function(root, factory) {
33  if (typeof module == 'object' && module.exports) module.exports = factory(); // CommonJS
34  else if (typeof define == 'function' && define.amd) define(factory); // AMD module
35  else root.Spinner = factory(); // Browser global
36}
37(this, function() {
38  'use strict';
39
40  var prefixes = ['webkit', 'Moz', 'ms', 'O']; // Vendor prefixes
41  var animations = {}; // Animation rules keyed by their name
42  var useCssAnimations; // Whether to use CSS animations or setTimeout
43  var sheet; // A stylesheet to hold the @keyframe or VML rules
44
45  /**
46   * Utility function to create elements. If no tag name is given,
47   * a DIV is created. Optionally properties can be passed.
48   */
49  function createEl(tag, prop) {
50    var el = document.createElement(tag || 'div');
51    var n;
52
53    for (n in prop) el[n] = prop[n];
54    return el;
55  }
56
57  /**
58   * Appends children and returns the parent.
59   */
60  function ins(parent /* child1, child2, ...*/) {
61    for (var i = 1, n = arguments.length; i < n; i++) {
62      parent.appendChild(arguments[i]);
63    }
64
65    return parent;
66  }
67
68  /**
69   * Creates an opacity keyframe animation rule and returns its name.
70   * Since most mobile Webkits have timing issues with animation-delay,
71   * we create separate rules for each line/segment.
72   */
73  function addAnimation(alpha, trail, i, lines) {
74    var name = ['opacity', trail, ~~(alpha * 100), i, lines].join('-');
75    var start = 0.01 + i/lines * 100;
76    var z = Math.max(1 - (1-alpha) / trail * (100-start), alpha);
77    var prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase();
78    var pre = prefix && '-' + prefix + '-' || '';
79
80    if (!animations[name]) {
81      sheet.insertRule(
82        '@' + pre + 'keyframes ' + name + '{' +
83        '0%{opacity:' + z + '}' +
84        start + '%{opacity:' + alpha + '}' +
85        (start+0.01) + '%{opacity:1}' +
86        (start+trail) % 100 + '%{opacity:' + alpha + '}' +
87        '100%{opacity:' + z + '}' +
88        '}', sheet.cssRules.length);
89
90      animations[name] = 1;
91    }
92
93    return name;
94  }
95
96  /**
97   * Tries various vendor prefixes and returns the first supported property.
98   */
99  function vendor(el, prop) {
100    var s = el.style;
101    var pp;
102    var i;
103
104    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
105    if (s[prop] !== undefined) return prop;
106    for (i = 0; i < prefixes.length; i++) {
107      pp = prefixes[i]+prop;
108      if (s[pp] !== undefined) return pp;
109    }
110  }
111
112  /**
113   * Sets multiple style properties at once.
114   */
115  function css(el, prop) {
116    for (var n in prop) {
117      el.style[vendor(el, n) || n] = prop[n];
118    }
119
120    return el;
121  }
122
123  /**
124   * Fills in default values.
125   */
126  function merge(obj) {
127    for (var i = 1; i < arguments.length; i++) {
128      var def = arguments[i];
129      for (var n in def) {
130        if (obj[n] === undefined) obj[n] = def[n];
131      }
132    }
133    return obj;
134  }
135
136  /**
137   * Returns the line color from the given string or array.
138   */
139  function getColor(color, idx) {
140    return typeof color == 'string' ? color : color[idx % color.length];
141  }
142
143  // Built-in defaults
144
145  var defaults = {
146    lines: 12,            // The number of lines to draw
147    length: 7,            // The length of each line
148    width: 5,             // The line thickness
149    radius: 10,           // The radius of the inner circle
150    scale: 1.0,           // Scales overall size of the spinner
151    corners: 1,           // Roundness (0..1)
152    color: '#000',        // #rgb or #rrggbb
153    opacity: 1/4,         // Opacity of the lines
154    rotate: 0,            // Rotation offset
155    direction: 1,         // 1: clockwise, -1: counterclockwise
156    speed: 1,             // Rounds per second
157    trail: 100,           // Afterglow percentage
158    fps: 20,              // Frames per second when using setTimeout()
159    zIndex: 2e9,          // Use a high z-index by default
160    className: 'spinner', // CSS class to assign to the element
161    top: '50%',           // center vertically
162    left: '50%',          // center horizontally
163    shadow: false,        // Whether to render a shadow
164    hwaccel: false,       // Whether to use hardware acceleration
165    position: 'fixed'  // Element positioning
166  };
167
168  /** The constructor */
169  function Spinner(o) {
170    this.opts = merge(o || {}, Spinner.defaults, defaults);
171  }
172
173  // Global defaults that override the built-ins:
174  Spinner.defaults = {};
175
176  merge(Spinner.prototype, {
177    /**
178     * Adds the spinner to the given target element. If this instance is already
179     * spinning, it is automatically removed from its previous target b calling
180     * stop() internally.
181     */
182    spin: function(target) {
183      this.stop();
184
185      var self = this;
186      var o = self.opts;
187      var el = self.el = createEl(null, {className: o.className});
188
189      css(el, {
190        position: o.position,
191        width: 0,
192        zIndex: o.zIndex,
193        left: o.left,
194        top: o.top
195      });
196
197      if (target) {
198        target.insertBefore(el, target.firstChild || null);
199      }
200
201      el.setAttribute('role', 'progressbar');
202      self.lines(el, self.opts);
203
204      if (!useCssAnimations) {
205        // No CSS animation support, use setTimeout() instead
206        var i = 0;
207        var start = (o.lines - 1) * (1 - o.direction) / 2;
208        var alpha;
209        var fps = o.fps;
210        var f = fps / o.speed;
211        var ostep = (1 - o.opacity) / (f * o.trail / 100);
212        var astep = f / o.lines;
213
214        (function anim() {
215          i++;
216          for (var j = 0; j < o.lines; j++) {
217            alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity);
218
219            self.opacity(el, j * o.direction + start, alpha, o);
220          }
221          self.timeout = self.el && setTimeout(anim, ~~(1000 / fps));
222        })();
223      }
224      return self;
225    },
226
227    /**
228     * Stops and removes the Spinner.
229     */
230    stop: function() {
231      var el = this.el;
232      if (el) {
233        clearTimeout(this.timeout);
234        if (el.parentNode) el.parentNode.removeChild(el);
235        this.el = undefined;
236      }
237      return this;
238    },
239
240    /**
241     * Internal method that draws the individual lines. Will be overwritten
242     * in VML fallback mode below.
243     */
244    lines: function(el, o) {
245      var i = 0;
246      var start = (o.lines - 1) * (1 - o.direction) / 2;
247      var seg;
248
249      function fill(color, shadow) {
250        return css(createEl(), {
251          position: 'absolute',
252          width: o.scale * (o.length + o.width) + 'px',
253          height: o.scale * o.width + 'px',
254          background: color,
255          boxShadow: shadow,
256          transformOrigin: 'left',
257          transform: 'rotate(' + ~~(360/o.lines*i + o.rotate) + 'deg) translate(' + o.scale*o.radius + 'px' + ',0)',
258          borderRadius: (o.corners * o.scale * o.width >> 1) + 'px'
259        });
260      }
261
262      for (; i < o.lines; i++) {
263        seg = css(createEl(), {
264          position: 'absolute',
265          top: 1 + ~(o.scale * o.width / 2) + 'px',
266          transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
267          opacity: o.opacity,
268          animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1 / o.speed + 's linear infinite'
269        });
270
271        if (o.shadow) ins(seg, css(fill('#000', '0 0 4px #000'), {top: '2px'}));
272        ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)')));
273      }
274      return el;
275    },
276
277    /**
278     * Internal method that adjusts the opacity of a single line.
279     * Will be overwritten in VML fallback mode below.
280     */
281    opacity: function(el, i, val) {
282      if (i < el.childNodes.length) el.childNodes[i].style.opacity = val;
283    }
284
285  });
286
287
288  function initVML() {
289
290    /* Utility function to create a VML tag */
291    function vml(tag, attr) {
292      return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr);
293    }
294
295    // No CSS transforms but VML support, add a CSS rule for VML elements:
296    sheet.addRule('.spin-vml', 'behavior:url(#default#VML)');
297
298    Spinner.prototype.lines = function(el, o) {
299      var r = o.scale * (o.length + o.width);
300      var s = o.scale * 2 * r;
301
302      function grp() {
303        return css(
304          vml('group', {
305            coordsize: s + ' ' + s,
306            coordorigin: -r + ' ' + -r
307          }),
308          { width: s, height: s }
309        );
310      }
311
312      var margin = -(o.width + o.length) * o.scale * 2 + 'px';
313      var g = css(grp(), {position: 'absolute', top: margin, left: margin});
314      var i;
315
316      function seg(i, dx, filter) {
317        ins(
318          g,
319          ins(
320            css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
321            ins(
322              css(
323                vml('roundrect', {arcsize: o.corners}),
324                {
325                  width: r,
326                  height: o.scale * o.width,
327                  left: o.scale * o.radius,
328                  top: -o.scale * o.width >> 1,
329                  filter: filter
330                }
331              ),
332              vml('fill', {color: getColor(o.color, i), opacity: o.opacity}),
333              vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
334            )
335          )
336        );
337      }
338
339      if (o.shadow)
340        for (i = 1; i <= o.lines; i++) {
341          seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
342        }
343
344      for (i = 1; i <= o.lines; i++) seg(i);
345      return ins(el, g);
346    };
347
348    Spinner.prototype.opacity = function(el, i, val, o) {
349      var c = el.firstChild;
350      o = o.shadow && o.lines || 0;
351      if (c && i + o < c.childNodes.length) {
352        c = c.childNodes[i + o]; c = c && c.firstChild; c = c && c.firstChild;
353        if (c) c.opacity = val;
354      }
355    };
356  }
357
358  if (typeof document !== 'undefined') {
359    sheet = (function() {
360      var el = createEl('style', {type : 'text/css'});
361      ins(document.getElementsByTagName('head')[0], el);
362      return el.sheet || el.styleSheet;
363    }());
364
365    var probe = css(createEl('group'), {behavior: 'url(#default#VML)'});
366
367    if (!vendor(probe, 'transform') && probe.adj) initVML();
368    else useCssAnimations = vendor(probe, 'animation');
369  }
370
371  return Spinner;
372
373}));
374
375// Ensure Spinner is available globally
376if (typeof Spinner !== 'undefined') {
377  window.Spinner = Spinner;
378}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.