Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions demo/stencil/www/index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>tsParticles Stencil Demo</title> <script type="module" src="/build/tsparticlesstencildemo.esm.js" data-stencil></script> <script nomodule="" src="/build/tsparticlesstencildemo.js" data-stencil></script> </head> <body> <app-root></app-root> <script>
if ('serviceWorker' in navigator && location.protocol !== 'file:') {
// auto-unregister service worker during dev mode
navigator.serviceWorker.getRegistration().then(function(registration) {
if (registration) {
registration.unregister().then(function() { location.reload() });
}
});
}
</script></body></html>
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>tsParticles Stencil Demo</title> <link rel="modulepreload" href="/build/p-BZoBWLqa.js"><link rel="modulepreload" href="/build/p-ufC1IdP9.js"><script type="module" data-stencil data-resources-url="/build/" data-stencil-namespace="tsparticlesstencildemo">import{p as o,b as n}from"/build/p-BZoBWLqa.js";export{s as setNonce}from"/build/p-BZoBWLqa.js";import{g as r}from"/build/p-DQuL1Twl.js";(()=>{const n=import.meta.url,r={};return""!==n&&(r.resourcesUrl=new URL(".",n).href),o(r)})().then((async o=>(await r(),n([["p-61df7b4b",[[0,"app-root",{engineReady:[32],initError:[32]}],[0,"stencil-particles",{options:[16],url:[1],init:[16]},null,{options:[{onPropsChange:0}],url:[{onPropsChange:0}],init:[{onPropsChange:0}]}]]]],o))));
</script> <script nomodule="" src="/build/tsparticlesstencildemo.js" data-stencil></script> </head> <body> <app-root></app-root> </body></html>
12 changes: 9 additions & 3 deletions engine/src/Core/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,18 @@ export class Engine {
*/
private _initialized = false;

/** The container instances */
/**
* The container instances
* @returns the instances loaded in the engine
*/
get items(): Container[] {
return this._domArray;
}

/** The engine version */
/**
* The engine version
* @returns the version string
*/
get version(): string {
return __VERSION__;
}
Expand All @@ -172,7 +178,7 @@ export class Engine {
*/
/**
* Checks if a plugin version matches the engine version
* @param pluginVersion
* @param pluginVersion - the version to check
*/
checkVersion(pluginVersion: string): void {
if (this.version === pluginVersion) {
Expand Down
51 changes: 37 additions & 14 deletions interactions/external/cannon/src/Cannoner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,16 @@ interface CannonGesture {
* The number of particles and their velocity scale with the drag length.
*
* Options live under `interactivity.modes.cannon`:
* - `spread` — half-angle spread in degrees around the launch angle (default 30)
* - `spread` — half-angle spread in degrees around the launch angle (default 30)
* - `velocityFactor` — multiplier applied to drag length to obtain particle speed (default 10)
* - `particleFactor` — how many particles per pixel of drag (default 0.2)
* - `minParticles` — minimum burst size regardless of drag length (default 5)
* - `maxParticles` — cap for burst size (default 200)
* - `drawVector` — whether to render the aiming line while dragging (default true)
* - `vectorColor` — CSS color for the aiming line (default "#ffffff80")
* - `minParticles` — minimum burst size regardless of drag length (default 5)
* - `maxParticles` — cap for burst size (default 200)
* - `drawVector` — whether to render the aiming line while dragging (default true)
* - `vectorColor` — CSS color for the aiming line (default "#ffffff80")
*/
export class Cannoner extends ExternalInteractorBase<CannonContainer> {
/** @inheritDoc */
/** {@inheritDoc ExternalInteractorBase.maxDistance} */
readonly maxDistance = 0;

private _data?: CannonData;
Expand All @@ -117,18 +117,25 @@ export class Cannoner extends ExternalInteractorBase<CannonContainer> {
private _lastDownPosition: ICoordinates | undefined = undefined;
private _state: CannonState = CannonState.idle;

/** @inheritDoc */
/**
* {@inheritDoc ExternalInteractorBase}
* @param container -
*/
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(container: CannonContainer) {
super(container);
}

/** @inheritDoc */
/**
* {@inheritDoc ExternalInteractorBase.clear}
* @param _particle -
* @param _delta -
*/
clear(_particle: InteractivityParticle, _delta: IDelta): void {
// nothing to clear per-particle
}

/** @inheritDoc */
/** {@inheritDoc ExternalInteractorBase.init} */
init(): void {
const options = this.container.actualOptions.interactivity?.modes.cannon ?? new Cannon();

Expand All @@ -144,7 +151,11 @@ export class Cannoner extends ExternalInteractorBase<CannonContainer> {
};
}

/** @inheritDoc */
/**
* {@inheritDoc ExternalInteractorBase.interact}
* @param interactivityData -
* @param _delta -
*/
interact(interactivityData: IInteractivityData, _delta: IDelta): void {
const mouse = interactivityData.mouse,
mousePos = mouse.position,
Expand Down Expand Up @@ -176,7 +187,11 @@ export class Cannoner extends ExternalInteractorBase<CannonContainer> {
}
}

/** @inheritDoc */
/**
* {@inheritDoc ExternalInteractorBase.isEnabled}
* @param interactivityData -
* @returns -
*/
isEnabled(interactivityData: IInteractivityData): boolean {
const { container } = this,
events = container.actualOptions.interactivity?.events;
Expand All @@ -197,7 +212,11 @@ export class Cannoner extends ExternalInteractorBase<CannonContainer> {
return this._state !== CannonState.idle || interactivityData.mouse.clicking;
}

/** @inheritDoc */
/**
* {@inheritDoc ExternalInteractorBase.loadModeOptions}
* @param options -
* @param sources -
*/
loadModeOptions(
options: Modes & CannonMode,
...sources: RecursivePartial<(IModes & ICannonMode) | undefined>[]
Expand All @@ -209,7 +228,11 @@ export class Cannoner extends ExternalInteractorBase<CannonContainer> {
}
}

/** @inheritDoc */
/**
* {@inheritDoc ExternalInteractorBase.reset}
* @param _interactivityData -
* @param _particle -
*/
reset(_interactivityData: IInteractivityData, _particle: InteractivityParticle): void {
// nothing to reset
}
Expand All @@ -231,7 +254,7 @@ export class Cannoner extends ExternalInteractorBase<CannonContainer> {
pxRatio = this.container.retina.pixelRatio,
dragDist = getDistance(origin, current),
// Clamp to maxDragDistance so visual feedback matches actual force
clampedDist = opts.maxDragDistance > none ? Math.min(dragDist, opts.maxDragDistance * pxRatio) : pxRatio,
clampedDist = opts.maxDragDistance > none ? Math.min(dragDist, opts.maxDragDistance * pxRatio) : dragDist,
clampRatio = dragDist > minDistance ? clampedDist / dragDist : minDistance,
clampedX = origin.x + (current.x - origin.x) * clampRatio,
clampedY = origin.y + (current.y - origin.y) * clampRatio;
Expand Down
6 changes: 5 additions & 1 deletion interactions/external/cannon/src/Options/Classes/Cannon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class Cannon implements ICannon {
this.spread = 30;
this.velocityFactor = 0.5;
this.particleFactor = 0.2;
this.maxDragDistance = 200;
this.maxDragDistance = 0;
this.minParticles = 5;
this.maxParticles = 200;
this.drawVector = true;
Expand Down Expand Up @@ -64,6 +64,10 @@ export class Cannon implements ICannon {
this.maxParticles = data.maxParticles;
}

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

if (data.drawVector !== undefined) {
this.drawVector = data.drawVector;
}
Expand Down
3 changes: 1 addition & 2 deletions interactions/external/cannon/src/index.lazy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
export type { CannonContainer, CannonMode, ICannonMode } from "./Types.js";
import { type Engine } from "@tsparticles/engine/lazy";
import type { InteractivityEngine } from "@tsparticles/plugin-interactivity/lazy";

export type { ICannon } from "./Options/Interfaces/ICannon.js";
export type { CannonContainer, CannonMode, ICannonMode } from "./Types.js";
export { Cannon } from "./Options/Classes/Cannon.js";

declare const __VERSION__: string;
Expand Down
2 changes: 1 addition & 1 deletion interactions/external/cannon/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export type { CannonContainer, CannonMode, ICannonMode } from "./Types.js";
import { type InteractivityEngine, ensureInteractivityPluginLoaded } from "@tsparticles/plugin-interactivity";
export { Cannon } from "./Options/Classes/Cannon.js";
import { Cannoner } from "./Cannoner.js";
import { type Engine } from "@tsparticles/engine";
export type { ICannon } from "./Options/Interfaces/ICannon.js";
export type { CannonContainer, CannonMode, ICannonMode } from "./Types.js";

declare const __VERSION__: string;

Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 0 additions & 25 deletions websites/confetti/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,6 @@
</title>

<link href="https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap" rel="stylesheet" />

<!-- Google Consent Mode v2 defaults — set before GA script loads -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('consent', 'default', {
ad_storage: 'denied',
analytics_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
});
</script>
<script
async
src="https://www.googletagmanager.com/gtag/js?id=G-80MY3TZM79"
id="ga-script"
></script>
<script>
gtag('js', new Date());
gtag('config', 'G-80MY3TZM79', {
send_page_view: false,
});
</script>
</head>
<body>
<svg class="sprite" xmlns="http://www.w3.org/2000/svg">
Expand Down
50 changes: 31 additions & 19 deletions websites/confetti/src/cookie-consent.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,32 +69,44 @@ function initAnalytics() {
return;
}

loadScript(
'google-analytics',
`https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`
);

window.dataLayer = window.dataLayer || [];

window.gtag = function () {
window.dataLayer.push(arguments);
};

const analyticsGranted = consent?.analytics;
const adsGranted = consent?.adsense;
const analyticsGranted = !!consent?.analytics;
const adsGranted = !!consent?.adsense;

// Consent Mode v2 default
// IMPORTANTISSIMO:
// default consent BEFORE loading GA
window.gtag('consent', 'default', {
ad_storage: adsGranted ? 'granted' : 'denied',
analytics_storage: analyticsGranted ? 'granted' : 'denied',
ad_user_data: adsGranted ? 'granted' : 'denied',
ad_personalization: adsGranted ? 'granted' : 'denied',

// cookieless improvements
wait_for_update: 500,
});

loadScript(
'google-analytics',
`https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`
);

window.gtag('js', new Date());

window.gtag('config', GA_MEASUREMENT_ID, {
send_page_view: true,

// cookieless mode
client_storage: analyticsGranted ? 'cookie' : 'none',

// aiuta attribution cookieless
url_passthrough: true,

anonymize_ip: true,
});

analyticsInitialized = true;
Expand All @@ -107,10 +119,6 @@ function initAdSense() {

window.adsbygoogle = window.adsbygoogle || [];

// NPA mode
window.adsbygoogle.requestNonPersonalizedAds =
consent?.adsense || !ADSENSE_NON_PERSONALIZED_ON_REJECT ? 0 : 1;

loadScript(
'adsense-script',
`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${ADSENSE_CLIENT_ID}`,
Expand All @@ -127,24 +135,28 @@ function updateConsentMode(activeConsent) {
return;
}

const analyticsGranted = !!activeConsent.analytics;

window.gtag('consent', 'update', {
ad_storage: activeConsent.adsense ? 'granted' : 'denied',
analytics_storage: activeConsent.analytics ? 'granted' : 'denied',
analytics_storage: analyticsGranted ? 'granted' : 'denied',
ad_user_data: activeConsent.adsense ? 'granted' : 'denied',
ad_personalization: activeConsent.adsense ? 'granted' : 'denied',
});

// switch runtime storage mode
window.gtag('set', {
client_storage: analyticsGranted ? 'cookie' : 'none',
});
}

function applyConsent(activeConsent) {
if (activeConsent.analytics || ANALYTICS_COOKIELESS_ON_REJECT) {
initAnalytics();
}
// analytics ALWAYS initialized
initAnalytics();

updateConsentMode(activeConsent);

if (activeConsent.adsense || ADSENSE_NON_PERSONALIZED_ON_REJECT) {
initAdSense();
}
initAdSense();
}

function closeBanner() {
Expand Down
15 changes: 1 addition & 14 deletions websites/confetti/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,7 @@ const updateShareLinks = function () {
};

const canTrackAnalytics = function () {
const consentApi = window.tsParticlesConfettiConsent;

// fallback nel caso il consent script non sia ancora pronto
if (!consentApi) {
return true;
}

const preferences = consentApi.get?.();

if (!preferences) {
return !!consentApi.allowsCookielessAnalytics;
}

return !!preferences.analytics || !!consentApi.allowsCookielessAnalytics;
return !!window.gtag;
};

const trackShare = function (platform) {
Expand Down
Loading