Skip to content

Commit

Permalink
feat: added option to pause the animation while the element is outsid…
Browse files Browse the repository at this point in the history
…e the viewport
  • Loading branch information
KolCrooks committed Oct 9, 2020
1 parent e9503d0 commit e28a624
Show file tree
Hide file tree
Showing 16 changed files with 87 additions and 39 deletions.
6 changes: 6 additions & 0 deletions core/editor/src/Sections/Options/OptionsEditor.ts
Expand Up @@ -50,6 +50,12 @@ export class OptionsEditor extends EditorBase {
this.group.addProperty("pauseOnBlur", "Pause on Blur", EditorType.boolean).change(async () => {
await particles.refresh();
});

this.group
.addProperty("pauseOnOutsideViewport", "Pause on Outside Viewport", EditorType.boolean)
.change(async () => {
await particles.refresh();
});
}

private addBackground(): void {
Expand Down
43 changes: 22 additions & 21 deletions core/main/markdown/Options.md
@@ -1,28 +1,29 @@
# **_Options_**

| property | option type | example | notes |
| ----------------- | ------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `autoPlay` | `boolean` | `true` / `false` | |
| `background` | `object` | | See Background options {@link IBackground | here} |
| `backgroundMask` | `object` | | See Background Mask options {@link IBackgroundMask | here} |
| `backgroundMode` | `object` | | See Background Mode options {@link IBackgroundMode | here} |
| `detectRetina` | `boolean` | `true` / `false` | Replaces the old `retina_detect` property |
| `fpsLimit` | `number` | `30` | _Defaults to `30`_, replaces the old `fps_limit` property |
| `infection` | `object` | | See Infection options {@link IInfection | here} |
| `interactivity` | `object` | | See Interactivity options {@link IInteractivity | here} |
| `manualParticles` | `array` | | An array of Manual Particles object. See Manual Particles documentation {@link IManualParticle | here} |
| `motion` | `object` | | See Motion options {@link IMotion | here} |
| `particles` | `object` | | See Particles options {@link IParticles | here} |
| `pauseOnBlur` | `boolean` | `true` / `false` | Pauses the animations when the page isn't on foreground |
| `preset` | `string` / `array` | `"basic"`<br /> `[ "basic", "60fps" ]` | You can use this property to load one or more presets for focusing on important properties and not all config. You can find presets on `npm` [here](https://www.npmjs.com/search?q=tsparticles-preset) |
| `themes` | `array` | | It's an array of Theme object, you can see the structure {@link ITheme | here } |
| property | option type | example | notes |
| ------------------------ | ------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `autoPlay` | `boolean` | `true` / `false` | |
| `background` | `object` | | See Background options {@link IBackground | here} |
| `backgroundMask` | `object` | | See Background Mask options {@link IBackgroundMask | here} |
| `backgroundMode` | `object` | | See Background Mode options {@link IBackgroundMode | here} |
| `detectRetina` | `boolean` | `true` / `false` | Replaces the old `retina_detect` property |
| `fpsLimit` | `number` | `30` | _Defaults to `30`_, replaces the old `fps_limit` property |
| `infection` | `object` | | See Infection options {@link IInfection | here} |
| `interactivity` | `object` | | See Interactivity options {@link IInteractivity | here} |
| `manualParticles` | `array` | | An array of Manual Particles object. See Manual Particles documentation {@link IManualParticle | here} |
| `motion` | `object` | | See Motion options {@link IMotion | here} |
| `particles` | `object` | | See Particles options {@link IParticles | here} |
| `pauseOnBlur` | `boolean` | `true` / `false` | Pauses the animations when the page isn't on foreground |
| `pauseOnOutsideViewport` | `boolean` | `true` / `false` | Pauses the animations when the element is out of the viewport |
| `preset` | `string` / `array` | `"basic"`<br /> `[ "basic", "60fps" ]` | You can use this property to load one or more presets for focusing on important properties and not all config. You can find presets on `npm` [here](https://www.npmjs.com/search?q=tsparticles-preset) |
| `themes` | `array` | | It's an array of Theme object, you can see the structure {@link ITheme | here } |

## Plugins

These options are not used by slim bundle

| property | option type | example | notes |
| ------------- | ------------------ | ------- | -------------------------------------------------- |
| `absorbers` | `object` / `array` | | See Absorbers options {@link IAbsorber | here} |
| `emitters` | `object` / `array` | | See Emitter options {@link IEmitter | here} |
| `polygonMask` | `object` | | See Particles options {@link IPolygonMask | here} |
| property | option type | example | notes |
| ------------- | ------------------ | ------- | ----------------------------------------- |
| `absorbers` | `object` / `array` | | See Absorbers options {@link IAbsorber | here} |
| `emitters` | `object` / `array` | | See Emitter options {@link IEmitter | here} |
| `polygonMask` | `object` | | See Particles options {@link IPolygonMask | here} |
4 changes: 4 additions & 0 deletions core/main/schema/options.schema.json
Expand Up @@ -2646,6 +2646,10 @@
"description": "Enables or disabled the animation on window blur",
"type": "boolean"
},
"pauseOnOutsideViewport": {
"description": "Enables or disabled the animation on when the element is outside of the viewport",
"type": "boolean"
},
"preset": {
"anyOf": [
{
Expand Down
25 changes: 25 additions & 0 deletions core/main/src/Core/Container.ts
Expand Up @@ -79,6 +79,8 @@ export class Container {

private readonly eventListeners;

private readonly intersectionObserver;

/**
* This is the core class, create an instance to have a new working particles manager
* @constructor
Expand Down Expand Up @@ -155,6 +157,10 @@ export class Container {

/* ---------- tsParticles - start ------------ */
this.eventListeners = new EventListeners(this);

if (typeof IntersectionObserver !== "undefined" && IntersectionObserver) {
this.intersectionObserver = new window.IntersectionObserver((entries) => this.intersectionManager(entries));
}
}

/**
Expand Down Expand Up @@ -362,6 +368,9 @@ export class Container {
this.particles.clear();
this.canvas.clear();

if (this.interactivity.element instanceof HTMLElement && this.intersectionObserver)
this.intersectionObserver.observe(this.interactivity.element);

for (const [, plugin] of this.plugins) {
if (plugin.stop) {
plugin.stop();
Expand Down Expand Up @@ -402,6 +411,9 @@ export class Container {

this.eventListeners.addListeners();

if (this.interactivity.element instanceof HTMLElement && this.intersectionObserver)
this.intersectionObserver.observe(this.interactivity.element);

for (const [, plugin] of this.plugins) {
if (plugin.startAsync !== undefined) {
await plugin.startAsync();
Expand Down Expand Up @@ -457,4 +469,17 @@ export class Container {
this.density =
(canvas.width * canvas.height) / (densityOptions.factor * pxRatio * pxRatio * densityOptions.area);
}

private intersectionManager(entries: IntersectionObserverEntry[]) {
if (this.options.pauseOnOutsideViewport)
for (const entry of entries) {
if (entry.target === this.interactivity.element) {
if (entry.isIntersecting) {
this.play();
} else {
this.pause();
}
}
}
}
}
6 changes: 6 additions & 0 deletions core/main/src/Options/Classes/Options.ts
Expand Up @@ -61,6 +61,7 @@ export class Options implements IOptions, IOptionLoader<IOptions> {
public motion;
public particles;
public pauseOnBlur;
public pauseOnOutsideViewport;
public preset?: string | string[];
public themes: Theme[];

Expand All @@ -77,6 +78,7 @@ export class Options implements IOptions, IOptionLoader<IOptions> {
this.motion = new Motion();
this.particles = new Particles();
this.pauseOnBlur = true;
this.pauseOnOutsideViewport = true;
this.themes = [];
}

Expand Down Expand Up @@ -119,6 +121,10 @@ export class Options implements IOptions, IOptionLoader<IOptions> {
this.pauseOnBlur = data.pauseOnBlur;
}

if (data.pauseOnOutsideViewport !== undefined) {
this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
}

this.background.load(data.background);
this.backgroundMode.load(data.backgroundMode);
this.backgroundMask.load(data.backgroundMask);
Expand Down
5 changes: 5 additions & 0 deletions core/main/src/Options/Interfaces/IOptions.ts
Expand Up @@ -81,6 +81,11 @@ export interface IOptions {
*/
pauseOnBlur: boolean;

/**
* Enable or disabled the animation if the element is outside the viewport
*/
pauseOnOutsideViewport: boolean;

/**
* This property will be used to add specified presets to the options
*/
Expand Down
3 changes: 3 additions & 0 deletions core/main/tests/Options.ts
Expand Up @@ -154,6 +154,9 @@ describe("Options tests", () => {

/* pause on blur */
expect(options.pauseOnBlur).to.be.true;

/** pause on Element Outside Viewport*/
expect(options.pauseOnOutsideViewport).to.be.true;
});

it("check default preset options", () => {
Expand Down
11 changes: 4 additions & 7 deletions demo/jquery/public/presets/fontawesome.json
Expand Up @@ -134,18 +134,14 @@
"fill": true,
"font": "Font Awesome 5 Brands",
"style": "",
"value": [
"\uf179"
],
"value": ["\uf179"],
"weight": "400"
},
{
"fill": true,
"font": "Font Awesome 5 Free",
"style": "",
"value": [
"\uf5d1"
],
"value": ["\uf5d1"],
"weight": "900"
}
],
Expand Down Expand Up @@ -199,6 +195,7 @@
"enable": false
},
"pauseOnBlur": true,
"pauseOnOutsideViewport": true,
"config_demo": {
"hide_card": false,
"background_color": "#0d47a1",
Expand All @@ -207,4 +204,4 @@
"background_repeat": "no-repeat",
"background_size": "cover"
}
}
}
3 changes: 2 additions & 1 deletion demo/jquery/public/presets/trail.json
Expand Up @@ -111,6 +111,7 @@
},
"retina_detect": true,
"pauseOnBlur": false,
"pauseOnOutsideViewport": true,
"config_demo": {
"hide_card": true,
"background_color": "#0d47a1",
Expand All @@ -119,4 +120,4 @@
"background_repeat": "no-repeat",
"background_size": "cover"
}
}
}
9 changes: 3 additions & 6 deletions demo/main/public/presets/fontawesome.json
Expand Up @@ -133,18 +133,14 @@
"fill": true,
"font": "Font Awesome 5 Brands",
"style": "",
"value": [
"\uf179"
],
"value": ["\uf179"],
"weight": "400"
},
{
"fill": true,
"font": "Font Awesome 5 Free",
"style": "",
"value": [
"\uf5d1"
],
"value": ["\uf5d1"],
"weight": "900"
}
],
Expand Down Expand Up @@ -198,6 +194,7 @@
"enable": false
},
"pauseOnBlur": true,
"pauseOnOutsideViewport": true,
"background": {
"color": "#0d47a1",
"image": "",
Expand Down
1 change: 1 addition & 0 deletions demo/main/public/presets/reactBubbles.json
Expand Up @@ -224,6 +224,7 @@
"enable": false
},
"pauseOnBlur": true,
"pauseOnOutsideViewport": true,
"background": {
"color": "#0d47a1",
"image": "",
Expand Down
6 changes: 2 additions & 4 deletions demo/main/public/presets/reactMultipleImages.json
Expand Up @@ -176,10 +176,7 @@
"fill": true,
"sides": 5
},
"type": [
"image",
"circle"
],
"type": ["image", "circle"],
"custom": {}
},
"size": {
Expand Down Expand Up @@ -245,6 +242,7 @@
"enable": false
},
"pauseOnBlur": true,
"pauseOnOutsideViewport": true,
"background": {
"color": "#0d47a1",
"image": "",
Expand Down
1 change: 1 addition & 0 deletions demo/main/public/presets/reactNightSky.json
Expand Up @@ -224,6 +224,7 @@
"enable": false
},
"pauseOnBlur": true,
"pauseOnOutsideViewport": true,
"background": {
"color": "#0d47a1",
"image": "",
Expand Down
1 change: 1 addition & 0 deletions demo/main/public/presets/reactPolygonMask.json
Expand Up @@ -224,6 +224,7 @@
"enable": false
},
"pauseOnBlur": true,
"pauseOnOutsideViewport": true,
"background": {
"color": "#0d47a1",
"image": "",
Expand Down
1 change: 1 addition & 0 deletions demo/main/public/presets/reactSimple.json
Expand Up @@ -224,6 +224,7 @@
"enable": false
},
"pauseOnBlur": true,
"pauseOnOutsideViewport": true,
"background": {
"color": "#0d47a1",
"image": "",
Expand Down
1 change: 1 addition & 0 deletions demo/main/public/presets/reactSnow.json
Expand Up @@ -224,6 +224,7 @@
"enable": false
},
"pauseOnBlur": true,
"pauseOnOutsideViewport": true,
"background": {
"color": "#0d47a1",
"image": "",
Expand Down

0 comments on commit e28a624

Please sign in to comment.