PageSourceSearch

https://candyaitool.com/wp-content/plugins/royal-elementor-addons/…/js/lib/particles/particles_ver-3.0.6.js

js candyaitool.com collected 2026-10-07 15:45:23 UTC 43,731 bytes, 1,551 lines download raw bytes

1var _____WB$wombat$assign$function_____=function(name){return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name))||self[name];};if(!self.__WB_pmw){self.__WB_pmw=function(obj){this.__WB_source=obj;return this;}}{
2let window = _____WB$wombat$assign$function_____("window");
3let self = _____WB$wombat$assign$function_____("self");
4let document = _____WB$wombat$assign$function_____("document");
5let location = _____WB$wombat$assign$function_____("location");
6let top = _____WB$wombat$assign$function_____("top");
7let parent = _____WB$wombat$assign$function_____("parent");
8let frames = _____WB$wombat$assign$function_____("frames");
9let opens = _____WB$wombat$assign$function_____("opens");
vendor: 43,009 bytes, lines 10-1550
10/* -----------------------------------------------
11/* Author : Vincent Garreau  - vincentgarreau.com
12/* MIT license: http://opensource.org/licenses/MIT
13/* Demo / Generator : vincentgarreau.com/particles.js
14/* GitHub : github.com/VincentGarreau/particles.js
15/* How to use? : Check the GitHub README
16/* v2.0.0
17/* ----------------------------------------------- */
18
19var pJS = function(tag_id, params){
20
21  var canvas_el = document.querySelector('#'+tag_id+' > .particles-js-canvas-el');
22
23  /* particles.js variables with default values */
24  this.pJS = {
25    canvas: {
26      el: canvas_el,
27      w: canvas_el.offsetWidth,
28      h: canvas_el.offsetHeight
29    },
30    particles: {
31      number: {
32        value: 400,
33        density: {
34          enable: true,
35          value_area: 800
36        }
37      },
38      color: {
39        value: '#fff'
40      },
41      shape: {
42        type: 'circle',
43        stroke: {
44          width: 0,
45          color: '#ff0000'
46        },
47        polygon: {
48          nb_sides: 5
49        },
50        image: {
51          src: '',
52          width: 100,
53          height: 100
54        }
55      },
56      opacity: {
57        value: 1,
58        random: false,
59        anim: {
60          enable: false,
61          speed: 2,
62          opacity_min: 0,
63          sync: false
64        }
65      },
66      size: {
67        value: 20,
68        random: false,
69        anim: {
70          enable: false,
71          speed: 20,
72          size_min: 0,
73          sync: false
74        }
75      },
76      line_linked: {
77        enable: true,
78        distance: 100,
79        color: '#fff',
80        opacity: 1,
81        width: 1
82      },
83      move: {
84        enable: true,
85        speed: 2,
86        direction: 'none',
87        random: false,
88        straight: false,
89        out_mode: 'out',
90        bounce: false,
91        attract: {
92          enable: false,
93          rotateX: 3000,
94          rotateY: 3000
95        }
96      },
97      array: []
98    },
99    interactivity: {
100      detect_on: 'canvas',
101      events: {
102        onhover: {
103          enable: true,
104          mode: 'grab'
105        },
106        onclick: {
107          enable: true,
108          mode: 'push'
109        },
110        resize: true
111      },
112      modes: {
113        grab:{
114          distance: 100,
115          line_linked:{
116            opacity: 1
117          }
118        },
119        bubble:{
120          distance: 200,
121          size: 80,
122          duration: 0.4
123        },
124        repulse:{
125          distance: 200,
126          duration: 0.4
127        },
128        push:{
129          particles_nb: 4
130        },
131        remove:{
132          particles_nb: 2
133        }
134      },
135      mouse:{}
136    },
137    retina_detect: false,
138    fn: {
139      interact: {},
140      modes: {},
141      vendors:{}
142    },
143    tmp: {}
144  };
145
146  var pJS = this.pJS;
147
148  /* params settings */
149  if(params){
150    Object.deepExtend(pJS, params);
151  }
152
153  pJS.tmp.obj = {
154    size_value: pJS.particles.size.value,
155    size_anim_speed: pJS.particles.size.anim.speed,
156    move_speed: pJS.particles.move.speed,
157    line_linked_distance: pJS.particles.line_linked.distance,
158    line_linked_width: pJS.particles.line_linked.width,
159    mode_grab_distance: pJS.interactivity.modes.grab.distance,
160    mode_bubble_distance: pJS.interactivity.modes.bubble.distance,
161    mode_bubble_size: pJS.interactivity.modes.bubble.size,
162    mode_repulse_distance: pJS.interactivity.modes.repulse.distance
163  };
164
165
166  pJS.fn.retinaInit = function(){
167
168    if(pJS.retina_detect && window.devicePixelRatio > 1){
169      pJS.canvas.pxratio = window.devicePixelRatio; 
170      pJS.tmp.retina = true;
171    } 
172    else{
173      pJS.canvas.pxratio = 1;
174      pJS.tmp.retina = false;
175    }
176
177    pJS.canvas.w = pJS.canvas.el.offsetWidth * pJS.canvas.pxratio;
178    pJS.canvas.h = pJS.canvas.el.offsetHeight * pJS.canvas.pxratio;
179
180    pJS.particles.size.value = pJS.tmp.obj.size_value * pJS.canvas.pxratio;
181    pJS.particles.size.anim.speed = pJS.tmp.obj.size_anim_speed * pJS.canvas.pxratio;
182    pJS.particles.move.speed = pJS.tmp.obj.move_speed * pJS.canvas.pxratio;
183    pJS.particles.line_linked.distance = pJS.tmp.obj.line_linked_distance * pJS.canvas.pxratio;
184    pJS.interactivity.modes.grab.distance = pJS.tmp.obj.mode_grab_distance * pJS.canvas.pxratio;
185    pJS.interactivity.modes.bubble.distance = pJS.tmp.obj.mode_bubble_distance * pJS.canvas.pxratio;
186    pJS.particles.line_linked.width = pJS.tmp.obj.line_linked_width * pJS.canvas.pxratio;
187    pJS.interactivity.modes.bubble.size = pJS.tmp.obj.mode_bubble_size * pJS.canvas.pxratio;
188    pJS.interactivity.modes.repulse.distance = pJS.tmp.obj.mode_repulse_distance * pJS.canvas.pxratio;
189
190  };
191
192
193
194  /* ---------- pJS functions - canvas ------------ */
195
196  pJS.fn.canvasInit = function(){
197    pJS.canvas.ctx = pJS.canvas.el.getContext('2d');
198  };
199
200  pJS.fn.canvasSize = function(){
201
202    pJS.canvas.el.width = pJS.canvas.w;
203    pJS.canvas.el.height = pJS.canvas.h;
204
205    if(pJS && pJS.interactivity.events.resize){
206
207      window.addEventListener('resize', function(){
208
209          pJS.canvas.w = pJS.canvas.el.offsetWidth;
210          pJS.canvas.h = pJS.canvas.el.offsetHeight;
211
212          /* resize canvas */
213          if(pJS.tmp.retina){
214            pJS.canvas.w *= pJS.canvas.pxratio;
215            pJS.canvas.h *= pJS.canvas.pxratio;
216          }
217
218          pJS.canvas.el.width = pJS.canvas.w;
219          pJS.canvas.el.height = pJS.canvas.h;
220
221          /* repaint canvas on anim disabled */
222          if(!pJS.particles.move.enable){
223            pJS.fn.particlesEmpty();
224            pJS.fn.particlesCreate();
225            pJS.fn.particlesDraw();
226            pJS.fn.vendors.densityAutoParticles();
227          }
228
229        /* density particles enabled */
230        pJS.fn.vendors.densityAutoParticles();
231
232      });
233
234    }
235
236  };
237
238
239  pJS.fn.canvasPaint = function(){
240    pJS.canvas.ctx.fillRect(0, 0, pJS.canvas.w, pJS.canvas.h);
241  };
242
243  pJS.fn.canvasClear = function(){
244    pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h);
245  };
246
247
248  /* --------- pJS functions - particles ----------- */
249
250  pJS.fn.particle = function(color, opacity, position){
251
252    /* size */
253    this.radius = (pJS.particles.size.random ? Math.random() : 1) * pJS.particles.size.value;
254    if(pJS.particles.size.anim.enable){
255      this.size_status = false;
256      this.vs = pJS.particles.size.anim.speed / 100;
257      if(!pJS.particles.size.anim.sync){
258        this.vs = this.vs * Math.random();
259      }
260    }
261
262    /* position */
263    this.x = position ? position.x : Math.random() * pJS.canvas.w;
264    this.y = position ? position.y : Math.random() * pJS.canvas.h;
265
266    /* check position  - into the canvas */
267    if(this.x > pJS.canvas.w - this.radius*2) this.x = this.x - this.radius;
268    else if(this.x < this.radius*2) this.x = this.x + this.radius;
269    if(this.y > pJS.canvas.h - this.radius*2) this.y = this.y - this.radius;
270    else if(this.y < this.radius*2) this.y = this.y + this.radius;
271
272    /* check position - avoid overlap */
273    if(pJS.particles.move.bounce){
274      pJS.fn.vendors.checkOverlap(this, position);
275    }
276
277    /* color */
278    this.color = {};
279    if(typeof(color.value) == 'object'){
280
281      if(color.value instanceof Array){
282        var color_selected = color.value[Math.floor(Math.random() * pJS.particles.color.value.length)];
283        this.color.rgb = hexToRgb(color_selected);
284      }else{
285        if(color.value.r != undefined && color.value.g != undefined && color.value.b != undefined){
286          this.color.rgb = {
287            r: color.value.r,
288            g: color.value.g,
289            b: color.value.b
290          }
291        }
292        if(color.value.h != undefined && color.value.s != undefined && color.value.l != undefined){
293          this.color.hsl = {
294            h: color.value.h,
295            s: color.value.s,
296            l: color.value.l
297          }
298        }
299      }
300
301    }
302    else if(color.value == 'random'){
303      this.color.rgb = {
304        r: (Math.floor(Math.random() * (255 - 0 + 1)) + 0),
305        g: (Math.floor(Math.random() * (255 - 0 + 1)) + 0),
306        b: (Math.floor(Math.random() * (255 - 0 + 1)) + 0)
307      }
308    }
309    else if(typeof(color.value) == 'string'){
310      this.color = color;
311      this.color.rgb = hexToRgb(this.color.value);
312    }
313
314    /* opacity */
315    this.opacity = (pJS.particles.opacity.random ? Math.random() : 1) * pJS.particles.opacity.value;
316    if(pJS.particles.opacity.anim.enable){
317      this.opacity_status = false;
318      this.vo = pJS.particles.opacity.anim.speed / 100;
319      if(!pJS.particles.opacity.anim.sync){
320        this.vo = this.vo * Math.random();
321      }
322    }
323
324    /* animation - velocity for speed */
325    var velbase = {}
326    switch(pJS.particles.move.direction){
327      case 'top':
328        velbase = { x:0, y:-1 };
329      break;
330      case 'top-right':
331        velbase = { x:0.5, y:-0.5 };
332      break;
333      case 'right':
334        velbase = { x:1, y:-0 };
335      break;
336      case 'bottom-right':
337        velbase = { x:0.5, y:0.5 };
338      break;
339      case 'bottom':
340        velbase = { x:0, y:1 };
341      break;
342      case 'bottom-left':
343        velbase = { x:-0.5, y:1 };
344      break;
345      case 'left':
346        velbase = { x:-1, y:0 };
347      break;
348      case 'top-left':
349        velbase = { x:-0.5, y:-0.5 };
350      break;
351      default:
352        velbase = { x:0, y:0 };
353      break;
354    }
355
356    if(pJS.particles.move.straight){
357      this.vx = velbase.x;
358      this.vy = velbase.y;
359      if(pJS.particles.move.random){
360        this.vx = this.vx * (Math.random());
361        this.vy = this.vy * (Math.random());
362      }
363    }else{
364      this.vx = velbase.x + Math.random()-0.5;
365      this.vy = velbase.y + Math.random()-0.5;
366    }
367
368    // var theta = 2.0 * Math.PI * Math.random();
369    // this.vx = Math.cos(theta);
370    // this.vy = Math.sin(theta);
371
372    this.vx_i = this.vx;
373    this.vy_i = this.vy;
374
375    
376
377    /* if shape is image */
378
379    var shape_type = pJS.particles.shape.type;
380    if(typeof(shape_type) == 'object'){
381      if(shape_type instanceof Array){
382        var shape_selected = shape_type[Math.floor(Math.random() * shape_type.length)];
383        this.shape = shape_selected;
384      }
385    }else{
386      this.shape = shape_type;
387    }
388
389    if(this.shape == 'image'){
390      var sh = pJS.particles.shape;
391      this.img = {
392        src: sh.image.src,
393        ratio: sh.image.width / sh.image.height
394      }
395      if(!this.img.ratio) this.img.ratio = 1;
396      if(pJS.tmp.img_type == 'svg' && pJS.tmp.source_svg != undefined){
397        pJS.fn.vendors.createSvgImg(this);
398        if(pJS.tmp.pushing){
399          this.img.loaded = false;
400        }
401      }
402    }
403
404    
405
406  };
407
408
409  pJS.fn.particle.prototype.draw = function() {
410
411    var p = this;
412
413    if(p.radius_bubble != undefined){
414      var radius = p.radius_bubble; 
415    }else{
416      var radius = p.radius;
417    }
418
419    if(p.opacity_bubble != undefined){
420      var opacity = p.opacity_bubble;
421    }else{
422      var opacity = p.opacity;
423    }
424
425    if(p.color.rgb){
426      var color_value = 'rgba('+p.color.rgb.r+','+p.color.rgb.g+','+p.color.rgb.b+','+opacity+')';
427    }else{
428      var color_value = 'hsla('+p.color.hsl.h+','+p.color.hsl.s+'%,'+p.color.hsl.l+'%,'+opacity+')';
429    }
430
431    pJS.canvas.ctx.fillStyle = color_value;
432    pJS.canvas.ctx.beginPath();
433
434    switch(p.shape){
435
436      case 'circle':
437        pJS.canvas.ctx.arc(p.x, p.y, radius, 0, Math.PI * 2, false);
438      break;
439
440      case 'edge':
441        pJS.canvas.ctx.rect(p.x-radius, p.y-radius, radius*2, radius*2);
442      break;
443
444      case 'triangle':
445        pJS.fn.vendors.drawShape(pJS.canvas.ctx, p.x-radius, p.y+radius / 1.66, radius*2, 3, 2);
446      break;
447
448      case 'polygon':
449        pJS.fn.vendors.drawShape(
450          pJS.canvas.ctx,
451          p.x - radius / (pJS.particles.shape.polygon.nb_sides/3.5), // startX
452          p.y - radius / (2.66/3.5), // startY
453          radius*2.66 / (pJS.particles.shape.polygon.nb_sides/3), // sideLength
454          pJS.particles.shape.polygon.nb_sides, // sideCountNumerator
455          1 // sideCountDenominator
456        );
457      break;
458
459      case 'star':
460        pJS.fn.vendors.drawShape(
461          pJS.canvas.ctx,
462          p.x - radius*2 / (pJS.particles.shape.polygon.nb_sides/4), // startX
463          p.y - radius / (2*2.66/3.5), // startY
464          radius*2*2.66 / (pJS.particles.shape.polygon.nb_sides/3), // sideLength
465          pJS.particles.shape.polygon.nb_sides, // sideCountNumerator
466          2 // sideCountDenominator
467        );
468      break;
469
470      case 'image':
471
472        function draw(){
473          pJS.canvas.ctx.drawImage(
474            img_obj,
475            p.x-radius,
476            p.y-radius,
477            radius*2,
478            radius*2 / p.img.ratio
479          );
480        }
481
482        if(pJS.tmp.img_type == 'svg'){
483          var img_obj = p.img.obj;
484        }else{
485          var img_obj = pJS.tmp.img_obj;
486        }
487
488        if(img_obj){
489          draw();
490        }
491
492      break;
493
494    }
495
496    pJS.canvas.ctx.closePath();
497
498    if(pJS.particles.shape.stroke.width > 0){
499      pJS.canvas.ctx.strokeStyle = pJS.particles.shape.stroke.color;
500      pJS.canvas.ctx.lineWidth = pJS.particles.shape.stroke.width;
501      pJS.canvas.ctx.stroke();
502    }
503    
504    pJS.canvas.ctx.fill();
505    
506  };
507
508
509  pJS.fn.particlesCreate = function(){
510    for(var i = 0; i < pJS.particles.number.value; i++) {
511      pJS.particles.array.push(new pJS.fn.particle(pJS.particles.color, pJS.particles.opacity.value));
512    }
513  };
514
515  pJS.fn.particlesUpdate = function(){
516
517    for(var i = 0; i < pJS.particles.array.length; i++){
518
519      /* the particle */
520      var p = pJS.particles.array[i];
521
522      // var d = ( dx = pJS.interactivity.mouse.click_pos_x - p.x ) * dx + ( dy = pJS.interactivity.mouse.click_pos_y - p.y ) * dy;
523      // var f = -BANG_SIZE / d;
524      // if ( d < BANG_SIZE ) {
525      //     var t = Math.atan2( dy, dx );
526      //     p.vx = f * Math.cos(t);
527      //     p.vy = f * Math.sin(t);
528      // }
529
530      /* move the particle */
531      if(pJS.particles.move.enable){
532        var ms = pJS.particles.move.speed/2;
533        p.x += p.vx * ms;
534        p.y += p.vy * ms;
535      }
536
537      /* change opacity status */
538      if(pJS.particles.opacity.anim.enable) {
539        if(p.opacity_status == true) {
540          if(p.opacity >= pJS.particles.opacity.value) p.opacity_status = false;
541          p.opacity += p.vo;
542        }else {
543          if(p.opacity <= pJS.particles.opacity.anim.opacity_min) p.opacity_status = true;
544          p.opacity -= p.vo;
545        }
546        if(p.opacity < 0) p.opacity = 0;
547      }
548
549      /* change size */
550      if(pJS.particles.size.anim.enable){
551        if(p.size_status == true){
552          if(p.radius >= pJS.particles.size.value) p.size_status = false;
553          p.radius += p.vs;
554        }else{
555          if(p.radius <= pJS.particles.size.anim.size_min) p.size_status = true;
556          p.radius -= p.vs;
557        }
558        if(p.radius < 0) p.radius = 0;
559      }
560
561      /* change particle position if it is out of canvas */
562      if(pJS.particles.move.out_mode == 'bounce'){
563        var new_pos = {
564          x_left: p.radius,
565          x_right:  pJS.canvas.w,
566          y_top: p.radius,
567          y_bottom: pJS.canvas.h
568        }
569      }else{
570        var new_pos = {
571          x_left: -p.radius,
572          x_right: pJS.canvas.w + p.radius,
573          y_top: -p.radius,
574          y_bottom: pJS.canvas.h + p.radius
575        }
576      }
577
578      if(p.x - p.radius > pJS.canvas.w){
579        p.x = new_pos.x_left;
580        p.y = Math.random() * pJS.canvas.h;
581      }
582      else if(p.x + p.radius < 0){
583        p.x = new_pos.x_right;
584        p.y = Math.random() * pJS.canvas.h;
585      }
586      if(p.y - p.radius > pJS.canvas.h){
587        p.y = new_pos.y_top;
588        p.x = Math.random() * pJS.canvas.w;
589      }
590      else if(p.y + p.radius < 0){
591        p.y = new_pos.y_bottom;
592        p.x = Math.random() * pJS.canvas.w;
593      }
594
595      /* out of canvas modes */
596      switch(pJS.particles.move.out_mode){
597        case 'bounce':
598          if (p.x + p.radius > pJS.canvas.w) p.vx = -p.vx;
599          else if (p.x - p.radius < 0) p.vx = -p.vx;
600          if (p.y + p.radius > pJS.canvas.h) p.vy = -p.vy;
601          else if (p.y - p.radius < 0) p.vy = -p.vy;
602        break;
603      }
604
605      /* events */
606      if(isInArray('grab', pJS.interactivity.events.onhover.mode)){
607        pJS.fn.modes.grabParticle(p);
608      }
609
610      if(isInArray('bubble', pJS.interactivity.events.onhover.mode) || isInArray('bubble', pJS.interactivity.events.onclick.mode)){
611        pJS.fn.modes.bubbleParticle(p);
612      }
613
614      if(isInArray('repulse', pJS.interactivity.events.onhover.mode) || isInArray('repulse', pJS.interactivity.events.onclick.mode)){
615        pJS.fn.modes.repulseParticle(p);
616      }
617
618      /* interaction auto between particles */
619      if(pJS.particles.line_linked.enable || pJS.particles.move.attract.enable){
620        for(var j = i + 1; j < pJS.particles.array.length; j++){
621          var p2 = pJS.particles.array[j];
622
623          /* link particles */
624          if(pJS.particles.line_linked.enable){
625            pJS.fn.interact.linkParticles(p,p2);
626          }
627
628          /* attract particles */
629          if(pJS.particles.move.attract.enable){
630            pJS.fn.interact.attractParticles(p,p2);
631          }
632
633          /* bounce particles */
634          if(pJS.particles.move.bounce){
635            pJS.fn.interact.bounceParticles(p,p2);
636          }
637
638        }
639      }
640
641
642    }
643
644  };
645
646  pJS.fn.particlesDraw = function(){
647
648    /* clear canvas */
649    pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h);
650
651    /* update each particles param */
652    pJS.fn.particlesUpdate();
653
654    /* draw each particle */
655    for(var i = 0; i < pJS.particles.array.length; i++){
656      var p = pJS.particles.array[i];
657      p.draw();
658    }
659
660  };
661
662  pJS.fn.particlesEmpty = function(){
663    pJS.particles.array = [];
664  };
665
666  pJS.fn.particlesRefresh = function(){
667
668    /* init all */
669    cancelRequestAnimFrame(pJS.fn.checkAnimFrame);
670    cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
671    pJS.tmp.source_svg = undefined;
672    pJS.tmp.img_obj = undefined;
673    pJS.tmp.count_svg = 0;
674    pJS.fn.particlesEmpty();
675    pJS.fn.canvasClear();
676    
677    /* restart */
678    pJS.fn.vendors.start();
679
680  };
681
682
683  /* ---------- pJS functions - particles interaction ------------ */
684
685  pJS.fn.interact.linkParticles = function(p1, p2){
686
687    var dx = p1.x - p2.x,
688        dy = p1.y - p2.y,
689        dist = Math.sqrt(dx*dx + dy*dy);
690
691    /* draw a line between p1 and p2 if the distance between them is under the config distance */
692    if(dist <= pJS.particles.line_linked.distance){
693
694      var opacity_line = pJS.particles.line_linked.opacity - (dist / (1/pJS.particles.line_linked.opacity)) / pJS.particles.line_linked.distance;
695
696      if(opacity_line > 0){        
697        
698        /* style */
699        var color_line = pJS.particles.line_linked.color_rgb_line;
700        pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')';
701        pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width;
702        //pJS.canvas.ctx.lineCap = 'round'; /* performance issue */
703        
704        /* path */
705        pJS.canvas.ctx.beginPath();
706        pJS.canvas.ctx.moveTo(p1.x, p1.y);
707        pJS.canvas.ctx.lineTo(p2.x, p2.y);
708        pJS.canvas.ctx.stroke();
709        pJS.canvas.ctx.closePath();
710
711      }
712
713    }
714
715  };
716
717
718  pJS.fn.interact.attractParticles  = function(p1, p2){
719
720    /* condensed particles */
721    var dx = p1.x - p2.x,
722        dy = p1.y - p2.y,
723        dist = Math.sqrt(dx*dx + dy*dy);
724
725    if(dist <= pJS.particles.line_linked.distance){
726
727      var ax = dx/(pJS.particles.move.attract.rotateX*1000),
728          ay = dy/(pJS.particles.move.attract.rotateY*1000);
729
730      p1.vx -= ax;
731      p1.vy -= ay;
732
733      p2.vx += ax;
734      p2.vy += ay;
735
736    }
737    
738
739  }
740
741
742  pJS.fn.interact.bounceParticles = function(p1, p2){
743
744    var dx = p1.x - p2.x,
745        dy = p1.y - p2.y,
746        dist = Math.sqrt(dx*dx + dy*dy),
747        dist_p = p1.radius+p2.radius;
748
749    if(dist <= dist_p){
750      p1.vx = -p1.vx;
751      p1.vy = -p1.vy;
752
753      p2.vx = -p2.vx;
754      p2.vy = -p2.vy;
755    }
756
757  }
758
759
760  /* ---------- pJS functions - modes events ------------ */
761
762  pJS.fn.modes.pushParticles = function(nb, pos){
763
764    pJS.tmp.pushing = true;
765
766    for(var i = 0; i < nb; i++){
767      pJS.particles.array.push(
768        new pJS.fn.particle(
769          pJS.particles.color,
770          pJS.particles.opacity.value,
771          {
772            'x': pos ? pos.pos_x : Math.random() * pJS.canvas.w,
773            'y': pos ? pos.pos_y : Math.random() * pJS.canvas.h
774          }
775        )
776      )
777      if(i == nb-1){
778        if(!pJS.particles.move.enable){
779          pJS.fn.particlesDraw();
780        }
781        pJS.tmp.pushing = false;
782      }
783    }
784
785  };
786
787
788  pJS.fn.modes.removeParticles = function(nb){
789
790    pJS.particles.array.splice(0, nb);
791    if(!pJS.particles.move.enable){
792      pJS.fn.particlesDraw();
793    }
794
795  };
796
797
798  pJS.fn.modes.bubbleParticle = function(p){
799
800    /* on hover event */
801    if(pJS.interactivity.events.onhover.enable && isInArray('bubble', pJS.interactivity.events.onhover.mode)){
802
803      var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
804          dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
805          dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse),
806          ratio = 1 - dist_mouse / pJS.interactivity.modes.bubble.distance;
807
808      function init(){
809        p.opacity_bubble = p.opacity;
810        p.radius_bubble = p.radius;
811      }
812
813      /* mousemove - check ratio */
814      if(dist_mouse <= pJS.interactivity.modes.bubble.distance){
815
816        if(ratio >= 0 && pJS.interactivity.status == 'mousemove'){
817          
818          /* size */
819          if(pJS.interactivity.modes.bubble.size != pJS.particles.size.value){
820
821            if(pJS.interactivity.modes.bubble.size > pJS.particles.size.value){
822              var size = p.radius + (pJS.interactivity.modes.bubble.size*ratio);
823              if(size >= 0){
824                p.radius_bubble = size;
825              }
826            }else{
827              var dif = p.radius - pJS.interactivity.modes.bubble.size,
828                  size = p.radius - (dif*ratio);
829              if(size > 0){
830                p.radius_bubble = size;
831              }else{
832                p.radius_bubble = 0;
833              }
834            }
835
836          }
837
838          /* opacity */
839          if(pJS.interactivity.modes.bubble.opacity != pJS.particles.opacity.value){
840
841            if(pJS.interactivity.modes.bubble.opacity > pJS.particles.opacity.value){
842              var opacity = pJS.interactivity.modes.bubble.opacity*ratio;
843              if(opacity > p.opacity && opacity <= pJS.interactivity.modes.bubble.opacity){
844                p.opacity_bubble = opacity;
845              }
846            }else{
847              var opacity = p.opacity - (pJS.particles.opacity.value-pJS.interactivity.modes.bubble.opacity)*ratio;
848              if(opacity < p.opacity && opacity >= pJS.interactivity.modes.bubble.opacity){
849                p.opacity_bubble = opacity;
850              }
851            }
852
853          }
854
855        }
856
857      }else{
858        init();
859      }
860
861
862      /* mouseleave */
863      if(pJS.interactivity.status == 'mouseleave'){
864        init();
865      }
866    
867    }
868
869    /* on click event */
870    else if(pJS.interactivity.events.onclick.enable && isInArray('bubble', pJS.interactivity.events.onclick.mode)){
871
872
873      if(pJS.tmp.bubble_clicking){
874        var dx_mouse = p.x - pJS.interactivity.mouse.click_pos_x,
875            dy_mouse = p.y - pJS.interactivity.mouse.click_pos_y,
876            dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse),
877            time_spent = (new Date().getTime() - pJS.interactivity.mouse.click_time)/1000;
878
879        if(time_spent > pJS.interactivity.modes.bubble.duration){
880          pJS.tmp.bubble_duration_end = true;
881        }
882
883        if(time_spent > pJS.interactivity.modes.bubble.duration*2){
884          pJS.tmp.bubble_clicking = false;
885          pJS.tmp.bubble_duration_end = false;
886        }
887      }
888
889
890      function process(bubble_param, particles_param, p_obj_bubble, p_obj, id){
891
892        if(bubble_param != particles_param){
893
894          if(!pJS.tmp.bubble_duration_end){
895            if(dist_mouse <= pJS.interactivity.modes.bubble.distance){
896              if(p_obj_bubble != undefined) var obj = p_obj_bubble;
897              else var obj = p_obj;
898              if(obj != bubble_param){
899                var value = p_obj - (time_spent * (p_obj - bubble_param) / pJS.interactivity.modes.bubble.duration);
900                if(id == 'size') p.radius_bubble = value;
901                if(id == 'opacity') p.opacity_bubble = value;
902              }
903            }else{
904              if(id == 'size') p.radius_bubble = undefined;
905              if(id == 'opacity') p.opacity_bubble = undefined;
906            }
907          }else{
908            if(p_obj_bubble != undefined){
909              var value_tmp = p_obj - (time_spent * (p_obj - bubble_param) / pJS.interactivity.modes.bubble.duration),
910                  dif = bubble_param - value_tmp;
911                  value = bubble_param + dif;
912              if(id == 'size') p.radius_bubble = value;
913              if(id == 'opacity') p.opacity_bubble = value;
914            }
915          }
916
917        }
918
919      }
920
921      if(pJS.tmp.bubble_clicking){
922        /* size */
923        process(pJS.interactivity.modes.bubble.size, pJS.particles.size.value, p.radius_bubble, p.radius, 'size');
924        /* opacity */
925        process(pJS.interactivity.modes.bubble.opacity, pJS.particles.opacity.value, p.opacity_bubble, p.opacity, 'opacity');
926      }
927
928    }
929
930  };
931
932
933  pJS.fn.modes.repulseParticle = function(p){
934
935    if(pJS.interactivity.events.onhover.enable && isInArray('repulse', pJS.interactivity.events.onhover.mode) && pJS.interactivity.status == 'mousemove') {
936
937      var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
938          dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
939          dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse);
940
941      var normVec = {x: dx_mouse/dist_mouse, y: dy_mouse/dist_mouse},
942          repulseRadius = pJS.interactivity.modes.repulse.distance,
943          velocity = 100,
944          repulseFactor = clamp((1/repulseRadius)*(-1*Math.pow(dist_mouse/repulseRadius,2)+1)*repulseRadius*velocity, 0, 50);
945      
946      var pos = {
947        x: p.x + normVec.x * repulseFactor,
948        y: p.y + normVec.y * repulseFactor
949      }
950
951      if(pJS.particles.move.out_mode == 'bounce'){
952        if(pos.x - p.radius > 0 && pos.x + p.radius < pJS.canvas.w) p.x = pos.x;
953        if(pos.y - p.radius > 0 && pos.y + p.radius < pJS.canvas.h) p.y = pos.y;
954      }else{
955        p.x = pos.x;
956        p.y = pos.y;
957      }
958    
959    }
960
961
962    else if(pJS.interactivity.events.onclick.enable && isInArray('repulse', pJS.interactivity.events.onclick.mode)) {
963
964      if(!pJS.tmp.repulse_finish){
965        pJS.tmp.repulse_count++;
966        if(pJS.tmp.repulse_count == pJS.particles.array.length){
967          pJS.tmp.repulse_finish = true;
968        }
969      }
970
971      if(pJS.tmp.repulse_clicking){
972
973        var repulseRadius = Math.pow(pJS.interactivity.modes.repulse.distance/6, 3);
974
975        var dx = pJS.interactivity.mouse.click_pos_x - p.x,
976            dy = pJS.interactivity.mouse.click_pos_y - p.y,
977            d = dx*dx + dy*dy;
978
979        var force = -repulseRadius / d * 1;
980
981        function process(){
982
983          var f = Math.atan2(dy,dx);
984          p.vx = force * Math.cos(f);
985          p.vy = force * Math.sin(f);
986
987          if(pJS.particles.move.out_mode == 'bounce'){
988            var pos = {
989              x: p.x + p.vx,
990              y: p.y + p.vy
991            }
992            if (pos.x + p.radius > pJS.canvas.w) p.vx = -p.vx;
993            else if (pos.x - p.radius < 0) p.vx = -p.vx;
994            if (pos.y + p.radius > pJS.canvas.h) p.vy = -p.vy;
995            else if (pos.y - p.radius < 0) p.vy = -p.vy;
996          }
997
998        }
999
1000        // default
1001        if(d <= repulseRadius){
1002          process();
1003        }
1004
1005        // bang - slow motion mode
1006        // if(!pJS.tmp.repulse_finish){
1007        //   if(d <= repulseRadius){
1008        //     process();
1009        //   }
1010        // }else{
1011        //   process();
1012        // }
1013        
1014
1015      }else{
1016
1017        if(pJS.tmp.repulse_clicking == false){
1018
1019          p.vx = p.vx_i;
1020          p.vy = p.vy_i;
1021        
1022        }
1023
1024      }
1025
1026    }
1027
1028  }
1029
1030
1031  pJS.fn.modes.grabParticle = function(p){
1032
1033    if(pJS.interactivity.events.onhover.enable && pJS.interactivity.status == 'mousemove'){
1034
1035      var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
1036          dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
1037          dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse);
1038
1039      /* draw a line between the cursor and the particle if the distance between them is under the config distance */
1040      if(dist_mouse <= pJS.interactivity.modes.grab.distance){
1041
1042        var opacity_line = pJS.interactivity.modes.grab.line_linked.opacity - (dist_mouse / (1/pJS.interactivity.modes.grab.line_linked.opacity)) / pJS.interactivity.modes.grab.distance;
1043
1044        if(opacity_line > 0){
1045
1046          /* style */
1047          var color_line = pJS.particles.line_linked.color_rgb_line;
1048          pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')';
1049          pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width;
1050          //pJS.canvas.ctx.lineCap = 'round'; /* performance issue */
1051          
1052          /* path */
1053          pJS.canvas.ctx.beginPath();
1054          pJS.canvas.ctx.moveTo(p.x, p.y);
1055          pJS.canvas.ctx.lineTo(pJS.interactivity.mouse.pos_x, pJS.interactivity.mouse.pos_y);
1056          pJS.canvas.ctx.stroke();
1057          pJS.canvas.ctx.closePath();
1058
1059        }
1060
1061      }
1062
1063    }
1064
1065  };
1066
1067
1068
1069  /* ---------- pJS functions - vendors ------------ */
1070
1071  pJS.fn.vendors.eventsListeners = function(){
1072
1073    /* events target element */
1074    if(pJS.interactivity.detect_on == 'window'){
1075      pJS.interactivity.el = window;
1076    }else{
1077      pJS.interactivity.el = pJS.canvas.el;
1078    }
1079
1080
1081    /* detect mouse pos - on hover / click event */
1082    if(pJS.interactivity.events.onhover.enable || pJS.interactivity.events.onclick.enable){
1083
1084      /* el on mousemove */
1085      pJS.interactivity.el.addEventListener('mousemove', function(e){
1086
1087        if(pJS.interactivity.el == window){
1088          var pos_x = e.clientX,
1089              pos_y = e.clientY;
1090        }
1091        else{
1092          var pos_x = e.offsetX || e.clientX,
1093              pos_y = e.offsetY || e.clientY;
1094        }
1095
1096        pJS.interactivity.mouse.pos_x = pos_x;
1097        pJS.interactivity.mouse.pos_y = pos_y;
1098
1099        if(pJS.tmp.retina){
1100          pJS.interactivity.mouse.pos_x *= pJS.canvas.pxratio;
1101          pJS.interactivity.mouse.pos_y *= pJS.canvas.pxratio;
1102        }
1103
1104        pJS.interactivity.status = 'mousemove';
1105
1106      });
1107
1108      /* el on onmouseleave */
1109      pJS.interactivity.el.addEventListener('mouseleave', function(e){
1110
1111        pJS.interactivity.mouse.pos_x = null;
1112        pJS.interactivity.mouse.pos_y = null;
1113        pJS.interactivity.status = 'mouseleave';
1114
1115      });
1116
1117    }
1118
1119    /* on click event */
1120    if(pJS.interactivity.events.onclick.enable){
1121
1122      pJS.interactivity.el.addEventListener('click', function(){
1123
1124        pJS.interactivity.mouse.click_pos_x = pJS.interactivity.mouse.pos_x;
1125        pJS.interactivity.mouse.click_pos_y = pJS.interactivity.mouse.pos_y;
1126        pJS.interactivity.mouse.click_time = new Date().getTime();
1127
1128        if(pJS.interactivity.events.onclick.enable){
1129
1130          switch(pJS.interactivity.events.onclick.mode){
1131
1132            case 'push':
1133              if(pJS.particles.move.enable){
1134                pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb, pJS.interactivity.mouse);
1135              }else{
1136                if(pJS.interactivity.modes.push.particles_nb == 1){
1137                  pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb, pJS.interactivity.mouse);
1138                }
1139                else if(pJS.interactivity.modes.push.particles_nb > 1){
1140                  pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb);
1141                }
1142              }
1143            break;
1144
1145            case 'remove':
1146              pJS.fn.modes.removeParticles(pJS.interactivity.modes.remove.particles_nb);
1147            break;
1148
1149            case 'bubble':
1150              pJS.tmp.bubble_clicking = true;
1151            break;
1152
1153            case 'repulse':
1154              pJS.tmp.repulse_clicking = true;
1155              pJS.tmp.repulse_count = 0;
1156              pJS.tmp.repulse_finish = false;
1157              setTimeout(function(){
1158                pJS.tmp.repulse_clicking = false;
1159              }, pJS.interactivity.modes.repulse.duration*1000)
1160            break;
1161
1162          }
1163
1164        }
1165
1166      });
1167        
1168    }
1169
1170
1171  };
1172
1173  pJS.fn.vendors.densityAutoParticles = function(){
1174
1175    if(pJS.particles.number.density.enable){
1176
1177      /* calc area */
1178      var area = pJS.canvas.el.width * pJS.canvas.el.height / 1000;
1179      if(pJS.tmp.retina){
1180        area = area/(pJS.canvas.pxratio*2);
1181      }
1182
1183      /* calc number of particles based on density area */
1184      var nb_particles = area * pJS.particles.number.value / pJS.particles.number.density.value_area;
1185
1186      /* add or remove X particles */
1187      var missing_particles = pJS.particles.array.length - nb_particles;
1188      if(missing_particles < 0) pJS.fn.modes.pushParticles(Math.abs(missing_particles));
1189      else pJS.fn.modes.removeParticles(missing_particles);
1190
1191    }
1192
1193  };
1194
1195
1196  pJS.fn.vendors.checkOverlap = function(p1, position){
1197    for(var i = 0; i < pJS.particles.array.length; i++){
1198      var p2 = pJS.particles.array[i];
1199
1200      var dx = p1.x - p2.x,
1201          dy = p1.y - p2.y,
1202          dist = Math.sqrt(dx*dx + dy*dy);
1203
1204      if(dist <= p1.radius + p2.radius){
1205        p1.x = position ? position.x : Math.random() * pJS.canvas.w;
1206        p1.y = position ? position.y : Math.random() * pJS.canvas.h;
1207        pJS.fn.vendors.checkOverlap(p1);
1208      }
1209    }
1210  };
1211
1212
1213  pJS.fn.vendors.createSvgImg = function(p){
1214
1215    /* set color to svg element */
1216    var svgXml = pJS.tmp.source_svg,
1217        rgbHex = /#([0-9A-F]{3,6})/gi,
1218        coloredSvgXml = svgXml.replace(rgbHex, function (m, r, g, b) {
1219          if(p.color.rgb){
1220            var color_value = 'rgba('+p.color.rgb.r+','+p.color.rgb.g+','+p.color.rgb.b+','+p.opacity+')';
1221          }else{
1222            var color_value = 'hsla('+p.color.hsl.h+','+p.color.hsl.s+'%,'+p.color.hsl.l+'%,'+p.opacity+')';
1223          }
1224          return color_value;
1225        });
1226
1227    /* prepare to create img with colored svg */
1228    var svg = new Blob([coloredSvgXml], {type: 'image/svg+xml;charset=utf-8'}),
1229        DOMURL = window.URL || window.webkitURL || window,
1230        url = DOMURL.createObjectURL(svg);
1231
1232    /* create particle img obj */
1233    var img = new Image();
1234    img.addEventListener('load', function(){
1235      p.img.obj = img;
1236      p.img.loaded = true;
1237      DOMURL.revokeObjectURL(url);
1238      pJS.tmp.count_svg++;
1239    });
1240    img.src = url;
1241
1242  };
1243
1244
1245  pJS.fn.vendors.destroypJS = function(){
1246    cancelAnimationFrame(pJS.fn.drawAnimFrame);
1247    canvas_el.remove();
1248    pJSDom = null;
1249  };
1250
1251
1252  pJS.fn.vendors.drawShape = function(c, startX, startY, sideLength, sideCountNumerator, sideCountDenominator){
1253
1254    // By Programming Thomas - https://programmingthomas.wordpress.com/2013/04/03/n-sided-shapes/
1255    var sideCount = sideCountNumerator * sideCountDenominator;
1256    var decimalSides = sideCountNumerator / sideCountDenominator;
1257    var interiorAngleDegrees = (180 * (decimalSides - 2)) / decimalSides;
1258    var interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180; // convert to radians
1259    c.save();
1260    c.beginPath();
1261    c.translate(startX, startY);
1262    c.moveTo(0,0);
1263    for (var i = 0; i < sideCount; i++) {
1264      c.lineTo(sideLength,0);
1265      c.translate(sideLength,0);
1266      c.rotate(interiorAngle);
1267    }
1268    //c.stroke();
1269    c.fill();
1270    c.restore();
1271
1272  };
1273
1274  pJS.fn.vendors.exportImg = function(){
1275    window.open(pJS.canvas.el.toDataURL('image/png'), '_blank');
1276  };
1277
1278
1279  pJS.fn.vendors.loadImg = function(type){
1280
1281    pJS.tmp.img_error = undefined;
1282
1283    if(pJS.particles.shape.image.src != ''){
1284
1285      if(type == 'svg'){
1286
1287        var xhr = new XMLHttpRequest();
1288        xhr.open('GET', pJS.particles.shape.image.src);
1289        xhr.onreadystatechange = function (data) {
1290          if(xhr.readyState == 4){
1291            if(xhr.status == 200){
1292              pJS.tmp.source_svg = data.currentTarget.response;
1293              pJS.fn.vendors.checkBeforeDraw();
1294            }else{
1295              console.log('Error pJS - Image not found');
1296              pJS.tmp.img_error = true;
1297            }
1298          }
1299        }
1300        xhr.send();
1301
1302      }else{
1303
1304        var img = new Image();
1305        img.addEventListener('load', function(){
1306          pJS.tmp.img_obj = img;
1307          pJS.fn.vendors.checkBeforeDraw();
1308        });
1309        img.src = pJS.particles.shape.image.src;
1310
1311      }
1312
1313    }else{
1314      console.log('Error pJS - No image.src');
1315      pJS.tmp.img_error = true;
1316    }
1317
1318  };
1319
1320
1321  pJS.fn.vendors.draw = function(){
1322
1323    if(pJS.particles.shape.type == 'image'){
1324
1325      if(pJS.tmp.img_type == 'svg'){
1326
1327        if(pJS.tmp.count_svg >= pJS.particles.number.value){
1328          pJS.fn.particlesDraw();
1329          if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
1330          else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
1331        }else{
1332          //console.log('still loading...');
1333          if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
1334        }
1335
1336      }else{
1337
1338        if(pJS.tmp.img_obj != undefined){
1339          pJS.fn.particlesDraw();
1340          if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
1341          else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
1342        }else{
1343          if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
1344        }
1345
1346      }
1347
1348    }else{
1349      pJS.fn.particlesDraw();
1350      if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
1351      else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
1352    }
1353
1354  };
1355
1356
1357  pJS.fn.vendors.checkBeforeDraw = function(){
1358
1359    // if shape is image
1360    if(pJS.particles.shape.type == 'image'){
1361
1362      if(pJS.tmp.img_type == 'svg' && pJS.tmp.source_svg == undefined){
1363        pJS.tmp.checkAnimFrame = requestAnimFrame(check);
1364      }else{
1365        //console.log('images loaded! cancel check');
1366        cancelRequestAnimFrame(pJS.tmp.checkAnimFrame);
1367        if(!pJS.tmp.img_error){
1368          pJS.fn.vendors.init();
1369          pJS.fn.vendors.draw();
1370        }
1371        
1372      }
1373
1374    }else{
1375      pJS.fn.vendors.init();
1376      pJS.fn.vendors.draw();
1377    }
1378
1379  };
1380
1381
1382  pJS.fn.vendors.init = function(){
1383
1384    /* init canvas + particles */
1385    pJS.fn.retinaInit();
1386    pJS.fn.canvasInit();
1387    pJS.fn.canvasSize();
1388    pJS.fn.canvasPaint();
1389    pJS.fn.particlesCreate();
1390    pJS.fn.vendors.densityAutoParticles();
1391
1392    /* particles.line_linked - convert hex colors to rgb */
1393    pJS.particles.line_linked.color_rgb_line = hexToRgb(pJS.particles.line_linked.color);
1394
1395  };
1396
1397
1398  pJS.fn.vendors.start = function(){
1399
1400    if(isInArray('image', pJS.particles.shape.type)){
1401      pJS.tmp.img_type = pJS.particles.shape.image.src.substr(pJS.particles.shape.image.src.length - 3);
1402      pJS.fn.vendors.loadImg(pJS.tmp.img_type);
1403    }else{
1404      pJS.fn.vendors.checkBeforeDraw();
1405    }
1406
1407  };
1408
1409
1410
1411
1412  /* ---------- pJS - start ------------ */
1413
1414
1415  pJS.fn.vendors.eventsListeners();
1416
1417  pJS.fn.vendors.start();
1418  
1419
1420
1421};
1422
1423/* ---------- global functions - vendors ------------ */
1424
1425Object.deepExtend = function(destination, source) {
1426  for (var property in source) {
1427    if (source[property] && source[property].constructor &&
1428     source[property].constructor === Object) {
1429      destination[property] = destination[property] || {};
1430      arguments.callee(destination[property], source[property]);
1431    } else {
1432      destination[property] = source[property];
1433    }
1434  }
1435  return destination;
1436};
1437
1438window.requestAnimFrame = (function(){
1439  return  window.requestAnimationFrame ||
1440    window.webkitRequestAnimationFrame ||
1441    window.mozRequestAnimationFrame    ||
1442    window.oRequestAnimationFrame      ||
1443    window.msRequestAnimationFrame     ||
1444    function(callback){
1445      window.setTimeout(callback, 1000 / 60);
1446    };
1447})();
1448
1449window.cancelRequestAnimFrame = ( function() {
1450  return window.cancelAnimationFrame         ||
1451    window.webkitCancelRequestAnimationFrame ||
1452    window.mozCancelRequestAnimationFrame    ||
1453    window.oCancelRequestAnimationFrame      ||
1454    window.msCancelRequestAnimationFrame     ||
1455    clearTimeout
1456} )();
1457
1458function hexToRgb(hex){
1459  // By Tim Down - http://stackoverflow.com/a/5624139/3493650
1460  // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
1461  var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
1462  hex = hex.replace(shorthandRegex, function(m, r, g, b) {
1463     return r + r + g + g + b + b;
1464  });
1465  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1466  return result ? {
1467      r: parseInt(result[1], 16),
1468      g: parseInt(result[2], 16),
1469      b: parseInt(result[3], 16)
1470  } : null;
1471};
1472
1473function clamp(number, min, max) {
1474  return Math.min(Math.max(number, min), max);
1475};
1476
1477function isInArray(value, array) {
1478  return array.indexOf(value) > -1;
1479}
1480
1481
1482/* ---------- particles.js functions - start ------------ */
1483
1484window.pJSDom = [];
1485
1486window.particlesJS = function(tag_id, params){
1487
1488  //console.log(params);
1489
1490  /* no string id? so it's object params, and set the id with default id */
1491  if(typeof(tag_id) != 'string'){
1492    params = tag_id;
1493    tag_id = 'particles-js';
1494  }
1495
1496  /* no id? set the id to default id */
1497  if(!tag_id){
1498    tag_id = 'particles-js';
1499  }
1500
1501  /* pJS elements */
1502  var pJS_tag = document.getElementById(tag_id),
1503      pJS_canvas_class = 'particles-js-canvas-el',
1504      exist_canvas = pJS_tag.getElementsByClassName(pJS_canvas_class);
1505
1506  /* remove canvas if exists into the pJS target tag */
1507  if(exist_canvas.length){
1508    while(exist_canvas.length > 0){
1509      pJS_tag.removeChild(exist_canvas[0]);
1510    }
1511  }
1512
1513  /* create canvas element */
1514  var canvas_el = document.createElement('canvas');
1515  canvas_el.className = pJS_canvas_class;
1516
1517  /* set size canvas */
1518  canvas_el.style.width = "100%";
1519  canvas_el.style.height = "100%";
1520
1521  /* append canvas */
1522  var canvas = document.getElementById(tag_id).appendChild(canvas_el);
1523
1524  /* launch particle.js */
1525  if(canvas != null){
1526    pJSDom.push(new pJS(tag_id, params));
1527  }
1528
1529};
1530
1531window.particlesJS.load = function(tag_id, path_config_json, callback){
1532
1533  /* load json config */
1534  var xhr = new XMLHttpRequest();
1535  xhr.open('GET', path_config_json);
1536  xhr.onreadystatechange = function (data) {
1537    if(xhr.readyState == 4){
1538      if(xhr.status == 200){
1539        var params = JSON.parse(data.currentTarget.response);
1540        window.particlesJS(tag_id, params);
1541        if(callback) callback();
1542      }else{
1543        console.log('Error pJS - XMLHttpRequest status: '+xhr.status);
1544        console.log('Error pJS - File config not found');
1545      }
1546    }
1547  };
1548  xhr.send();
1549
1550};
1550
1551}

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.