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