diff --git a/src/components/views/elements/effects/EffectsOverlay.tsx b/src/components/views/elements/effects/EffectsOverlay.tsx index 5ec3566f18..b2ecec8753 100644 --- a/src/components/views/elements/effects/EffectsOverlay.tsx +++ b/src/components/views/elements/effects/EffectsOverlay.tsx @@ -1,6 +1,7 @@ import React, { FunctionComponent, useEffect, useRef } from 'react'; import dis from '../../../../dispatcher/dispatcher'; -import ICanvasEffect from './ICanvasEffect.js'; +import ICanvasEffect, { ICanvasEffectConstructable } from './ICanvasEffect.js'; +import effects from './index' export type EffectsOverlayProps = { roomWidth: number; @@ -8,15 +9,16 @@ export type EffectsOverlayProps = { const EffectsOverlay: FunctionComponent = ({ roomWidth }) => { const canvasRef = useRef(null); - const effectsRef = useRef>(new Map()); + const effectsRef = useRef>(new Map()); const lazyLoadEffectModule = async (name: string): Promise => { if (!name) return null; - let effect = effectsRef.current[name] ?? null; + let effect: ICanvasEffect | null = effectsRef.current[name] || null; if (effect === null) { + const options = effects.find((e) => e.command === name)?.options try { - const { default: Effect } = await import(`./${name}`); - effect = new Effect(); + const { default: Effect }: { default: ICanvasEffectConstructable } = await import(`./${name}`); + effect = new Effect(options); effectsRef.current[name] = effect; } catch (err) { console.warn('Unable to load effect module at \'./${name}\'.', err) diff --git a/src/components/views/elements/effects/ICanvasEffect.ts b/src/components/views/elements/effects/ICanvasEffect.ts index 71210d7ec3..c2a3046c8f 100644 --- a/src/components/views/elements/effects/ICanvasEffect.ts +++ b/src/components/views/elements/effects/ICanvasEffect.ts @@ -1,3 +1,7 @@ +export interface ICanvasEffectConstructable { + new(options?: { [key: string]: any }): ICanvasEffect +} + export default interface ICanvasEffect { start: (canvas: HTMLCanvasElement, timeout?: number) => Promise, stop: () => Promise, diff --git a/src/components/views/elements/effects/confetti/index.ts b/src/components/views/elements/effects/confetti/index.ts index b613c32043..07b6f1632a 100644 --- a/src/components/views/elements/effects/confetti/index.ts +++ b/src/components/views/elements/effects/confetti/index.ts @@ -43,8 +43,8 @@ export const DefaultOptions: ConfettiOptions = { export default class Confetti implements ICanvasEffect { private readonly options: ConfettiOptions; - constructor(options: ConfettiOptions = DefaultOptions) { - this.options = options; + constructor(options: { [key: string]: any }) { + this.options = {...DefaultOptions, ...options}; } private context: CanvasRenderingContext2D | null = null; diff --git a/src/components/views/elements/effects/index.ts b/src/components/views/elements/effects/index.ts index 8a95b1c9d0..3986d6e841 100644 --- a/src/components/views/elements/effects/index.ts +++ b/src/components/views/elements/effects/index.ts @@ -1,11 +1,22 @@ import { _t, _td } from "../../../../languageHandler"; -type Effect = { +export type Effect = { emojis: Array; msgType: string; command: string; description: () => string; fallbackMessage: () => string; + options: { + [key: string]: any + } +} + +type ConfettiOptions = { + maxCount: number, + speed: number, + frameInterval: number, + alpha: number, + gradient: boolean, } const effects: Array = [ @@ -15,6 +26,18 @@ const effects: Array = [ command: 'confetti', description: () => _td("Sends the given message with confetti"), fallbackMessage: () => _t("sends confetti") + " 🎉", + options: { + //set max confetti count + maxCount: 150, + //syarn addet the particle animation speed + speed: 3, + //the confetti animation frame interval in milliseconds + frameInterval: 15, + //the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible) + alpha: 1.0, + //use gradient instead of solid particle color + gradient: false, + } as ConfettiOptions, }, ];