From a729ca6ff89e1004b7e3ad3379ac0cf8cfff6537 Mon Sep 17 00:00:00 2001 From: Cyril CHAPON Date: Fri, 9 Dec 2022 15:41:37 +0100 Subject: [PATCH] Change count logic to density --- README.md | 17 +++++++++-------- dist/sparticles.esm.js | 9 ++++++--- dist/sparticles.js | 9 ++++++--- dist/sparticles.min.js | 2 +- dist/sparticles.mjs | 9 ++++++--- example/test/test.js | 4 ++-- src/sparticles.js | 10 +++++++--- 7 files changed, 37 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 909812f..151d603 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ running this code in your javascript; ``` @@ -66,7 +66,7 @@ the third step with something like below; ```html ``` @@ -91,7 +91,7 @@ import Sparticles from "sparticles"; 3. Finally initialise with vanillaJS ```js -new Sparticles(node, { count: 100 }, 400); +new Sparticles(node, { density: 100 }, 400); ``` 4. If you're using SvelteJS specifically, then your single-file component @@ -165,7 +165,7 @@ A brief look at all the options, with more details below. option | type | default | description -------------------------------------------|-------------------|-----------------|----------------------------------------------------- **[composition](#composition)** | `String` | `source-over` | canvas globalCompositeOperation value for particles -**[count](#count)** | `Number` | `50` | number of particles on the canvas simultaneously +**[density](#density)** | `Number` | `50` | density of particles on the canvas simultaneously (50 =~ 50 on a 1440 / 600 container) **[speed](#speed)** | `Number` | `10` | default velocity of every particle **[parallax](#parallax)** | `Number` | `1` | speed multiplier effect for larger particles (0 = none) **[direction](#direction)** | `Number` | `180` | default direction of particles in degrees (0 = ↑, 180 = ↓) @@ -203,12 +203,13 @@ other than the default value (`source-over`), and will ultimately degrade perfor Will accept [any of the values that are provided as part of the Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) -## `count` +## `density` - Type: `Number` - Default: `50` - Range: `1 - 10000` -Simply the number of particles drawn to the screen. +Density of particles drawn to the screen. Automatically recalculates particles count. +50 is equivalent to 50 on a 1440 x 660 container. Values over `500` may begin to degrade performance. ## `speed` @@ -531,8 +532,8 @@ of particles based on their device; ```js let myElement = document.getElementById("myDiv"); // PLEASE DON'T PUSH A TON OF ANIMATION ON MOBILES! - let count = (/Mobi|Android/i.test(navigator.userAgent)) ? 100 : 500; - let mySparticles = new Sparticles(myElement, { count: count }, 400); + let density = (/Mobi|Android/i.test(navigator.userAgent)) ? 100 : 500; + let mySparticles = new Sparticles(myElement, { density: density }, 400); ``` # why "Sparticles" ? diff --git a/dist/sparticles.esm.js b/dist/sparticles.esm.js index b26f592..3fcda40 100644 --- a/dist/sparticles.esm.js +++ b/dist/sparticles.esm.js @@ -699,13 +699,14 @@ Sparticle.prototype.renderRotate = function () { } }; +var BASE_RESOLUTION = 1400 * 660; /** * Sparticles Constructor; * Create a , append to the given node, and start the particle effect * @param {HTMLElement} [node=document.body] - element to which canvas is appended to * @param {Object} [options={}] - settings to use for the particle effect * @param {String} [options.composition=source-over] - canvas globalCompositeOperation value for particles - * @param {Number} [options.count=50] - number of particles on the canvas simultaneously + * @param {Number} [options.density=50] - density of particles on the canvas simultaneously. 50 =~ 50 on a 1400 x 660 container * @param {Number} [options.speed=10] - default velocity of every particle * @param {Number} [options.parallax=1] - speed multiplier effect for larger particles (0 = none) * @param {Number} [options.direction=180] - default direction of particles in degrees (0 = ↑, 180 = ↓) @@ -754,7 +755,7 @@ var Sparticles = function Sparticles(node, options, width, height) { randomColor: randomHsl, randomColorCount: 3, composition: "source-over", - count: 50, + density: 50, direction: 180, drift: 1, glow: 0, @@ -890,6 +891,8 @@ var Sparticles = function Sparticles(node, options, width, height) { this.width = width || this.width; this.height = height || this.height; + this.resolution = this.width * this.height; + this.count = Math.ceil(this.resolution / BASE_RESOLUTION * this.settings.density); this.canvas.width = this.width; this.canvas.height = this.height; return this; @@ -904,7 +907,7 @@ var Sparticles = function Sparticles(node, options, width, height) { this.sparticles = []; this.ctx.globalCompositeOperation = this.settings.composition; - for (var i = 0; i < this.settings.count; i++) { + for (var i = 0; i < this.count; i++) { this.sparticles.push(new Sparticle(this, i)); } diff --git a/dist/sparticles.js b/dist/sparticles.js index caf6f99..766f9f5 100644 --- a/dist/sparticles.js +++ b/dist/sparticles.js @@ -702,13 +702,14 @@ var Sparticles = (function () { } }; + var BASE_RESOLUTION = 1400 * 660; /** * Sparticles Constructor; * Create a , append to the given node, and start the particle effect * @param {HTMLElement} [node=document.body] - element to which canvas is appended to * @param {Object} [options={}] - settings to use for the particle effect * @param {String} [options.composition=source-over] - canvas globalCompositeOperation value for particles - * @param {Number} [options.count=50] - number of particles on the canvas simultaneously + * @param {Number} [options.density=50] - density of particles on the canvas simultaneously. 50 =~ 50 on a 1400 x 660 container * @param {Number} [options.speed=10] - default velocity of every particle * @param {Number} [options.parallax=1] - speed multiplier effect for larger particles (0 = none) * @param {Number} [options.direction=180] - default direction of particles in degrees (0 = ↑, 180 = ↓) @@ -757,7 +758,7 @@ var Sparticles = (function () { randomColor: randomHsl, randomColorCount: 3, composition: "source-over", - count: 50, + density: 50, direction: 180, drift: 1, glow: 0, @@ -893,6 +894,8 @@ var Sparticles = (function () { this.width = width || this.width; this.height = height || this.height; + this.resolution = this.width * this.height; + this.count = Math.ceil(this.resolution / BASE_RESOLUTION * this.settings.density); this.canvas.width = this.width; this.canvas.height = this.height; return this; @@ -907,7 +910,7 @@ var Sparticles = (function () { this.sparticles = []; this.ctx.globalCompositeOperation = this.settings.composition; - for (var i = 0; i < this.settings.count; i++) { + for (var i = 0; i < this.count; i++) { this.sparticles.push(new Sparticle(this, i)); } diff --git a/dist/sparticles.min.js b/dist/sparticles.min.js index b0e4205..c5c7519 100644 --- a/dist/sparticles.min.js +++ b/dist/sparticles.min.js @@ -6,4 +6,4 @@ * @website http://sparticlesjs.dev * @repository https://github.com/simeydotme/sparticles.git */ -var Sparticles=function(){"use strict";function t(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(t);e&&(s=s.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,s)}return i}function e(e){for(var s=1;s0&&void 0!==arguments[0]?arguments[0]:function(){},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:60;this.fps=e,this.handler=t;var i=0;this.start=function(){var t=this;if(!this.started){var e=performance.now(),s=1e3/this.fps;i=requestAnimationFrame((function n(r){var h=r-e;i=requestAnimationFrame(n),h>=s-0&&(t.handler(h),e=r-h%s)})),this.started=!0}},this.stop=function(){cancelAnimationFrame(i),this.started=!1}},n=function(t){return[Math.cos(h(t-90)),Math.sin(h(t-90))]},r=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;return Math.max(e,Math.min(i,t))},h=function(t){return t*Math.PI/180},a=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Math.random();return e<=t?i=t:(0!==t||1!==e)&&e>t&&(i=i*(e-t)+t),i},o=function(t){return t[Math.floor(a(0,t.length))]},c=function(){var t=p(a(0,360)),e=p(a(90,100)),i=p(a(45,85));return"hsl(".concat(t,",").concat(e,"%,").concat(i,"%)")},l=function(t){return t>a()},p=function(t){return.5+t|0},g=function(t){return t?(this.canvas=t.canvas,this.settings=t.settings,this.colors=t.colors,this.shapes=t.shapes,this.images=t.images,this.styles=t.styles,this.ctx=t.canvas.getContext("2d"),this.setup(),this.init()):console.warn("Invalid parameters given to Sparticle()",arguments),this};g.prototype.setup=function(){var t=this.settings;this.frame=0,this.frameoffset=p(a(0,360)),this.size=p(a(t.minSize,t.maxSize)),this.da=this.getAlphaDelta(),this.dx=this.getDeltaX(),this.dy=this.getDeltaY(),this.dd=this.getDriftDelta(),this.dr=this.getRotationDelta(),this.color=this.getColor(),this.shape=this.getShape(),this.image=this.getImage(),this.style=this.getStyle(),this.rotation=t.rotate?h(a(0,360)):0,this.vertical=t.direction>150&&t.direction<210||t.direction>330&&t.direction<390||t.direction>-30&&t.direction<30,this.horizontal=t.direction>60&&t.direction<120||t.direction>240&&t.direction<300},g.prototype.init=function(){var t=this.settings,e=this.canvas;this.alpha=0,(t.speed>0||0===t.alphaSpeed)&&(this.alpha=a(t.minAlpha,t.maxAlpha)),t.bounce?(this.px=p(a(2,e.width-this.size-2)),this.py=p(a(2,e.height-this.size-2))):(this.px=p(a(2*-this.size,e.width+this.size)),this.py=p(a(2*-this.size,e.height+this.size)))},g.prototype.reset=function(){this.setup(),this.py<0?this.py=this.canvas.height+2*this.size:this.py>this.canvas.height&&(this.py=0-2*this.size),this.px<0?this.px=this.canvas.width+2*this.size:this.px>this.canvas.width&&(this.px=0-2*this.size)},g.prototype.bounce=function(){this.settings.direction;(this.py<=0||this.py+this.size>=this.canvas.height)&&(this.dy=-this.dy,this.horizontal&&(this.dd=-this.dd)),(this.px<=0||this.px+this.size>=this.canvas.width)&&(this.dx=-this.dx,this.vertical&&(this.dd=-this.dd))},g.prototype.isOffCanvas=function(){var t=0-2*this.size,e=this.canvas.height+2*this.size,i=this.canvas.width+2*this.size;return this.pxi||this.pye},g.prototype.isTouchingEdge=function(){var t=this.canvas.height-this.size,e=this.canvas.width-this.size;return this.px<0||this.px>e||this.py<0||this.py>t},g.prototype.getColor=function(){return"random"===this.settings.color?o(this.colors):Array.isArray(this.settings.color)?o(this.settings.color):this.settings.color},g.prototype.getShape=function(){return"random"===this.settings.shape?o(this.shapes):Array.isArray(this.settings.shape)?o(this.settings.shape):this.settings.shape},g.prototype.getImage=function(){return Array.isArray(this.settings.imageUrl)?o(this.settings.imageUrl):this.settings.imageUrl},g.prototype.getStyle=function(){return o(this.styles)},g.prototype.getDelta=function(){var t=.1*this.settings.speed;return this.settings.speed&&this.settings.parallax?t+this.size*this.settings.parallax/50:t},g.prototype.getDeltaVariance=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=this.settings.speed||10;return t>0?a(-t,t)*e/100:0},g.prototype.getDeltaX=function(){var t=this.getDelta(),e=this.getDeltaVariance(this.settings.xVariance);return n(this.settings.direction)[0]*t+e},g.prototype.getDeltaY=function(){var t=this.getDelta(),e=this.getDeltaVariance(this.settings.yVariance);return n(this.settings.direction)[1]*t+e},g.prototype.getAlphaDelta=function(){var t=this.settings.alphaVariance,e=a(1,t+1);return l(.5)&&(e=-e),e},g.prototype.getDriftDelta=function(){return this.settings.drift?a(this.settings.drift-this.settings.drift/2,this.settings.drift+this.settings.drift/2):0},g.prototype.getRotationDelta=function(){var t=0;return this.settings.rotate&&this.settings.rotation&&(t=h(a(.5,1.5)*this.settings.rotation),l(.5)&&(t=-t)),t},g.prototype.update=function(){return this.frame+=1,this.updatePosition(),this.updateAlpha(),this},g.prototype.updateAlpha=function(){return this.settings.alphaSpeed>0&&(this.settings.twinkle?this.alpha=this.updateTwinkle():this.alpha=this.updateFade()),this.alpha},g.prototype.updateFade=function(){var t=this.da/1e3*this.settings.alphaSpeed*.5,e=this.alpha+t,i=this.da>0&&e>this.settings.maxAlpha,s=this.da<0&&ethis.settings.maxAlpha,s=t=1&&!(arguments[0]instanceof HTMLElement)&&(i=arguments[0],n=arguments[1],r=arguments[2],t=void 0),n&&!r&&(r=n);var h={alphaSpeed:10,alphaVariance:1,bounce:!1,color:"random",randomColor:c,randomColorCount:3,composition:"source-over",count:50,direction:180,drift:1,glow:0,imageUrl:"",maxAlpha:1,maxSize:10,minAlpha:0,minSize:1,parallax:1,rotate:!0,rotation:1,shape:"circle",speed:10,style:"fill",twinkle:!1,xVariance:2,yVariance:2};return this.el=t||document.body,this.settings=e(e({},h),i),this.resizable=!n&&!r,this.width=this.resizable?this.el.clientWidth:n,this.height=this.resizable?this.el.clientHeight:r,this.init=function(){var t=this;return this.sparticles=[],this.colors=this.getColorArray(),this.shapes=this.getShapeArray(),this.styles=this.getStyleArray(),this.imageUrls=this.getImageArray(),this.setupMainCanvas(),this.setupOffscreenCanvasses((function(){t.createSparticles(),t.start()})),window.addEventListener("resize",this),this},this.handleEvent=function(t){var e=this;"resize"===t.type&&(clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout((function(){e.resizable&&(e.width=e.el.clientWidth,e.height=e.el.clientHeight,e.setCanvasSize().resetSparticles())}),200))},this.start=function(){var t=this;return this.loop||(this.loop=new s((function(e){t.drawFrame(e)}))),this.loop.start(),this},this.stop=function(){return this.loop.stop(),this},this.destroy=function(){for(var t in this.stop(),this.el.removeChild(this.canvas),window.removeEventListener("resize",this),this)this.hasOwnProperty(t)&&delete this[t];return this},this.setCanvasSize=function(t,e){return t&&(this.resizable=!1),this.width=t||this.width,this.height=e||this.height,this.canvas.width=this.width,this.canvas.height=this.height,this},this.resetSparticles=this.createSparticles=function(){this.sparticles=[],this.ctx.globalCompositeOperation=this.settings.composition;for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:function(){},i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:60;this.fps=i,this.handler=t;var e=0;this.start=function(){var t=this;if(!this.started){var i=performance.now(),s=1e3/this.fps;e=requestAnimationFrame((function n(r){var h=r-i;e=requestAnimationFrame(n),h>=s-0&&(t.handler(h),i=r-h%s)})),this.started=!0}},this.stop=function(){cancelAnimationFrame(e),this.started=!1}},n=function(t){return[Math.cos(h(t-90)),Math.sin(h(t-90))]},r=function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;return Math.max(i,Math.min(e,t))},h=function(t){return t*Math.PI/180},a=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Math.random();return i<=t?e=t:(0!==t||1!==i)&&i>t&&(e=e*(i-t)+t),e},o=function(t){return t[Math.floor(a(0,t.length))]},c=function(){var t=p(a(0,360)),i=p(a(90,100)),e=p(a(45,85));return"hsl(".concat(t,",").concat(i,"%,").concat(e,"%)")},l=function(t){return t>a()},p=function(t){return.5+t|0},g=function(t){return t?(this.canvas=t.canvas,this.settings=t.settings,this.colors=t.colors,this.shapes=t.shapes,this.images=t.images,this.styles=t.styles,this.ctx=t.canvas.getContext("2d"),this.setup(),this.init()):console.warn("Invalid parameters given to Sparticle()",arguments),this};g.prototype.setup=function(){var t=this.settings;this.frame=0,this.frameoffset=p(a(0,360)),this.size=p(a(t.minSize,t.maxSize)),this.da=this.getAlphaDelta(),this.dx=this.getDeltaX(),this.dy=this.getDeltaY(),this.dd=this.getDriftDelta(),this.dr=this.getRotationDelta(),this.color=this.getColor(),this.shape=this.getShape(),this.image=this.getImage(),this.style=this.getStyle(),this.rotation=t.rotate?h(a(0,360)):0,this.vertical=t.direction>150&&t.direction<210||t.direction>330&&t.direction<390||t.direction>-30&&t.direction<30,this.horizontal=t.direction>60&&t.direction<120||t.direction>240&&t.direction<300},g.prototype.init=function(){var t=this.settings,i=this.canvas;this.alpha=0,(t.speed>0||0===t.alphaSpeed)&&(this.alpha=a(t.minAlpha,t.maxAlpha)),t.bounce?(this.px=p(a(2,i.width-this.size-2)),this.py=p(a(2,i.height-this.size-2))):(this.px=p(a(2*-this.size,i.width+this.size)),this.py=p(a(2*-this.size,i.height+this.size)))},g.prototype.reset=function(){this.setup(),this.py<0?this.py=this.canvas.height+2*this.size:this.py>this.canvas.height&&(this.py=0-2*this.size),this.px<0?this.px=this.canvas.width+2*this.size:this.px>this.canvas.width&&(this.px=0-2*this.size)},g.prototype.bounce=function(){this.settings.direction;(this.py<=0||this.py+this.size>=this.canvas.height)&&(this.dy=-this.dy,this.horizontal&&(this.dd=-this.dd)),(this.px<=0||this.px+this.size>=this.canvas.width)&&(this.dx=-this.dx,this.vertical&&(this.dd=-this.dd))},g.prototype.isOffCanvas=function(){var t=0-2*this.size,i=this.canvas.height+2*this.size,e=this.canvas.width+2*this.size;return this.pxe||this.pyi},g.prototype.isTouchingEdge=function(){var t=this.canvas.height-this.size,i=this.canvas.width-this.size;return this.px<0||this.px>i||this.py<0||this.py>t},g.prototype.getColor=function(){return"random"===this.settings.color?o(this.colors):Array.isArray(this.settings.color)?o(this.settings.color):this.settings.color},g.prototype.getShape=function(){return"random"===this.settings.shape?o(this.shapes):Array.isArray(this.settings.shape)?o(this.settings.shape):this.settings.shape},g.prototype.getImage=function(){return Array.isArray(this.settings.imageUrl)?o(this.settings.imageUrl):this.settings.imageUrl},g.prototype.getStyle=function(){return o(this.styles)},g.prototype.getDelta=function(){var t=.1*this.settings.speed;return this.settings.speed&&this.settings.parallax?t+this.size*this.settings.parallax/50:t},g.prototype.getDeltaVariance=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,i=this.settings.speed||10;return t>0?a(-t,t)*i/100:0},g.prototype.getDeltaX=function(){var t=this.getDelta(),i=this.getDeltaVariance(this.settings.xVariance);return n(this.settings.direction)[0]*t+i},g.prototype.getDeltaY=function(){var t=this.getDelta(),i=this.getDeltaVariance(this.settings.yVariance);return n(this.settings.direction)[1]*t+i},g.prototype.getAlphaDelta=function(){var t=this.settings.alphaVariance,i=a(1,t+1);return l(.5)&&(i=-i),i},g.prototype.getDriftDelta=function(){return this.settings.drift?a(this.settings.drift-this.settings.drift/2,this.settings.drift+this.settings.drift/2):0},g.prototype.getRotationDelta=function(){var t=0;return this.settings.rotate&&this.settings.rotation&&(t=h(a(.5,1.5)*this.settings.rotation),l(.5)&&(t=-t)),t},g.prototype.update=function(){return this.frame+=1,this.updatePosition(),this.updateAlpha(),this},g.prototype.updateAlpha=function(){return this.settings.alphaSpeed>0&&(this.settings.twinkle?this.alpha=this.updateTwinkle():this.alpha=this.updateFade()),this.alpha},g.prototype.updateFade=function(){var t=this.da/1e3*this.settings.alphaSpeed*.5,i=this.alpha+t,e=this.da>0&&i>this.settings.maxAlpha,s=this.da<0&&ithis.settings.maxAlpha,s=t=1&&!(arguments[0]instanceof HTMLElement)&&(e=arguments[0],n=arguments[1],r=arguments[2],t=void 0),n&&!r&&(r=n);var h={alphaSpeed:10,alphaVariance:1,bounce:!1,color:"random",randomColor:c,randomColorCount:3,composition:"source-over",density:50,direction:180,drift:1,glow:0,imageUrl:"",maxAlpha:1,maxSize:10,minAlpha:0,minSize:1,parallax:1,rotate:!0,rotation:1,shape:"circle",speed:10,style:"fill",twinkle:!1,xVariance:2,yVariance:2};return this.el=t||document.body,this.settings=i(i({},h),e),this.resizable=!n&&!r,this.width=this.resizable?this.el.clientWidth:n,this.height=this.resizable?this.el.clientHeight:r,this.init=function(){var t=this;return this.sparticles=[],this.colors=this.getColorArray(),this.shapes=this.getShapeArray(),this.styles=this.getStyleArray(),this.imageUrls=this.getImageArray(),this.setupMainCanvas(),this.setupOffscreenCanvasses((function(){t.createSparticles(),t.start()})),window.addEventListener("resize",this),this},this.handleEvent=function(t){var i=this;"resize"===t.type&&(clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout((function(){i.resizable&&(i.width=i.el.clientWidth,i.height=i.el.clientHeight,i.setCanvasSize().resetSparticles())}),200))},this.start=function(){var t=this;return this.loop||(this.loop=new s((function(i){t.drawFrame(i)}))),this.loop.start(),this},this.stop=function(){return this.loop.stop(),this},this.destroy=function(){for(var t in this.stop(),this.el.removeChild(this.canvas),window.removeEventListener("resize",this),this)this.hasOwnProperty(t)&&delete this[t];return this},this.setCanvasSize=function(t,i){return t&&(this.resizable=!1),this.width=t||this.width,this.height=i||this.height,this.resolution=this.width*this.height,this.count=Math.ceil(this.resolution/924e3*this.settings.density),this.canvas.width=this.width,this.canvas.height=this.height,this},this.resetSparticles=this.createSparticles=function(){this.sparticles=[],this.ctx.globalCompositeOperation=this.settings.composition;for(var t=0;t, append to the given node, and start the particle effect * @param {HTMLElement} [node=document.body] - element to which canvas is appended to * @param {Object} [options={}] - settings to use for the particle effect * @param {String} [options.composition=source-over] - canvas globalCompositeOperation value for particles - * @param {Number} [options.count=50] - number of particles on the canvas simultaneously + * @param {Number} [options.density=50] - density of particles on the canvas simultaneously. 50 =~ 50 on a 1400 x 660 container * @param {Number} [options.speed=10] - default velocity of every particle * @param {Number} [options.parallax=1] - speed multiplier effect for larger particles (0 = none) * @param {Number} [options.direction=180] - default direction of particles in degrees (0 = ↑, 180 = ↓) @@ -754,7 +755,7 @@ var Sparticles = function Sparticles(node, options, width, height) { randomColor: randomHsl, randomColorCount: 3, composition: "source-over", - count: 50, + density: 50, direction: 180, drift: 1, glow: 0, @@ -890,6 +891,8 @@ var Sparticles = function Sparticles(node, options, width, height) { this.width = width || this.width; this.height = height || this.height; + this.resolution = this.width * this.height; + this.count = Math.ceil(this.resolution / BASE_RESOLUTION * this.settings.density); this.canvas.width = this.width; this.canvas.height = this.height; return this; @@ -904,7 +907,7 @@ var Sparticles = function Sparticles(node, options, width, height) { this.sparticles = []; this.ctx.globalCompositeOperation = this.settings.composition; - for (var i = 0; i < this.settings.count; i++) { + for (var i = 0; i < this.count; i++) { this.sparticles.push(new Sparticle(this, i)); } diff --git a/example/test/test.js b/example/test/test.js index 84738ff..2f9e410 100644 --- a/example/test/test.js +++ b/example/test/test.js @@ -17,7 +17,7 @@ let options = { randomColorCount: 7, composition: "source-over", bounce: false, - count: 200, + density: 200, direction: 180, drift: 0, glow: 0, @@ -148,7 +148,7 @@ window.initGui = function() { const gui = new dat.GUI({ load: options }); const part = gui.addFolder("Particles"); part.open(); - part.add(options, "count", 1, 500, 1).onFinishChange(rerender); + part.add(options, "density", 1, 500, 1).onFinishChange(rerender); part.add(options, "shape", shapes).onFinishChange(rerender); part.add(options, "style", styles).onFinishChange(rerender); part.add(options, "rotate").onFinishChange(rerender); diff --git a/src/sparticles.js b/src/sparticles.js index 360b9dc..c066bcf 100644 --- a/src/sparticles.js +++ b/src/sparticles.js @@ -2,13 +2,15 @@ import { AnimationFrame } from "./animationFrame.js"; import { clamp, randomHsl } from "./helpers.js"; import { Sparticle } from "./sparticle.js"; +const BASE_RESOLUTION = 1400 * 660; + /** * Sparticles Constructor; * Create a , append to the given node, and start the particle effect * @param {HTMLElement} [node=document.body] - element to which canvas is appended to * @param {Object} [options={}] - settings to use for the particle effect * @param {String} [options.composition=source-over] - canvas globalCompositeOperation value for particles - * @param {Number} [options.count=50] - number of particles on the canvas simultaneously + * @param {Number} [options.density=50] - density of particles on the canvas simultaneously. 50 =~ 50 on a 1400 x 660 container * @param {Number} [options.speed=10] - default velocity of every particle * @param {Number} [options.parallax=1] - speed multiplier effect for larger particles (0 = none) * @param {Number} [options.direction=180] - default direction of particles in degrees (0 = ↑, 180 = ↓) @@ -54,7 +56,7 @@ const Sparticles = function(node, options, width, height) { randomColor: randomHsl, randomColorCount: 3, composition: "source-over", - count: 50, + density: 50, direction: 180, drift: 1, glow: 0, @@ -175,6 +177,8 @@ const Sparticles = function(node, options, width, height) { } this.width = width || this.width; this.height = height || this.height; + this.resolution = this.width * this.height; + this.count = Math.ceil((this.resolution / BASE_RESOLUTION) * this.settings.density); this.canvas.width = this.width; this.canvas.height = this.height; return this; @@ -187,7 +191,7 @@ const Sparticles = function(node, options, width, height) { this.resetSparticles = this.createSparticles = function() { this.sparticles = []; this.ctx.globalCompositeOperation = this.settings.composition; - for (let i = 0; i < this.settings.count; i++) { + for (let i = 0; i < this.count; i++) { this.sparticles.push(new Sparticle(this, i)); } this.sort();