From bd73cf9f6f6453f1469021c85d0244cfb11d9731 Mon Sep 17 00:00:00 2001 From: Matteo Bruni <176620+matteobruni@users.noreply.github.com> Date: Wed, 13 May 2026 15:28:53 +0200 Subject: [PATCH 1/2] build: simplified some types --- engine/src/Core/CanvasManager.ts | 9 ++--- .../src/Core/Interfaces/IContainerPlugin.ts | 15 ++++---- .../Core/Interfaces/IDrawParticleParams.ts | 3 +- .../src/Core/Interfaces/IParticleUpdater.ts | 3 +- engine/src/Core/Interfaces/IShapeDrawData.ts | 3 +- engine/src/Core/RenderManager.ts | 9 ++--- engine/src/Types/CanvasContextType.ts | 4 -- engine/src/Types/ParticlesCanvasType.ts | 4 -- engine/src/Utils/CanvasUtils.ts | 9 ++--- engine/src/export-types.ts | 2 - interactions/external/connect/src/Utils.ts | 9 ++--- interactions/external/grab/src/Utils.ts | 4 +- interactions/light/src/Utils.ts | 17 ++++----- .../particles/links/src/LinkInstance.ts | 5 +-- plugins/absorbers/src/AbsorberInstance.ts | 3 +- .../absorbers/src/AbsorbersPluginInstance.ts | 3 +- .../src/BackgroundMaskPluginInstance.ts | 5 +-- .../src/Options/Classes/BackgroundMask.ts | 2 +- .../src/Options/Interfaces/IBackgroundMask.ts | 2 +- plugins/blend/src/BlendPluginInstance.ts | 10 ++--- plugins/blend/src/Options/Classes/Blend.ts | 2 +- .../blend/src/Options/Interfaces/IBlend.ts | 2 +- .../path/src/EmittersPathShape.ts | 3 +- plugins/emittersShapes/path/src/utils.ts | 6 +-- .../polygonMask/src/PolygonMaskInstance.ts | 3 +- plugins/polygonMask/src/utils.ts | 5 +-- plugins/zoom/src/ZoomPluginInstance.ts | 6 +-- shapes/cards/src/utils.ts | 38 ++++++------------- shapes/emoji/src/EmojiDrawer.ts | 27 +++---------- shapes/rounded-polygon/src/Utils.ts | 4 +- shapes/rounded-rect/src/Utils.ts | 3 +- shapes/text/src/Utils.ts | 10 +---- updaters/gradient/src/GradientUpdater.ts | 3 +- updaters/orbit/src/Utils.ts | 12 +----- updaters/twinkle/src/TwinkleUpdater.ts | 3 +- utils/canvasUtils/src/Utils.ts | 7 ++-- utils/noiseField/src/NoiseFieldGenerator.ts | 13 +------ utils/pathUtils/src/Utils.ts | 3 +- 38 files changed, 92 insertions(+), 179 deletions(-) delete mode 100644 engine/src/Types/CanvasContextType.ts delete mode 100644 engine/src/Types/ParticlesCanvasType.ts diff --git a/engine/src/Core/CanvasManager.ts b/engine/src/Core/CanvasManager.ts index e75cd09eda8..02fb4a5a263 100644 --- a/engine/src/Core/CanvasManager.ts +++ b/engine/src/Core/CanvasManager.ts @@ -5,7 +5,6 @@ import type { Container } from "./Container.js"; import type { IContainerPlugin } from "./Interfaces/IContainerPlugin.js"; import type { ICoordinates } from "./Interfaces/ICoordinates.js"; import type { IDimension } from "./Interfaces/IDimension.js"; -import type { ParticlesCanvasType } from "../Types/ParticlesCanvasType.js"; import type { PluginManager } from "./Utils/PluginManager.js"; import { RenderManager } from "./RenderManager.js"; @@ -40,7 +39,7 @@ const transferredCanvases = new WeakMap(), throw new TypeError("OffscreenCanvas transfer failed"); } }, - isHtmlCanvasElement = (canvas: ParticlesCanvasType): canvas is HTMLCanvasElement => { + isHtmlCanvasElement = (canvas: HTMLCanvasElement | OffscreenCanvas): canvas is HTMLCanvasElement => { return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement; }; @@ -106,7 +105,7 @@ export class CanvasManager { * The canvas used for rendering and as source for the 2D context. * This is an OffscreenCanvas when a DOM canvas is provided. */ - renderCanvas?: ParticlesCanvasType; + renderCanvas?: OffscreenCanvas; /** * The particles canvas dimension @@ -280,7 +279,7 @@ export class CanvasManager { * Loads the canvas HTML element * @param canvas - the canvas source element or OffscreenCanvas */ - loadCanvas(canvas: ParticlesCanvasType): void { + loadCanvas(canvas: HTMLCanvasElement | OffscreenCanvas): void { if (this._generated && this.domElement) { this.domElement.remove(); } @@ -290,7 +289,7 @@ export class CanvasManager { this.domElement = domCanvas; this._generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false; - this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas; + this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : (canvas as OffscreenCanvas); const domElement = this.domElement; diff --git a/engine/src/Core/Interfaces/IContainerPlugin.ts b/engine/src/Core/Interfaces/IContainerPlugin.ts index cd68ce3f884..068a74325cb 100644 --- a/engine/src/Core/Interfaces/IContainerPlugin.ts +++ b/engine/src/Core/Interfaces/IContainerPlugin.ts @@ -1,4 +1,3 @@ -import type { CanvasContextType } from "../../Types/CanvasContextType.js"; import type { ExportResult } from "../../Types/ExportResult.js"; import type { ICoordinates } from "./ICoordinates.js"; import type { IDelta } from "./IDelta.js"; @@ -16,25 +15,25 @@ export interface IContainerPlugin { /** Checks if a particle position is valid, with retry count */ checkParticlePosition?: (particle: Particle, position: ICoordinates, tryCount: number) => boolean; /** Clears plugin-specific drawings from the canvas */ - clearDraw?: (context: CanvasContextType, delta: IDelta) => void; + clearDraw?: (context: OffscreenCanvasRenderingContext2D, delta: IDelta) => void; /** Validates a click position */ clickPositionValid?: (position: ICoordinates) => boolean; /** Cleans up plugin resources */ destroy?: () => void; /** Draws plugin content on the canvas */ - draw?: (context: CanvasContextType, delta: IDelta) => void; + draw?: (context: OffscreenCanvasRenderingContext2D, delta: IDelta) => void; /** Draws a particle managed by the plugin */ - drawParticle?: (context: CanvasContextType, particle: Particle, delta: IDelta) => void; + drawParticle?: (context: OffscreenCanvasRenderingContext2D, particle: Particle, delta: IDelta) => void; /** Cleanup after drawing a particle */ - drawParticleCleanup?: (context: CanvasContextType, particle: Particle, delta: IDelta) => void; + drawParticleCleanup?: (context: OffscreenCanvasRenderingContext2D, particle: Particle, delta: IDelta) => void; /** Setup before drawing a particle */ - drawParticleSetup?: (context: CanvasContextType, particle: Particle, delta: IDelta) => void; + drawParticleSetup?: (context: OffscreenCanvasRenderingContext2D, particle: Particle, delta: IDelta) => void; /** Applies canvas transform before drawing a particle */ drawParticleTransform?: (data: IShapeDrawData) => void; /** Cleanup after drawing settings */ - drawSettingsCleanup?: (context: CanvasContextType, delta: IDelta) => void; + drawSettingsCleanup?: (context: OffscreenCanvasRenderingContext2D, delta: IDelta) => void; /** Setup before drawing settings */ - drawSettingsSetup?: (context: CanvasContextType, delta: IDelta) => void; + drawSettingsSetup?: (context: OffscreenCanvasRenderingContext2D, delta: IDelta) => void; /** Exports the container content */ export?: (type: string, data: Record) => Promise; /** Initializes the plugin */ diff --git a/engine/src/Core/Interfaces/IDrawParticleParams.ts b/engine/src/Core/Interfaces/IDrawParticleParams.ts index 3db5557ffa9..575e3c7a043 100644 --- a/engine/src/Core/Interfaces/IDrawParticleParams.ts +++ b/engine/src/Core/Interfaces/IDrawParticleParams.ts @@ -1,4 +1,3 @@ -import type { CanvasContextType } from "../../Types/CanvasContextType.js"; import type { Container } from "../Container.js"; import type { IDelta } from "./IDelta.js"; import type { IParticleColorStyle } from "./IParticleColorStyle.js"; @@ -20,7 +19,7 @@ export interface IDrawParticleParams { /** * The canvas context to draw on */ - context: CanvasContextType; + context: OffscreenCanvasRenderingContext2D; /** * This variable contains the delta between the current frame and the previous frame */ diff --git a/engine/src/Core/Interfaces/IParticleUpdater.ts b/engine/src/Core/Interfaces/IParticleUpdater.ts index 2d6c767a914..c2da2ed48f5 100644 --- a/engine/src/Core/Interfaces/IParticleUpdater.ts +++ b/engine/src/Core/Interfaces/IParticleUpdater.ts @@ -1,4 +1,3 @@ -import type { CanvasContextType } from "../../Types/CanvasContextType.js"; import type { IDelta } from "./IDelta.js"; import type { IParticleColorStyle } from "./IParticleColorStyle.js"; import type { IParticleTransformValues } from "./IParticleTransformValues.js"; @@ -18,7 +17,7 @@ export interface IParticleUpdater { /** Returns custom color styles for a particle */ getColorStyles?: ( particle: Particle, - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, radius: number, opacity: number, ) => IParticleColorStyle; diff --git a/engine/src/Core/Interfaces/IShapeDrawData.ts b/engine/src/Core/Interfaces/IShapeDrawData.ts index cee5dec5938..8d57131e39f 100644 --- a/engine/src/Core/Interfaces/IShapeDrawData.ts +++ b/engine/src/Core/Interfaces/IShapeDrawData.ts @@ -1,4 +1,3 @@ -import type { CanvasContextType } from "../../Types/CanvasContextType.js"; import type { ICoordinates } from "./ICoordinates.js"; import type { IDelta } from "./IDelta.js"; import type { Particle } from "../Particle.js"; @@ -10,7 +9,7 @@ export interface IShapeDrawData { /** * the canvas context for drawing */ - context: CanvasContextType; + context: OffscreenCanvasRenderingContext2D; /** * this variable contains the delta between the current frame and the previous frame diff --git a/engine/src/Core/RenderManager.ts b/engine/src/Core/RenderManager.ts index 9090aad3866..615d328099e 100644 --- a/engine/src/Core/RenderManager.ts +++ b/engine/src/Core/RenderManager.ts @@ -1,7 +1,6 @@ import { clear, drawParticle, drawParticlePlugin, paintBase, paintImage } from "../Utils/CanvasUtils.js"; import { defaultCompositeValue, defaultTransformValue, minimumSize, zIndexFactorOffset } from "./Utils/Constants.js"; import { getStyleFromHsl, rangeColorToHsl } from "../Utils/ColorUtils.js"; -import type { CanvasContextType } from "../Types/CanvasContextType.js"; import type { CanvasManager } from "./CanvasManager.js"; import type { Container } from "./Container.js"; import type { IContainerPlugin } from "./Interfaces/IContainerPlugin.js"; @@ -46,7 +45,7 @@ export class RenderManager { /** * The particles canvas context */ - private _context: CanvasContextType | null; + private _context: OffscreenCanvasRenderingContext2D | null; private _contextSettings?: CanvasRenderingContext2DSettings; private _drawParticlePlugins: IContainerPlugin[]; private _drawParticlesCleanupPlugins: IContainerPlugin[]; @@ -148,7 +147,7 @@ export class RenderManager { * @param cb - * @returns the result of the callback */ - draw(cb: (context: CanvasContextType) => T): T | undefined { + draw(cb: (context: OffscreenCanvasRenderingContext2D) => T): T | undefined { const ctx = this._context; if (!ctx) { @@ -403,7 +402,7 @@ export class RenderManager { * Sets the canvas rendering context * @param context */ - setContext(context: CanvasContextType | null): void { + setContext(context: OffscreenCanvasRenderingContext2D | null): void { this._context = context; if (this._context) { @@ -433,7 +432,7 @@ export class RenderManager { }; private readonly _applyPreDrawUpdaters: ( - ctx: CanvasContextType, + ctx: OffscreenCanvasRenderingContext2D, particle: Particle, radius: number, zOpacity: number, diff --git a/engine/src/Types/CanvasContextType.ts b/engine/src/Types/CanvasContextType.ts deleted file mode 100644 index 86adc71aff7..00000000000 --- a/engine/src/Types/CanvasContextType.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Supported canvas rendering contexts. - */ -export type CanvasContextType = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; diff --git a/engine/src/Types/ParticlesCanvasType.ts b/engine/src/Types/ParticlesCanvasType.ts deleted file mode 100644 index b608360fe56..00000000000 --- a/engine/src/Types/ParticlesCanvasType.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Supported canvas elements. - */ -export type ParticlesCanvasType = HTMLCanvasElement | OffscreenCanvas; diff --git a/engine/src/Utils/CanvasUtils.ts b/engine/src/Utils/CanvasUtils.ts index 3565bd32a56..6ba04477e94 100644 --- a/engine/src/Utils/CanvasUtils.ts +++ b/engine/src/Utils/CanvasUtils.ts @@ -1,5 +1,4 @@ import { defaultZoom, minStrokeWidth, originPoint } from "../Core/Utils/Constants.js"; -import type { CanvasContextType } from "../Types/CanvasContextType.js"; import type { IContainerPlugin } from "../Core/Interfaces/IContainerPlugin.js"; import type { IDelta } from "../Core/Interfaces/IDelta.js"; import type { IDimension } from "../Core/Interfaces/IDimension.js"; @@ -15,7 +14,7 @@ import type { Particle } from "../Core/Particle.js"; * @param dimension - The dimension of the rectangle. * @param baseColor - The base color of the rectangle, if not specified a transparent color will be used. */ -export function paintBase(context: CanvasContextType, dimension: IDimension, baseColor?: string): void { +export function paintBase(context: OffscreenCanvasRenderingContext2D, dimension: IDimension, baseColor?: string): void { context.fillStyle = baseColor ?? "rgba(0,0,0,0)"; context.fillRect(originPoint.x, originPoint.y, dimension.width, dimension.height); @@ -29,7 +28,7 @@ export function paintBase(context: CanvasContextType, dimension: IDimension, bas * @param opacity - The opacity of the image. */ export function paintImage( - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, dimension: IDimension, image: HTMLImageElement | undefined, opacity: number, @@ -52,7 +51,7 @@ export function paintImage( * @param context - The canvas context to clear. * @param dimension - The dimension of the canvas. */ -export function clear(context: CanvasContextType, dimension: IDimension): void { +export function clear(context: OffscreenCanvasRenderingContext2D, dimension: IDimension): void { context.clearRect(originPoint.x, originPoint.y, dimension.width, dimension.height); } @@ -235,7 +234,7 @@ export function drawShapeBeforeDraw(drawer: IShapeDrawer | undefined, data: ISha * @param delta - this variable contains the delta between the current frame and the previous frame */ export function drawParticlePlugin( - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, plugin: IContainerPlugin, particle: Particle, delta: IDelta, diff --git a/engine/src/export-types.ts b/engine/src/export-types.ts index 02aed2d91d1..d322df04e49 100644 --- a/engine/src/export-types.ts +++ b/engine/src/export-types.ts @@ -74,8 +74,6 @@ export type * from "./Options/Interfaces/Particles/Size/ISizeAnimation.js"; export type * from "./Options/Interfaces/Particles/ZIndex/IZIndex.js"; -export type * from "./Types/CanvasContextType.js"; -export type * from "./Types/ParticlesCanvasType.js"; export type * from "./Types/CustomEventArgs.js"; export type * from "./Types/CustomEventListener.js"; export type * from "./Types/EasingFunction.js"; diff --git a/interactions/external/connect/src/Utils.ts b/interactions/external/connect/src/Utils.ts index 98ec6d52e17..e9ed451c825 100644 --- a/interactions/external/connect/src/Utils.ts +++ b/interactions/external/connect/src/Utils.ts @@ -1,5 +1,5 @@ +import type { ConnectContainer, LinkParticle } from "./Types.js"; import { - type CanvasContextType, type ICoordinates, type Particle, clamp, @@ -7,7 +7,6 @@ import { getStyleFromHsl, getStyleFromRgb, } from "@tsparticles/engine"; -import type { ConnectContainer, LinkParticle } from "./Types.js"; import { drawLine } from "@tsparticles/canvas-utils"; const gradientMin = 0, @@ -25,7 +24,7 @@ const gradientMin = 0, */ export function gradient( container: ConnectContainer, - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, p1: Particle, p2: Particle, opacity: number, @@ -59,7 +58,7 @@ export function gradient( * @param end */ export function drawConnectLine( - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, width: number, lineStyle: CanvasGradient, begin: ICoordinates, @@ -81,7 +80,7 @@ export function drawConnectLine( */ export function lineStyle( container: ConnectContainer, - ctx: CanvasContextType, + ctx: OffscreenCanvasRenderingContext2D, p1: Particle, p2: Particle, ): CanvasGradient | undefined { diff --git a/interactions/external/grab/src/Utils.ts b/interactions/external/grab/src/Utils.ts index 1a7bc8f7d9a..01215458e06 100644 --- a/interactions/external/grab/src/Utils.ts +++ b/interactions/external/grab/src/Utils.ts @@ -1,5 +1,5 @@ -import { type CanvasContextType, type ICoordinates, type IRgb, getStyleFromRgb } from "@tsparticles/engine"; import type { GrabContainer, LinkParticle } from "./Types.js"; +import { type ICoordinates, type IRgb, getStyleFromRgb } from "@tsparticles/engine"; import { drawLine } from "@tsparticles/canvas-utils"; const defaultWidth = 0; @@ -15,7 +15,7 @@ const defaultWidth = 0; * @param hdr - Whether the line should be drawn in HDR mode or not. */ export function drawGrabLine( - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, width: number, begin: ICoordinates, end: ICoordinates, diff --git a/interactions/light/src/Utils.ts b/interactions/light/src/Utils.ts index 89c2905c8f6..45860bfc9dc 100644 --- a/interactions/light/src/Utils.ts +++ b/interactions/light/src/Utils.ts @@ -1,11 +1,4 @@ -import { - type CanvasContextType, - type ICoordinates, - doublePI, - getStyleFromRgb, - half, - quarter, -} from "@tsparticles/engine"; +import { type ICoordinates, doublePI, getStyleFromRgb, half, quarter } from "@tsparticles/engine"; import type { LightContainer, LightParticle } from "./Types.js"; const gradientPos = { @@ -25,7 +18,11 @@ export const lightMode = "light"; * @param context * @param mousePos */ -export function drawLight(container: LightContainer, context: CanvasContextType, mousePos: ICoordinates): void { +export function drawLight( + container: LightContainer, + context: OffscreenCanvasRenderingContext2D, + mousePos: ICoordinates, +): void { const lightOptions = container.actualOptions.interactivity?.modes.light?.area; if (!lightOptions) { @@ -65,7 +62,7 @@ export function drawLight(container: LightContainer, context: CanvasContextType, */ export function drawParticleShadow( container: LightContainer, - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, particle: LightParticle, mousePos: ICoordinates, ): void { diff --git a/interactions/particles/links/src/LinkInstance.ts b/interactions/particles/links/src/LinkInstance.ts index 59c0f88849b..f469d1292f2 100644 --- a/interactions/particles/links/src/LinkInstance.ts +++ b/interactions/particles/links/src/LinkInstance.ts @@ -1,5 +1,4 @@ import { - type CanvasContextType, type IContainerPlugin, type IRgb, type PluginManager, @@ -33,7 +32,7 @@ export class LinkInstance implements IContainerPlugin { this._freqs = { links: new Map(), triangles: new Map() }; } - drawParticle(context: CanvasContextType, particle: LinkParticle): void { + drawParticle(context: OffscreenCanvasRenderingContext2D, particle: LinkParticle): void { const { links, options } = particle; if (!links?.length || !options.links) { @@ -192,7 +191,7 @@ export class LinkInstance implements IContainerPlugin { p1Destinations: Set, pos1: ReturnType, pos2: ReturnType, - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, ): void { const p2 = link.destination, triangleOptions = options.links?.triangles; diff --git a/plugins/absorbers/src/AbsorberInstance.ts b/plugins/absorbers/src/AbsorberInstance.ts index 2b79455e638..c465cacaeef 100644 --- a/plugins/absorbers/src/AbsorberInstance.ts +++ b/plugins/absorbers/src/AbsorberInstance.ts @@ -1,5 +1,4 @@ import { - type CanvasContextType, type Container, type ICoordinates, type IDelta, @@ -230,7 +229,7 @@ export class AbsorberInstance { * The draw method, for drawing the absorber in the canvas * @param context - the canvas 2d context used for drawing */ - draw(context: CanvasContextType): void { + draw(context: OffscreenCanvasRenderingContext2D): void { context.translate(this.position.x, this.position.y); context.beginPath(); context.arc(originPoint.x, originPoint.y, this.size, minAngle, maxAngle, false); diff --git a/plugins/absorbers/src/AbsorbersPluginInstance.ts b/plugins/absorbers/src/AbsorbersPluginInstance.ts index 6bc8fceb274..d46d7f2a028 100644 --- a/plugins/absorbers/src/AbsorbersPluginInstance.ts +++ b/plugins/absorbers/src/AbsorbersPluginInstance.ts @@ -1,5 +1,4 @@ import { - type CanvasContextType, type IContainerPlugin, type IDelta, type Particle, @@ -22,7 +21,7 @@ export class AbsorbersPluginInstance implements IContainerPlugin { this._instancesManager.initContainer(container); } - draw(context: CanvasContextType): void { + draw(context: OffscreenCanvasRenderingContext2D): void { for (const absorber of this._instancesManager.getArray(this._container)) { absorber.draw(context); } diff --git a/plugins/backgroundMask/src/BackgroundMaskPluginInstance.ts b/plugins/backgroundMask/src/BackgroundMaskPluginInstance.ts index 134529c83e3..0e421132b46 100644 --- a/plugins/backgroundMask/src/BackgroundMaskPluginInstance.ts +++ b/plugins/backgroundMask/src/BackgroundMaskPluginInstance.ts @@ -1,5 +1,4 @@ import { - type CanvasContextType, type IContainerPlugin, type PluginManager, getStyleFromRgb, @@ -48,7 +47,7 @@ export class BackgroundMaskPluginInstance implements IContainerPlugin { return true; } - drawSettingsCleanup(context: CanvasContextType): void { + drawSettingsCleanup(context: OffscreenCanvasRenderingContext2D): void { if (!this._defaultCompositeValue) { return; } @@ -56,7 +55,7 @@ export class BackgroundMaskPluginInstance implements IContainerPlugin { context.globalCompositeOperation = this._defaultCompositeValue; } - drawSettingsSetup(context: CanvasContextType): void { + drawSettingsSetup(context: OffscreenCanvasRenderingContext2D): void { const previousComposite = context.globalCompositeOperation, backgroundMask = this._container.actualOptions.backgroundMask; diff --git a/plugins/backgroundMask/src/Options/Classes/BackgroundMask.ts b/plugins/backgroundMask/src/Options/Classes/BackgroundMask.ts index 5af66f9ed1d..d700082d4f9 100644 --- a/plugins/backgroundMask/src/Options/Classes/BackgroundMask.ts +++ b/plugins/backgroundMask/src/Options/Classes/BackgroundMask.ts @@ -9,7 +9,7 @@ import type { IBackgroundMaskCover } from "../Interfaces/IBackgroundMaskCover.js export class BackgroundMask implements IBackgroundMask, IOptionLoader { /** * Canvas composite operation - * values here: https://developer.mozilla.org/en-US/docs/Web/API/CanvasContextType/globalCompositeOperation + * values here: https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D/globalCompositeOperation */ composite: GlobalCompositeOperation; diff --git a/plugins/backgroundMask/src/Options/Interfaces/IBackgroundMask.ts b/plugins/backgroundMask/src/Options/Interfaces/IBackgroundMask.ts index 7bdddddf8cc..6c2d1ce0aa6 100644 --- a/plugins/backgroundMask/src/Options/Interfaces/IBackgroundMask.ts +++ b/plugins/backgroundMask/src/Options/Interfaces/IBackgroundMask.ts @@ -11,7 +11,7 @@ export interface IBackgroundMask { * This property is used to choose the composition mode for the background mask effect. * * The default value is `destination-out`, which unveils the background below using drawn elements, any other valid value - * can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/CanvasContextType/globalCompositeOperation) + * can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D/globalCompositeOperation) */ composite: GlobalCompositeOperation; diff --git a/plugins/blend/src/BlendPluginInstance.ts b/plugins/blend/src/BlendPluginInstance.ts index 2d333212ce9..8c560879a1e 100644 --- a/plugins/blend/src/BlendPluginInstance.ts +++ b/plugins/blend/src/BlendPluginInstance.ts @@ -1,5 +1,5 @@ import type { BlendContainer, BlendParticle } from "./types.js"; -import { type CanvasContextType, type IContainerPlugin, defaultCompositeValue } from "@tsparticles/engine"; +import { type IContainerPlugin, defaultCompositeValue } from "@tsparticles/engine"; export class BlendPluginInstance implements IContainerPlugin { private readonly _container; @@ -9,7 +9,7 @@ export class BlendPluginInstance implements IContainerPlugin { this._container = container; } - drawParticleCleanup(context: CanvasContextType, particle: BlendParticle): void { + drawParticleCleanup(context: OffscreenCanvasRenderingContext2D, particle: BlendParticle): void { if (!particle.options.blend?.enable) { return; } @@ -19,7 +19,7 @@ export class BlendPluginInstance implements IContainerPlugin { particle.originalBlendMode = undefined; } - drawParticleSetup(context: CanvasContextType, particle: BlendParticle): void { + drawParticleSetup(context: OffscreenCanvasRenderingContext2D, particle: BlendParticle): void { if (!particle.options.blend?.enable) { return; } @@ -29,7 +29,7 @@ export class BlendPluginInstance implements IContainerPlugin { context.globalCompositeOperation = particle.options.blend.mode; } - drawSettingsCleanup(context: CanvasContextType): void { + drawSettingsCleanup(context: OffscreenCanvasRenderingContext2D): void { if (!this._defaultCompositeValue) { return; } @@ -37,7 +37,7 @@ export class BlendPluginInstance implements IContainerPlugin { context.globalCompositeOperation = this._defaultCompositeValue; } - drawSettingsSetup(context: CanvasContextType): void { + drawSettingsSetup(context: OffscreenCanvasRenderingContext2D): void { const previousComposite = context.globalCompositeOperation, blend = this._container.actualOptions.blend; diff --git a/plugins/blend/src/Options/Classes/Blend.ts b/plugins/blend/src/Options/Classes/Blend.ts index 21eef9b0b14..a6da0406794 100644 --- a/plugins/blend/src/Options/Classes/Blend.ts +++ b/plugins/blend/src/Options/Classes/Blend.ts @@ -12,7 +12,7 @@ export class Blend implements IBlend, IOptionLoader { /** * Canvas composite operation - * values here: https://developer.mozilla.org/en-US/docs/Web/API/CanvasContextType/globalCompositeOperation + * values here: https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D/globalCompositeOperation */ mode: GlobalCompositeOperation; diff --git a/plugins/blend/src/Options/Interfaces/IBlend.ts b/plugins/blend/src/Options/Interfaces/IBlend.ts index 62143cbc7fd..5ebf07a76ba 100644 --- a/plugins/blend/src/Options/Interfaces/IBlend.ts +++ b/plugins/blend/src/Options/Interfaces/IBlend.ts @@ -13,7 +13,7 @@ export interface IBlend { * This property is used to choose the composition mode for the blend effect. * * The default value is `destination-out`, which unveils the background below using drawn elements, any other valid value - * can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/CanvasContextType/globalCompositeOperation) + * can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D/globalCompositeOperation) */ mode: GlobalCompositeOperation; } diff --git a/plugins/emittersShapes/path/src/EmittersPathShape.ts b/plugins/emittersShapes/path/src/EmittersPathShape.ts index e3cb59141ac..05d1ecf7c5f 100644 --- a/plugins/emittersShapes/path/src/EmittersPathShape.ts +++ b/plugins/emittersShapes/path/src/EmittersPathShape.ts @@ -1,5 +1,4 @@ import { - type CanvasContextType, type Container, type ICoordinates, type IDimension, @@ -12,7 +11,7 @@ import { generateRandomPointOnPathPerimeter, generateRandomPointWithinPath } fro import type { EmittersPathShapeOptions } from "./Options/Classes/EmittersPathShapeOptions.js"; export class EmittersPathShape extends EmitterShapeBase { - checkContext: CanvasContextType; + checkContext: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; path: Path2D; points: ICoordinates[]; diff --git a/plugins/emittersShapes/path/src/utils.ts b/plugins/emittersShapes/path/src/utils.ts index a2b72850482..b950826258d 100644 --- a/plugins/emittersShapes/path/src/utils.ts +++ b/plugins/emittersShapes/path/src/utils.ts @@ -1,4 +1,4 @@ -import { type CanvasContextType, type ICoordinates, type IDimension, getRandom, half } from "@tsparticles/engine"; +import { type ICoordinates, type IDimension, getRandom, half } from "@tsparticles/engine"; const maxAttempts = 100; @@ -11,7 +11,7 @@ const maxAttempts = 100; * @returns the random point within the path */ export function generateRandomPointWithinPath( - ctx: CanvasContextType, + ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, path: Path2D, center: ICoordinates, size: IDimension, @@ -43,7 +43,7 @@ export function generateRandomPointWithinPath( * @returns the random point on the perimeter of the path */ export function generateRandomPointOnPathPerimeter( - ctx: CanvasContextType, + ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, path: Path2D, center: ICoordinates, size: IDimension, diff --git a/plugins/polygonMask/src/PolygonMaskInstance.ts b/plugins/polygonMask/src/PolygonMaskInstance.ts index fc3bee32dbe..7b65f569f38 100644 --- a/plugins/polygonMask/src/PolygonMaskInstance.ts +++ b/plugins/polygonMask/src/PolygonMaskInstance.ts @@ -1,6 +1,5 @@ import "./pathseg.js"; import { - type CanvasContextType, type IContainerPlugin, type ICoordinates, type IDelta, @@ -87,7 +86,7 @@ export class PolygonMaskInstance implements IContainerPlugin { } /** @inheritDoc */ - draw(context: CanvasContextType): void { + draw(context: OffscreenCanvasRenderingContext2D): void { if (!this.paths?.length) { return; } diff --git a/plugins/polygonMask/src/utils.ts b/plugins/polygonMask/src/utils.ts index 4dc1d2b22e2..d5d981798cd 100644 --- a/plugins/polygonMask/src/utils.ts +++ b/plugins/polygonMask/src/utils.ts @@ -1,5 +1,4 @@ import { - type CanvasContextType, type ICoordinates, type PluginManager, Vector, @@ -34,7 +33,7 @@ const squareExp = 2, */ export function drawPolygonMask( pluginManager: PluginManager, - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, rawData: ICoordinates[], stroke: IPolygonMaskDrawStroke, hdr = false, @@ -75,7 +74,7 @@ export function drawPolygonMask( */ export function drawPolygonMaskPath( pluginManager: PluginManager, - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, path: Path2D, stroke: IPolygonMaskDrawStroke, position: ICoordinates, diff --git a/plugins/zoom/src/ZoomPluginInstance.ts b/plugins/zoom/src/ZoomPluginInstance.ts index 708b220c6be..2dc9916293d 100644 --- a/plugins/zoom/src/ZoomPluginInstance.ts +++ b/plugins/zoom/src/ZoomPluginInstance.ts @@ -1,4 +1,4 @@ -import { type CanvasContextType, type IContainerPlugin, type IShapeDrawData, defaultZoom } from "@tsparticles/engine"; +import { type IContainerPlugin, type IShapeDrawData, defaultZoom } from "@tsparticles/engine"; import type { ZoomContainer } from "./types.js"; import { ZoomEventListeners } from "./ZoomEventListeners.js"; @@ -43,7 +43,7 @@ export class ZoomPluginInstance implements IContainerPlugin { ); } - drawSettingsCleanup(context: CanvasContextType): void { + drawSettingsCleanup(context: OffscreenCanvasRenderingContext2D): void { const zoom = this._container.canvas.zoom; if (zoom === defaultZoom) { @@ -53,7 +53,7 @@ export class ZoomPluginInstance implements IContainerPlugin { context.restore(); } - drawSettingsSetup(context: CanvasContextType): void { + drawSettingsSetup(context: OffscreenCanvasRenderingContext2D): void { const zoom = this._container.canvas.zoom; if (zoom === defaultZoom) { diff --git a/shapes/cards/src/utils.ts b/shapes/cards/src/utils.ts index 38ae249b32a..7fd4d4f6185 100644 --- a/shapes/cards/src/utils.ts +++ b/shapes/cards/src/utils.ts @@ -1,14 +1,4 @@ -import { - type CanvasContextType, - type IRgb, - double, - doublePI, - getStyleFromRgb, - half, - originPoint, - safeDocument, - triple, -} from "@tsparticles/engine"; +import { type IRgb, double, doublePI, getStyleFromRgb, half, originPoint, triple } from "@tsparticles/engine"; import type { ICardData } from "./ICardData.js"; import { SuitType } from "./SuitType.js"; import { drawPath } from "@tsparticles/path-utils"; @@ -42,7 +32,7 @@ const cardWidthRatio = (double * double) / triple, * @param canvasSettings - */ export function drawRoundedCard( - ctx: CanvasContextType, + ctx: OffscreenCanvasRenderingContext2D, radius: number, cardData: ICardData, hdr: boolean, @@ -61,19 +51,8 @@ export function drawRoundedCard( let cachedData = cardsCache.get(cacheKey); if (!cachedData) { - let cacheCanvas: HTMLCanvasElement | OffscreenCanvas, cacheCtx: CanvasContextType | null; - - if (typeof OffscreenCanvas === "undefined") { - cacheCanvas = safeDocument().createElement("canvas"); - - cacheCanvas.width = cardWidth; - cacheCanvas.height = cardHeight; - + const cacheCanvas = new OffscreenCanvas(cardWidth, cardHeight), cacheCtx = cacheCanvas.getContext("2d", canvasSettings); - } else { - cacheCanvas = new OffscreenCanvas(cardWidth, cardHeight); - cacheCtx = cacheCanvas.getContext("2d", canvasSettings); - } if (cacheCtx) { cacheCtx.translate(halfWidth, halfHeight); @@ -108,7 +87,7 @@ function getCacheKey(radius: number, hdr: boolean, cardData: ICardData): string * @param ctx - * @param radius - */ -function drawRoundedCardBack(ctx: CanvasContextType, radius: number): void { +function drawRoundedCardBack(ctx: OffscreenCanvasRenderingContext2D, radius: number): void { drawCardBody(ctx, radius); } @@ -118,7 +97,12 @@ function drawRoundedCardBack(ctx: CanvasContextType, radius: number): void { * @param cardData - * @param hdr - */ -function drawRoundedCardFront(ctx: CanvasContextType, radius: number, cardData: ICardData, hdr: boolean): void { +function drawRoundedCardFront( + ctx: OffscreenCanvasRenderingContext2D, + radius: number, + cardData: ICardData, + hdr: boolean, +): void { const { suit, value } = cardData, cardWidth = radius * cardWidthRatio, cardHeight = radius * cardHeightRatio, @@ -202,7 +186,7 @@ function drawRoundedCardFront(ctx: CanvasContextType, radius: number, cardData: * @param ctx - * @param radius - */ -function drawCardBody(ctx: CanvasContextType, radius: number): void { +function drawCardBody(ctx: OffscreenCanvasRenderingContext2D, radius: number): void { const cardWidth = radius * cardWidthRatio, cardHeight = radius * cardHeightRatio, halfWidth = cardWidth * half, diff --git a/shapes/emoji/src/EmojiDrawer.ts b/shapes/emoji/src/EmojiDrawer.ts index e50f4168171..63ac8fa924d 100644 --- a/shapes/emoji/src/EmojiDrawer.ts +++ b/shapes/emoji/src/EmojiDrawer.ts @@ -1,5 +1,4 @@ import { - type CanvasContextType, type Container, type IShapeDrawData, type IShapeDrawer, @@ -9,7 +8,6 @@ import { getRangeMax, isInArray, itemFromSingleOrMultiple, - safeDocument, } from "@tsparticles/engine"; import { drawEmoji, validTypes } from "./Utils.js"; import type { EmojiParticle } from "./EmojiParticle.js"; @@ -38,7 +36,7 @@ export class EmojiDrawer implements IShapeDrawer { /** * Draws the emoji shape - * @param data + * @param data - */ draw(data: IShapeDrawData): void { const key = data.particle.emojiDataKey; @@ -82,7 +80,7 @@ export class EmojiDrawer implements IShapeDrawer { /** * Cleans up emoji data when particle is destroyed - * @param particle + * @param particle - */ particleDestroy(particle: EmojiParticle): void { particle.emojiDataKey = undefined; @@ -90,8 +88,8 @@ export class EmojiDrawer implements IShapeDrawer { /** * Initializes the emoji shape for a particle - * @param container - * @param particle + * @param container - + * @param particle - */ particleInit(container: Container, particle: EmojiParticle): void { const shapeData = particle.shapeData as unknown as IEmojiShape; @@ -132,22 +130,9 @@ export class EmojiDrawer implements IShapeDrawer { const padding = emojiOptions.padding * double, maxSize = getRangeMax(particle.size.value), fullSize = maxSize + padding, - canvasSize = fullSize * double; - - let cacheCanvas: HTMLCanvasElement | OffscreenCanvas, context: CanvasContextType | null; - - if (typeof OffscreenCanvas === "undefined") { - const canvas = safeDocument().createElement("canvas"); - - canvas.width = canvasSize; - canvas.height = canvasSize; - - context = canvas.getContext("2d", container.canvas.render.settings); - cacheCanvas = canvas; - } else { - cacheCanvas = new OffscreenCanvas(canvasSize, canvasSize); + canvasSize = fullSize * double, + cacheCanvas = new OffscreenCanvas(canvasSize, canvasSize), context = cacheCanvas.getContext("2d", container.canvas.render.settings); - } if (!context) { return; diff --git a/shapes/rounded-polygon/src/Utils.ts b/shapes/rounded-polygon/src/Utils.ts index 2a3ab07601c..422484ee4d2 100644 --- a/shapes/rounded-polygon/src/Utils.ts +++ b/shapes/rounded-polygon/src/Utils.ts @@ -1,4 +1,4 @@ -import { type CanvasContextType, type ICoordinates, doublePI, half } from "@tsparticles/engine"; +import { type ICoordinates, doublePI, half } from "@tsparticles/engine"; const defaultRotation = 0; @@ -24,7 +24,7 @@ export function polygon(sides: number, radius: number, rot = defaultRotation): I * @param path - * @param radius - */ -export function roundedPath(context: CanvasContextType, path: ICoordinates[], radius: number): void { +export function roundedPath(context: OffscreenCanvasRenderingContext2D, path: ICoordinates[], radius: number): void { const index1 = 0, index2 = 1, increment = 1; diff --git a/shapes/rounded-rect/src/Utils.ts b/shapes/rounded-rect/src/Utils.ts index 4ac73b41ba0..156e3ebd20f 100644 --- a/shapes/rounded-rect/src/Utils.ts +++ b/shapes/rounded-rect/src/Utils.ts @@ -1,4 +1,3 @@ -import type { CanvasContextType } from "@tsparticles/engine"; import type { RadiusInfo } from "./RadiusInfo.js"; import type { RectInfo } from "./RectInfo.js"; @@ -10,7 +9,7 @@ import type { RectInfo } from "./RectInfo.js"; * @param borderRadius - */ export function drawRoundedRect( - ctx: CanvasContextType, + ctx: OffscreenCanvasRenderingContext2D, fixedRadius: number, fixedDiameter: number, borderRadius: number, diff --git a/shapes/text/src/Utils.ts b/shapes/text/src/Utils.ts index e5547c4496b..19019695797 100644 --- a/shapes/text/src/Utils.ts +++ b/shapes/text/src/Utils.ts @@ -1,10 +1,4 @@ -import { - type CanvasContextType, - type IShapeDrawData, - double, - half, - itemFromSingleOrMultiple, -} from "@tsparticles/engine"; +import { type IShapeDrawData, double, half, itemFromSingleOrMultiple } from "@tsparticles/engine"; import type { TextParticle } from "./TextParticle.js"; export const validTypes = ["text", "character", "char", "multiline-text"]; @@ -69,7 +63,7 @@ export function drawText(data: IShapeDrawData): void { * @param stroke - */ function drawTextLine( - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, line: string, size: number, index: number, diff --git a/updaters/gradient/src/GradientUpdater.ts b/updaters/gradient/src/GradientUpdater.ts index 1974814adab..e0eecde5c48 100644 --- a/updaters/gradient/src/GradientUpdater.ts +++ b/updaters/gradient/src/GradientUpdater.ts @@ -1,6 +1,5 @@ import { AnimationStatus, - type CanvasContextType, type Container, GradientType, type ICoordinates, @@ -56,7 +55,7 @@ export class GradientUpdater implements IParticleUpdater { */ getColorStyles( particle: GradientParticle, - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, radius: number, opacity: number, ): IParticleColorStyle { diff --git a/updaters/orbit/src/Utils.ts b/updaters/orbit/src/Utils.ts index 5401164622c..46f67350fb3 100644 --- a/updaters/orbit/src/Utils.ts +++ b/updaters/orbit/src/Utils.ts @@ -1,12 +1,4 @@ -import { - type CanvasContextType, - type IHsl, - type Particle, - degToRad, - double, - getStyleFromHsl, - half, -} from "@tsparticles/engine"; +import { type IHsl, type Particle, degToRad, double, getStyleFromHsl, half } from "@tsparticles/engine"; import type { OrbitContainer } from "./Types.js"; const minWidth = 0; @@ -26,7 +18,7 @@ const minWidth = 0; */ export function drawEllipse( container: OrbitContainer, - context: CanvasContextType, + context: OffscreenCanvasRenderingContext2D, particle: Particle, fillColorValue: IHsl | undefined, radius: number, diff --git a/updaters/twinkle/src/TwinkleUpdater.ts b/updaters/twinkle/src/TwinkleUpdater.ts index 568f7c0b0ad..63d6e8a0362 100644 --- a/updaters/twinkle/src/TwinkleUpdater.ts +++ b/updaters/twinkle/src/TwinkleUpdater.ts @@ -1,5 +1,4 @@ import { - type CanvasContextType, type Container, type IParticleColorStyle, type IParticleUpdater, @@ -40,7 +39,7 @@ export class TwinkleUpdater implements IParticleUpdater { */ getColorStyles( particle: Particle, - _context: CanvasContextType, + _context: OffscreenCanvasRenderingContext2D, _radius: number, opacity: number, ): IParticleColorStyle { diff --git a/utils/canvasUtils/src/Utils.ts b/utils/canvasUtils/src/Utils.ts index d2d140f0fe5..96854cb1f12 100644 --- a/utils/canvasUtils/src/Utils.ts +++ b/utils/canvasUtils/src/Utils.ts @@ -1,5 +1,5 @@ +import type { CanvasPixelData, ITextDataOptions, TextLineData } from "./types.js"; import { - type CanvasContextType, type ICoordinates, type IDimension, type IRgba, @@ -10,7 +10,6 @@ import { originPoint, safeDocument, } from "@tsparticles/engine"; -import type { CanvasPixelData, ITextDataOptions, TextLineData } from "./types.js"; const defaultWidth = 0, indexesOffset = { @@ -28,7 +27,7 @@ const defaultWidth = 0, * @param begin - The start point of the line. * @param end - The end point of the line. */ -export function drawLine(context: CanvasContextType, begin: ICoordinates, end: ICoordinates): void { +export function drawLine(context: OffscreenCanvasRenderingContext2D, begin: ICoordinates, end: ICoordinates): void { context.beginPath(); context.moveTo(begin.x, begin.y); context.lineTo(end.x, end.y); @@ -43,7 +42,7 @@ export function drawLine(context: CanvasContextType, begin: ICoordinates, end: I * @returns the canvas pixel data */ export function getCanvasImageData( - ctx: CanvasContextType, + ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, size: IDimension, offset: number, clear = true, diff --git a/utils/noiseField/src/NoiseFieldGenerator.ts b/utils/noiseField/src/NoiseFieldGenerator.ts index a511a9fc60d..f81672d7a43 100644 --- a/utils/noiseField/src/NoiseFieldGenerator.ts +++ b/utils/noiseField/src/NoiseFieldGenerator.ts @@ -1,13 +1,4 @@ -import { - type CanvasContextType, - type Container, - type Particle, - Vector, - deepExtend, - doublePI, - getRandom, - identity, -} from "@tsparticles/engine"; +import { type Container, type Particle, Vector, deepExtend, doublePI, getRandom, identity } from "@tsparticles/engine"; import type { IFactorValues, IOffsetValues } from "./IFactorOffsetValues.js"; import { type IMovePathGenerator } from "@tsparticles/plugin-move"; import type { INoiseFieldOptions } from "./INoiseFieldOptions.js"; @@ -145,7 +136,7 @@ export abstract class NoiseFieldGenerator implements IMovePathGenerator { } } - private _drawField(ctx: CanvasContextType): void { + private _drawField(ctx: OffscreenCanvasRenderingContext2D): void { const { field, options } = this; for (let x = 0; x < options.columns; x++) { diff --git a/utils/pathUtils/src/Utils.ts b/utils/pathUtils/src/Utils.ts index e912df769cd..e0b78cc5826 100644 --- a/utils/pathUtils/src/Utils.ts +++ b/utils/pathUtils/src/Utils.ts @@ -1,4 +1,3 @@ -import type { CanvasContextType } from "@tsparticles/engine"; import type { IPathData } from "./IPathData.js"; import { SegmentType } from "./SegmentType.js"; @@ -12,7 +11,7 @@ const firstIndex = 0, * @param radius - * @param path - */ -export function drawPath(ctx: CanvasContextType, radius: number, path: IPathData): void { +export function drawPath(ctx: OffscreenCanvasRenderingContext2D, radius: number, path: IPathData): void { const firstSegment = path.segments[firstIndex]; if (!firstSegment) { From 977aa1667d4c99fe31f3f9eaf27c272a7b5b979a Mon Sep 17 00:00:00 2001 From: Matteo Bruni <176620+matteobruni@users.noreply.github.com> Date: Wed, 13 May 2026 16:09:53 +0200 Subject: [PATCH 2/2] docs: updated analytics mode --- websites/confetti/public/cookie-policy.html | 6 ++- websites/confetti/src/cookie-consent.js | 47 ++++++++++++++++++- websites/confetti/src/main.js | 13 +++-- .../theme/components/CookieConsentBanner.vue | 4 +- .../theme/components/TrackingManager.vue | 5 +- .../docs/.vitepress/theme/tracking/config.ts | 5 ++ .../docs/.vitepress/theme/tracking/runtime.ts | 40 ++++++++++++++-- websites/website/docs/cookie-policy.md | 4 +- websites/website/docs/privacy-policy.md | 5 +- 9 files changed, 109 insertions(+), 20 deletions(-) diff --git a/websites/confetti/public/cookie-policy.html b/websites/confetti/public/cookie-policy.html index 77b000e33e9..4d2440e35f6 100644 --- a/websites/confetti/public/cookie-policy.html +++ b/websites/confetti/public/cookie-policy.html @@ -29,9 +29,13 @@

Categories

Consent and control

- Analytics and personalized advertising scripts are loaded only after explicit consent. You + Analytics cookies and personalized advertising are enabled only after explicit consent. You can reject all, accept all, or save a custom choice from the privacy banner.

+

+ If analytics cookies are rejected, the website can still use anonymous cookieless + analytics measurement (Google Consent Mode) without storing analytics cookies. +

You can change your choice at any time from the Cookie preferences button in the website footer. diff --git a/websites/confetti/src/cookie-consent.js b/websites/confetti/src/cookie-consent.js index c4882859b99..e79ecb784f5 100644 --- a/websites/confetti/src/cookie-consent.js +++ b/websites/confetti/src/cookie-consent.js @@ -2,6 +2,7 @@ const CONSENT_KEY = 'tsparticles-confetti/cookie-consent-v1'; const GA_MEASUREMENT_ID = 'G-80MY3TZM79'; const ADSENSE_CLIENT_ID = 'ca-pub-1784552607103901'; const ADSENSE_NON_PERSONALIZED_ON_REJECT = true; +const ANALYTICS_COOKIELESS_ON_REJECT = true; const defaultConsent = { analytics: false, @@ -11,6 +12,8 @@ const defaultConsent = { let consent = readConsent(); let analyticsInitialized = false; let adsenseInitialized = false; +let consentDefaultsInitialized = false; +let initialPageViewTracked = false; function readConsent() { try { @@ -78,6 +81,7 @@ function initAnalytics() { } ensureGtagStub(); + initConsentDefaults(); loadScript('ga-script', `https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`); window.gtag('js', new Date()); window.gtag('config', GA_MEASUREMENT_ID, { @@ -109,6 +113,23 @@ function initAdSense() { adsenseInitialized = true; } +function initConsentDefaults() { + if (consentDefaultsInitialized) { + return; + } + + ensureGtagStub(); + + window.gtag('consent', 'default', { + ad_storage: 'denied', + analytics_storage: 'denied', + ad_user_data: 'denied', + ad_personalization: 'denied', + }); + + consentDefaultsInitialized = true; +} + function updateConsentMode(activeConsent) { ensureGtagStub(); @@ -126,14 +147,34 @@ function updateAdSensePersonalization(activeConsent) { activeConsent.adsense || !ADSENSE_NON_PERSONALIZED_ON_REJECT ? 0 : 1; } +function canTrackAnalytics(activeConsent) { + return !!activeConsent && (activeConsent.analytics || ANALYTICS_COOKIELESS_ON_REJECT); +} + +function trackInitialPageView(activeConsent) { + if (initialPageViewTracked || !canTrackAnalytics(activeConsent) || !globalThis.gtag) { + return; + } + + globalThis.gtag('event', 'page_view', { + page_location: globalThis.location.href, + page_path: globalThis.location.pathname, + page_title: document.title, + }); + + initialPageViewTracked = true; +} + function applyConsent(activeConsent) { updateConsentMode(activeConsent); updateAdSensePersonalization(activeConsent); - if (activeConsent.analytics) { + if (canTrackAnalytics(activeConsent)) { initAnalytics(); } + trackInitialPageView(activeConsent); + if (activeConsent.adsense || ADSENSE_NON_PERSONALIZED_ON_REJECT) { initAdSense(); } @@ -170,11 +211,12 @@ function createBanner() {