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.