@tsparticles/interaction-external-attract
Advanced tools
Comparing version 3.0.0-alpha.1 to 3.0.0-beta.0
@@ -6,2 +6,50 @@ import { Circle, ExternalInteractorBase, Vector, clamp, getDistances, getEasing, isInArray, mouseMoveEvent, } from "@tsparticles/engine"; | ||
super(container); | ||
this._clickAttract = () => { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
const { attract } = container; | ||
if (!attract.finish) { | ||
if (!attract.count) { | ||
attract.count = 0; | ||
} | ||
attract.count++; | ||
if (attract.count === container.particles.count) { | ||
attract.finish = true; | ||
} | ||
} | ||
if (attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
else if (attract.clicking === false) { | ||
attract.particles = []; | ||
} | ||
return; | ||
}; | ||
this._hoverAttract = () => { | ||
const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius)); | ||
}; | ||
this._processAttract = (position, attractRadius, area) => { | ||
const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { dx, dy, distance } = getDistances(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = clamp(getEasing(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
}; | ||
this._engine = engine; | ||
@@ -30,8 +78,9 @@ if (!container.attract) { | ||
setTimeout(() => { | ||
if (!container.destroyed) { | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
container.attract.clicking = false; | ||
if (container.destroyed) { | ||
return; | ||
} | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
container.attract.clicking = false; | ||
}, attract.duration * 1000); | ||
@@ -52,11 +101,10 @@ }; | ||
if (mouseMoveStatus && hoverEnabled && isInArray("attract", hoverMode)) { | ||
this.hoverAttract(); | ||
this._hoverAttract(); | ||
} | ||
else if (clickEnabled && isInArray("attract", clickMode)) { | ||
this.clickAttract(); | ||
this._clickAttract(); | ||
} | ||
} | ||
isEnabled(particle) { | ||
var _a; | ||
const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events; | ||
const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = (particle?.interactivity ?? options.interactivity).events; | ||
if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) { | ||
@@ -73,3 +121,3 @@ return false; | ||
for (const source of sources) { | ||
options.attract.load(source === null || source === void 0 ? void 0 : source.attract); | ||
options.attract.load(source?.attract); | ||
} | ||
@@ -79,49 +127,2 @@ } | ||
} | ||
clickAttract() { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
if (!container.attract.finish) { | ||
if (!container.attract.count) { | ||
container.attract.count = 0; | ||
} | ||
container.attract.count++; | ||
if (container.attract.count === container.particles.count) { | ||
container.attract.finish = true; | ||
} | ||
} | ||
if (container.attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
else if (container.attract.clicking === false) { | ||
container.attract.particles = []; | ||
} | ||
return; | ||
} | ||
hoverAttract() { | ||
const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
processAttract(position, attractRadius, area) { | ||
const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { dx, dy, distance } = getDistances(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = clamp(getEasing(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
} | ||
} |
import { Attractor } from "./Attractor"; | ||
export async function loadExternalAttractInteraction(engine) { | ||
await engine.addInteractor("externalAttract", (container) => new Attractor(engine, container)); | ||
export async function loadExternalAttractInteraction(engine, refresh = true) { | ||
await engine.addInteractor("externalAttract", (container) => new Attractor(engine, container), refresh); | ||
} | ||
export * from "./Options/Classes/Attract"; | ||
export * from "./Options/Interfaces/IAttract"; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -18,2 +9,50 @@ exports.Attractor = void 0; | ||
super(container); | ||
this._clickAttract = () => { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
const { attract } = container; | ||
if (!attract.finish) { | ||
if (!attract.count) { | ||
attract.count = 0; | ||
} | ||
attract.count++; | ||
if (attract.count === container.particles.count) { | ||
attract.finish = true; | ||
} | ||
} | ||
if (attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
else if (attract.clicking === false) { | ||
attract.particles = []; | ||
} | ||
return; | ||
}; | ||
this._hoverAttract = () => { | ||
const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
}; | ||
this._processAttract = (position, attractRadius, area) => { | ||
const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { dx, dy, distance } = (0, engine_1.getDistances)(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = (0, engine_1.clamp)((0, engine_1.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = engine_1.Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
}; | ||
this._engine = engine; | ||
@@ -42,8 +81,9 @@ if (!container.attract) { | ||
setTimeout(() => { | ||
if (!container.destroyed) { | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
container.attract.clicking = false; | ||
if (container.destroyed) { | ||
return; | ||
} | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
container.attract.clicking = false; | ||
}, attract.duration * 1000); | ||
@@ -61,16 +101,13 @@ }; | ||
} | ||
interact() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const container = this.container, options = container.actualOptions, mouseMoveStatus = container.interactivity.status === engine_1.mouseMoveEvent, events = options.interactivity.events, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, clickEnabled = events.onClick.enable, clickMode = events.onClick.mode; | ||
if (mouseMoveStatus && hoverEnabled && (0, engine_1.isInArray)("attract", hoverMode)) { | ||
this.hoverAttract(); | ||
} | ||
else if (clickEnabled && (0, engine_1.isInArray)("attract", clickMode)) { | ||
this.clickAttract(); | ||
} | ||
}); | ||
async interact() { | ||
const container = this.container, options = container.actualOptions, mouseMoveStatus = container.interactivity.status === engine_1.mouseMoveEvent, events = options.interactivity.events, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, clickEnabled = events.onClick.enable, clickMode = events.onClick.mode; | ||
if (mouseMoveStatus && hoverEnabled && (0, engine_1.isInArray)("attract", hoverMode)) { | ||
this._hoverAttract(); | ||
} | ||
else if (clickEnabled && (0, engine_1.isInArray)("attract", clickMode)) { | ||
this._clickAttract(); | ||
} | ||
} | ||
isEnabled(particle) { | ||
var _a; | ||
const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events; | ||
const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = (particle?.interactivity ?? options.interactivity).events; | ||
if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) { | ||
@@ -87,3 +124,3 @@ return false; | ||
for (const source of sources) { | ||
options.attract.load(source === null || source === void 0 ? void 0 : source.attract); | ||
options.attract.load(source?.attract); | ||
} | ||
@@ -93,50 +130,3 @@ } | ||
} | ||
clickAttract() { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
if (!container.attract.finish) { | ||
if (!container.attract.count) { | ||
container.attract.count = 0; | ||
} | ||
container.attract.count++; | ||
if (container.attract.count === container.particles.count) { | ||
container.attract.finish = true; | ||
} | ||
} | ||
if (container.attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
else if (container.attract.clicking === false) { | ||
container.attract.particles = []; | ||
} | ||
return; | ||
} | ||
hoverAttract() { | ||
const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
processAttract(position, attractRadius, area) { | ||
const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { dx, dy, distance } = (0, engine_1.getDistances)(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = (0, engine_1.clamp)((0, engine_1.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = engine_1.Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
} | ||
} | ||
exports.Attractor = Attractor; |
@@ -16,18 +16,7 @@ "use strict"; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.loadExternalAttractInteraction = void 0; | ||
const Attractor_1 = require("./Attractor"); | ||
function loadExternalAttractInteraction(engine) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield engine.addInteractor("externalAttract", (container) => new Attractor_1.Attractor(engine, container)); | ||
}); | ||
async function loadExternalAttractInteraction(engine, refresh = true) { | ||
await engine.addInteractor("externalAttract", (container) => new Attractor_1.Attractor(engine, container), refresh); | ||
} | ||
@@ -34,0 +23,0 @@ exports.loadExternalAttractInteraction = loadExternalAttractInteraction; |
@@ -6,2 +6,50 @@ import { Circle, ExternalInteractorBase, Vector, clamp, getDistances, getEasing, isInArray, mouseMoveEvent, } from "@tsparticles/engine"; | ||
super(container); | ||
this._clickAttract = () => { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
const { attract } = container; | ||
if (!attract.finish) { | ||
if (!attract.count) { | ||
attract.count = 0; | ||
} | ||
attract.count++; | ||
if (attract.count === container.particles.count) { | ||
attract.finish = true; | ||
} | ||
} | ||
if (attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
else if (attract.clicking === false) { | ||
attract.particles = []; | ||
} | ||
return; | ||
}; | ||
this._hoverAttract = () => { | ||
const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius)); | ||
}; | ||
this._processAttract = (position, attractRadius, area) => { | ||
const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { dx, dy, distance } = getDistances(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = clamp(getEasing(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
}; | ||
this._engine = engine; | ||
@@ -30,8 +78,9 @@ if (!container.attract) { | ||
setTimeout(() => { | ||
if (!container.destroyed) { | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
container.attract.clicking = false; | ||
if (container.destroyed) { | ||
return; | ||
} | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
container.attract.clicking = false; | ||
}, attract.duration * 1000); | ||
@@ -52,11 +101,10 @@ }; | ||
if (mouseMoveStatus && hoverEnabled && isInArray("attract", hoverMode)) { | ||
this.hoverAttract(); | ||
this._hoverAttract(); | ||
} | ||
else if (clickEnabled && isInArray("attract", clickMode)) { | ||
this.clickAttract(); | ||
this._clickAttract(); | ||
} | ||
} | ||
isEnabled(particle) { | ||
var _a; | ||
const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events; | ||
const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = (particle?.interactivity ?? options.interactivity).events; | ||
if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) { | ||
@@ -73,3 +121,3 @@ return false; | ||
for (const source of sources) { | ||
options.attract.load(source === null || source === void 0 ? void 0 : source.attract); | ||
options.attract.load(source?.attract); | ||
} | ||
@@ -79,49 +127,2 @@ } | ||
} | ||
clickAttract() { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
if (!container.attract.finish) { | ||
if (!container.attract.count) { | ||
container.attract.count = 0; | ||
} | ||
container.attract.count++; | ||
if (container.attract.count === container.particles.count) { | ||
container.attract.finish = true; | ||
} | ||
} | ||
if (container.attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
else if (container.attract.clicking === false) { | ||
container.attract.particles = []; | ||
} | ||
return; | ||
} | ||
hoverAttract() { | ||
const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
processAttract(position, attractRadius, area) { | ||
const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { dx, dy, distance } = getDistances(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = clamp(getEasing(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
} | ||
} |
import { Attractor } from "./Attractor"; | ||
export async function loadExternalAttractInteraction(engine) { | ||
await engine.addInteractor("externalAttract", (container) => new Attractor(engine, container)); | ||
export async function loadExternalAttractInteraction(engine, refresh = true) { | ||
await engine.addInteractor("externalAttract", (container) => new Attractor(engine, container), refresh); | ||
} | ||
export * from "./Options/Classes/Attract"; | ||
export * from "./Options/Interfaces/IAttract"; |
{ | ||
"name": "@tsparticles/interaction-external-attract", | ||
"version": "3.0.0-alpha.1", | ||
"version": "3.0.0-beta.0", | ||
"description": "tsParticles attract external interaction", | ||
@@ -76,8 +76,9 @@ "homepage": "https://particles.js.org", | ||
"types": "types/index.d.ts", | ||
"sideEffects": false, | ||
"dependencies": { | ||
"@tsparticles/engine": "^3.0.0-beta.0" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"@tsparticles/engine": "^3.0.0-alpha.1" | ||
} | ||
} | ||
} |
@@ -5,5 +5,5 @@ [](https://particles.js.org) | ||
[](https://www.jsdelivr.com/package/npm/tsparticles-interaction-external-attract) | ||
[](https://www.npmjs.com/package/tsparticles-interaction-external-attract) | ||
[](https://www.npmjs.com/package/tsparticles-interaction-external-attract) [](https://github.com/sponsors/matteobruni) | ||
[](https://www.jsdelivr.com/package/npm/@tsparticles/interaction-external-attract) | ||
[](https://www.npmjs.com/package/@tsparticles/interaction-external-attract) | ||
[](https://www.npmjs.com/package/@tsparticles/interaction-external-attract) [](https://github.com/sponsors/matteobruni) | ||
@@ -31,10 +31,12 @@ [tsParticles](https://github.com/matteobruni/tsparticles) interaction plugin for attract effect around mouse or HTML | ||
```javascript | ||
loadExternalAttractInteraction(tsParticles); | ||
(async () => { | ||
await loadExternalAttractInteraction(tsParticles); | ||
tsParticles.load({ | ||
id: "tsparticles", | ||
options: { | ||
/* options */ | ||
}, | ||
}); | ||
await tsParticles.load({ | ||
id: "tsparticles", | ||
options: { | ||
/* options */ | ||
}, | ||
}); | ||
})(); | ||
``` | ||
@@ -47,3 +49,3 @@ | ||
```shell | ||
$ npm install tsparticles-interaction-external-attract | ||
$ npm install @tsparticles/interaction-external-attract | ||
``` | ||
@@ -54,3 +56,3 @@ | ||
```shell | ||
$ yarn add tsparticles-interaction-external-attract | ||
$ yarn add @tsparticles/interaction-external-attract | ||
``` | ||
@@ -61,6 +63,8 @@ | ||
```javascript | ||
const { tsParticles } = require("tsparticles-engine"); | ||
const { loadExternalAttractInteraction } = require("tsparticles-interaction-external-attract"); | ||
const { tsParticles } = require("@tsparticles/engine"); | ||
const { loadExternalAttractInteraction } = require("@tsparticles/interaction-external-attract"); | ||
loadExternalAttractInteraction(tsParticles); | ||
(async () => { | ||
await loadExternalAttractInteraction(tsParticles); | ||
})(); | ||
``` | ||
@@ -71,6 +75,8 @@ | ||
```javascript | ||
import { tsParticles } from "tsparticles-engine"; | ||
import { loadExternalAttractInteraction } from "tsparticles-interaction-external-attract"; | ||
import { tsParticles } from "@tsparticles/engine"; | ||
import { loadExternalAttractInteraction } from "@tsparticles/interaction-external-attract"; | ||
loadExternalAttractInteraction(tsParticles); | ||
(async () => { | ||
await loadExternalAttractInteraction(tsParticles); | ||
})(); | ||
``` |
@@ -7,3 +7,3 @@ /*! | ||
* How to use? : Check the GitHub README | ||
* v3.0.0-alpha.1 | ||
* v3.0.0-beta.0 | ||
*/ | ||
@@ -95,4 +95,4 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
__webpack_require__.d(__webpack_exports__, { | ||
"Attract": () => (/* reexport */ Attract), | ||
"loadExternalAttractInteraction": () => (/* binding */ loadExternalAttractInteraction) | ||
Attract: () => (/* reexport */ Attract), | ||
loadExternalAttractInteraction: () => (/* binding */ loadExternalAttractInteraction) | ||
}); | ||
@@ -142,2 +142,61 @@ | ||
super(container); | ||
this._clickAttract = () => { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { | ||
particles: [] | ||
}; | ||
} | ||
const { | ||
attract | ||
} = container; | ||
if (!attract.finish) { | ||
if (!attract.count) { | ||
attract.count = 0; | ||
} | ||
attract.count++; | ||
if (attract.count === container.particles.count) { | ||
attract.finish = true; | ||
} | ||
} | ||
if (attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, | ||
attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new engine_root_window_.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} else if (attract.clicking === false) { | ||
attract.particles = []; | ||
} | ||
return; | ||
}; | ||
this._hoverAttract = () => { | ||
const container = this.container, | ||
mousePos = container.interactivity.mouse.position, | ||
attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new engine_root_window_.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
}; | ||
this._processAttract = (position, attractRadius, area) => { | ||
const container = this.container, | ||
attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, p => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { | ||
dx, | ||
dy, | ||
distance | ||
} = (0,engine_root_window_.getDistances)(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = (0,engine_root_window_.clamp)((0,engine_root_window_.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = engine_root_window_.Vector.create(distance === 0 ? velocity : dx / distance * attractFactor, distance === 0 ? velocity : dy / distance * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
}; | ||
this._engine = engine; | ||
@@ -171,10 +230,11 @@ if (!container.attract) { | ||
setTimeout(() => { | ||
if (!container.destroyed) { | ||
if (!container.attract) { | ||
container.attract = { | ||
particles: [] | ||
}; | ||
} | ||
container.attract.clicking = false; | ||
if (container.destroyed) { | ||
return; | ||
} | ||
if (!container.attract) { | ||
container.attract = { | ||
particles: [] | ||
}; | ||
} | ||
container.attract.clicking = false; | ||
}, attract.duration * 1000); | ||
@@ -202,13 +262,12 @@ }; | ||
if (mouseMoveStatus && hoverEnabled && (0,engine_root_window_.isInArray)("attract", hoverMode)) { | ||
this.hoverAttract(); | ||
this._hoverAttract(); | ||
} else if (clickEnabled && (0,engine_root_window_.isInArray)("attract", clickMode)) { | ||
this.clickAttract(); | ||
this._clickAttract(); | ||
} | ||
} | ||
isEnabled(particle) { | ||
var _a; | ||
const container = this.container, | ||
options = container.actualOptions, | ||
mouse = container.interactivity.mouse, | ||
events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events; | ||
events = (particle?.interactivity ?? options.interactivity).events; | ||
if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) { | ||
@@ -226,67 +285,11 @@ return false; | ||
for (const source of sources) { | ||
options.attract.load(source === null || source === void 0 ? void 0 : source.attract); | ||
options.attract.load(source?.attract); | ||
} | ||
} | ||
reset() {} | ||
clickAttract() { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { | ||
particles: [] | ||
}; | ||
} | ||
if (!container.attract.finish) { | ||
if (!container.attract.count) { | ||
container.attract.count = 0; | ||
} | ||
container.attract.count++; | ||
if (container.attract.count === container.particles.count) { | ||
container.attract.finish = true; | ||
} | ||
} | ||
if (container.attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, | ||
attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new engine_root_window_.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} else if (container.attract.clicking === false) { | ||
container.attract.particles = []; | ||
} | ||
return; | ||
} | ||
hoverAttract() { | ||
const container = this.container, | ||
mousePos = container.interactivity.mouse.position, | ||
attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new engine_root_window_.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
processAttract(position, attractRadius, area) { | ||
const container = this.container, | ||
attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, p => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { | ||
dx, | ||
dy, | ||
distance | ||
} = (0,engine_root_window_.getDistances)(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = (0,engine_root_window_.clamp)((0,engine_root_window_.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = engine_root_window_.Vector.create(distance === 0 ? velocity : dx / distance * attractFactor, distance === 0 ? velocity : dy / distance * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
} | ||
} | ||
;// CONCATENATED MODULE: ./dist/browser/index.js | ||
async function loadExternalAttractInteraction(engine) { | ||
await engine.addInteractor("externalAttract", container => new Attractor(engine, container)); | ||
async function loadExternalAttractInteraction(engine, refresh = true) { | ||
await engine.addInteractor("externalAttract", container => new Attractor(engine, container), refresh); | ||
} | ||
@@ -293,0 +296,0 @@ |
/*! For license information please see tsparticles.interaction.external.attract.min.js.LICENSE.txt */ | ||
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],e);else{var a="object"==typeof exports?e(require("@tsparticles/engine")):e(t.window);for(var i in a)("object"==typeof exports?exports:t)[i]=a[i]}}(this,(t=>(()=>{"use strict";var e={533:e=>{e.exports=t}},a={};function i(t){var r=a[t];if(void 0!==r)return r.exports;var c=a[t]={exports:{}};return e[t](c,c.exports,i),c.exports}i.d=(t,e)=>{for(var a in e)i.o(e,a)&&!i.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:e[a]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{i.r(r),i.d(r,{Attract:()=>e,loadExternalAttractInteraction:()=>c});var t=i(533);class e{constructor(){this.distance=200,this.duration=.4,this.easing="ease-out-quad",this.factor=1,this.maxSpeed=50,this.speed=1}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.easing&&(this.easing=t.easing),void 0!==t.factor&&(this.factor=t.factor),void 0!==t.maxSpeed&&(this.maxSpeed=t.maxSpeed),void 0!==t.speed&&(this.speed=t.speed))}}class a extends t.ExternalInteractorBase{constructor(t,e){super(e),this._engine=t,e.attract||(e.attract={particles:[]}),this.handleClickMode=t=>{const a=this.container.actualOptions.interactivity.modes.attract;if(a&&"attract"===t){e.attract||(e.attract={particles:[]}),e.attract.clicking=!0,e.attract.count=0;for(const t of e.attract.particles)this.isEnabled(t)&&t.velocity.setTo(t.initialVelocity);e.attract.particles=[],e.attract.finish=!1,setTimeout((()=>{e.destroyed||(e.attract||(e.attract={particles:[]}),e.attract.clicking=!1)}),1e3*a.duration)}}}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.attract;e&&(t.retina.attractModeDistance=e.distance*t.retina.pixelRatio)}async interact(){const e=this.container,a=e.actualOptions,i=e.interactivity.status===t.mouseMoveEvent,r=a.interactivity.events,c=r.onHover.enable,n=r.onHover.mode,o=r.onClick.enable,s=r.onClick.mode;i&&c&&(0,t.isInArray)("attract",n)?this.hoverAttract():o&&(0,t.isInArray)("attract",s)&&this.clickAttract()}isEnabled(e){var a;const i=this.container,r=i.actualOptions,c=i.interactivity.mouse,n=(null!==(a=null==e?void 0:e.interactivity)&&void 0!==a?a:r.interactivity).events;if(!(c.position&&n.onHover.enable||c.clickPosition&&n.onClick.enable))return!1;const o=n.onHover.mode,s=n.onClick.mode;return(0,t.isInArray)("attract",o)||(0,t.isInArray)("attract",s)}loadModeOptions(t,...a){t.attract||(t.attract=new e);for(const e of a)t.attract.load(null==e?void 0:e.attract)}reset(){}clickAttract(){const e=this.container;if(e.attract||(e.attract={particles:[]}),e.attract.finish||(e.attract.count||(e.attract.count=0),e.attract.count++,e.attract.count===e.particles.count&&(e.attract.finish=!0)),e.attract.clicking){const a=e.interactivity.mouse.clickPosition,i=e.retina.attractModeDistance;if(!i||i<0||!a)return;this.processAttract(a,i,new t.Circle(a.x,a.y,i))}else!1===e.attract.clicking&&(e.attract.particles=[])}hoverAttract(){const e=this.container,a=e.interactivity.mouse.position,i=e.retina.attractModeDistance;!i||i<0||!a||this.processAttract(a,i,new t.Circle(a.x,a.y,i))}processAttract(e,a,i){const r=this.container,c=r.actualOptions.interactivity.modes.attract;if(!c)return;const n=r.particles.quadTree.query(i,(t=>this.isEnabled(t)));for(const i of n){const{dx:r,dy:n,distance:o}=(0,t.getDistances)(i.position,e),s=c.speed*c.factor,d=(0,t.clamp)((0,t.getEasing)(c.easing)(1-o/a)*s,0,c.maxSpeed),l=t.Vector.create(0===o?s:r/o*d,0===o?s:n/o*d);i.position.subFrom(l)}}}async function c(t){await t.addInteractor("externalAttract",(e=>new a(t,e)))}})(),r})())); | ||
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],e);else{var i="object"==typeof exports?e(require("@tsparticles/engine")):e(t.window);for(var a in i)("object"==typeof exports?exports:t)[a]=i[a]}}(this,(t=>(()=>{"use strict";var e={533:e=>{e.exports=t}},i={};function a(t){var r=i[t];if(void 0!==r)return r.exports;var n=i[t]={exports:{}};return e[t](n,n.exports,a),n.exports}a.d=(t,e)=>{for(var i in e)a.o(e,i)&&!a.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},a.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),a.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{a.r(r),a.d(r,{Attract:()=>e,loadExternalAttractInteraction:()=>n});var t=a(533);class e{constructor(){this.distance=200,this.duration=.4,this.easing="ease-out-quad",this.factor=1,this.maxSpeed=50,this.speed=1}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.easing&&(this.easing=t.easing),void 0!==t.factor&&(this.factor=t.factor),void 0!==t.maxSpeed&&(this.maxSpeed=t.maxSpeed),void 0!==t.speed&&(this.speed=t.speed))}}class i extends t.ExternalInteractorBase{constructor(e,i){super(i),this._clickAttract=()=>{const e=this.container;e.attract||(e.attract={particles:[]});const{attract:i}=e;if(i.finish||(i.count||(i.count=0),i.count++,i.count===e.particles.count&&(i.finish=!0)),i.clicking){const i=e.interactivity.mouse.clickPosition,a=e.retina.attractModeDistance;if(!a||a<0||!i)return;this._processAttract(i,a,new t.Circle(i.x,i.y,a))}else!1===i.clicking&&(i.particles=[])},this._hoverAttract=()=>{const e=this.container,i=e.interactivity.mouse.position,a=e.retina.attractModeDistance;!a||a<0||!i||this._processAttract(i,a,new t.Circle(i.x,i.y,a))},this._processAttract=(e,i,a)=>{const r=this.container,n=r.actualOptions.interactivity.modes.attract;if(!n)return;const c=r.particles.quadTree.query(a,(t=>this.isEnabled(t)));for(const a of c){const{dx:r,dy:c,distance:o}=(0,t.getDistances)(a.position,e),s=n.speed*n.factor,d=(0,t.clamp)((0,t.getEasing)(n.easing)(1-o/i)*s,0,n.maxSpeed),l=t.Vector.create(0===o?s:r/o*d,0===o?s:c/o*d);a.position.subFrom(l)}},this._engine=e,i.attract||(i.attract={particles:[]}),this.handleClickMode=t=>{const e=this.container.actualOptions.interactivity.modes.attract;if(e&&"attract"===t){i.attract||(i.attract={particles:[]}),i.attract.clicking=!0,i.attract.count=0;for(const t of i.attract.particles)this.isEnabled(t)&&t.velocity.setTo(t.initialVelocity);i.attract.particles=[],i.attract.finish=!1,setTimeout((()=>{i.destroyed||(i.attract||(i.attract={particles:[]}),i.attract.clicking=!1)}),1e3*e.duration)}}}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.attract;e&&(t.retina.attractModeDistance=e.distance*t.retina.pixelRatio)}async interact(){const e=this.container,i=e.actualOptions,a=e.interactivity.status===t.mouseMoveEvent,r=i.interactivity.events,n=r.onHover.enable,c=r.onHover.mode,o=r.onClick.enable,s=r.onClick.mode;a&&n&&(0,t.isInArray)("attract",c)?this._hoverAttract():o&&(0,t.isInArray)("attract",s)&&this._clickAttract()}isEnabled(e){const i=this.container,a=i.actualOptions,r=i.interactivity.mouse,n=(e?.interactivity??a.interactivity).events;if(!(r.position&&n.onHover.enable||r.clickPosition&&n.onClick.enable))return!1;const c=n.onHover.mode,o=n.onClick.mode;return(0,t.isInArray)("attract",c)||(0,t.isInArray)("attract",o)}loadModeOptions(t,...i){t.attract||(t.attract=new e);for(const e of i)t.attract.load(e?.attract)}reset(){}}async function n(t,e=!0){await t.addInteractor("externalAttract",(e=>new i(t,e)),e)}})(),r})())); |
@@ -1,8 +0,1 @@ | ||
/*! | ||
* Author : Matteo Bruni | ||
* MIT license: https://opensource.org/licenses/MIT | ||
* Demo / Generator : https://particles.js.org/ | ||
* GitHub : https://www.github.com/matteobruni/tsparticles | ||
* How to use? : Check the GitHub README | ||
* v3.0.0-alpha.1 | ||
*/ | ||
/*! tsParticles Attract External Interaction v3.0.0-beta.0 by Matteo Bruni */ |
import type { AttractContainer, AttractMode, IAttractMode } from "./Types"; | ||
import { ExternalInteractorBase } from "@tsparticles/engine"; | ||
import type { Engine, IModes, Modes, Particle, RecursivePartial } from "@tsparticles/engine"; | ||
import { type Engine, ExternalInteractorBase, type IModes, type Modes, type Particle, type RecursivePartial } from "@tsparticles/engine"; | ||
export declare class Attractor extends ExternalInteractorBase<AttractContainer> { | ||
@@ -14,5 +13,5 @@ handleClickMode: (mode: string) => void; | ||
reset(): void; | ||
private clickAttract; | ||
private hoverAttract; | ||
private processAttract; | ||
private readonly _clickAttract; | ||
private readonly _hoverAttract; | ||
private readonly _processAttract; | ||
} |
import type { Engine } from "@tsparticles/engine"; | ||
export declare function loadExternalAttractInteraction(engine: Engine): Promise<void>; | ||
export declare function loadExternalAttractInteraction(engine: Engine, refresh?: boolean): Promise<void>; | ||
export * from "./Options/Classes/Attract"; | ||
export * from "./Options/Interfaces/IAttract"; |
@@ -1,3 +0,2 @@ | ||
import type { EasingTypeAlt, IOptionLoader, RecursivePartial } from "@tsparticles/engine"; | ||
import { EasingType } from "@tsparticles/engine"; | ||
import { EasingType, type EasingTypeAlt, type IOptionLoader, type RecursivePartial } from "@tsparticles/engine"; | ||
import type { IAttract } from "../Interfaces/IAttract"; | ||
@@ -4,0 +3,0 @@ export declare class Attract implements IAttract, IOptionLoader<IAttract> { |
@@ -18,2 +18,50 @@ (function (factory) { | ||
super(container); | ||
this._clickAttract = () => { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
const { attract } = container; | ||
if (!attract.finish) { | ||
if (!attract.count) { | ||
attract.count = 0; | ||
} | ||
attract.count++; | ||
if (attract.count === container.particles.count) { | ||
attract.finish = true; | ||
} | ||
} | ||
if (attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
else if (attract.clicking === false) { | ||
attract.particles = []; | ||
} | ||
return; | ||
}; | ||
this._hoverAttract = () => { | ||
const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this._processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
}; | ||
this._processAttract = (position, attractRadius, area) => { | ||
const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { dx, dy, distance } = (0, engine_1.getDistances)(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = (0, engine_1.clamp)((0, engine_1.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = engine_1.Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
}; | ||
this._engine = engine; | ||
@@ -42,8 +90,9 @@ if (!container.attract) { | ||
setTimeout(() => { | ||
if (!container.destroyed) { | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
container.attract.clicking = false; | ||
if (container.destroyed) { | ||
return; | ||
} | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
container.attract.clicking = false; | ||
}, attract.duration * 1000); | ||
@@ -64,11 +113,10 @@ }; | ||
if (mouseMoveStatus && hoverEnabled && (0, engine_1.isInArray)("attract", hoverMode)) { | ||
this.hoverAttract(); | ||
this._hoverAttract(); | ||
} | ||
else if (clickEnabled && (0, engine_1.isInArray)("attract", clickMode)) { | ||
this.clickAttract(); | ||
this._clickAttract(); | ||
} | ||
} | ||
isEnabled(particle) { | ||
var _a; | ||
const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events; | ||
const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = (particle?.interactivity ?? options.interactivity).events; | ||
if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) { | ||
@@ -85,3 +133,3 @@ return false; | ||
for (const source of sources) { | ||
options.attract.load(source === null || source === void 0 ? void 0 : source.attract); | ||
options.attract.load(source?.attract); | ||
} | ||
@@ -91,51 +139,4 @@ } | ||
} | ||
clickAttract() { | ||
const container = this.container; | ||
if (!container.attract) { | ||
container.attract = { particles: [] }; | ||
} | ||
if (!container.attract.finish) { | ||
if (!container.attract.count) { | ||
container.attract.count = 0; | ||
} | ||
container.attract.count++; | ||
if (container.attract.count === container.particles.count) { | ||
container.attract.finish = true; | ||
} | ||
} | ||
if (container.attract.clicking) { | ||
const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
else if (container.attract.clicking === false) { | ||
container.attract.particles = []; | ||
} | ||
return; | ||
} | ||
hoverAttract() { | ||
const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance; | ||
if (!attractRadius || attractRadius < 0 || !mousePos) { | ||
return; | ||
} | ||
this.processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius)); | ||
} | ||
processAttract(position, attractRadius, area) { | ||
const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract; | ||
if (!attractOptions) { | ||
return; | ||
} | ||
const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); | ||
for (const particle of query) { | ||
const { dx, dy, distance } = (0, engine_1.getDistances)(particle.position, position); | ||
const velocity = attractOptions.speed * attractOptions.factor; | ||
const attractFactor = (0, engine_1.clamp)((0, engine_1.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed); | ||
const normVec = engine_1.Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor); | ||
particle.position.subFrom(normVec); | ||
} | ||
} | ||
} | ||
exports.Attractor = Attractor; | ||
}); |
@@ -28,4 +28,4 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
const Attractor_1 = require("./Attractor"); | ||
async function loadExternalAttractInteraction(engine) { | ||
await engine.addInteractor("externalAttract", (container) => new Attractor_1.Attractor(engine, container)); | ||
async function loadExternalAttractInteraction(engine, refresh = true) { | ||
await engine.addInteractor("externalAttract", (container) => new Attractor_1.Attractor(engine, container), refresh); | ||
} | ||
@@ -32,0 +32,0 @@ exports.loadExternalAttractInteraction = loadExternalAttractInteraction; |
Sorry, the diff of this file is not supported yet
77
335314
1139