summaryrefslogtreecommitdiff
path: root/packages/frontend/src/utility/confetti.ts
blob: b95c26345e32a8d92f13494099a39daef9f12132 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
 * SPDX-FileCopyrightText: syuilo and misskey-project
 * SPDX-License-Identifier: AGPL-3.0-only
 */

import _confetti from 'canvas-confetti';
import * as os from '@/os.js';
import { prefer } from '@/preferences.js';

export function confetti(options: { duration?: number; } = {}) {
	if (!prefer.s.animation) return;

	const duration = options.duration ?? 1000 * 4;
	const animationEnd = Date.now() + duration;
	const defaults = {
		startVelocity: 30,
		spread: 360,
		ticks: 60,
		zIndex: os.claimZIndex('high'),
	} satisfies _confetti.Options;

	function randomInRange(min: number, max: number) {
		return Math.random() * (max - min) + min;
	}

	const interval = window.setInterval(() => {
		const timeLeft = animationEnd - Date.now();

		if (timeLeft <= 0) {
			return window.clearInterval(interval);
		}

		const particleCount = 50 * (timeLeft / duration);
		// since particles fall down, start a bit higher than random
		_confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 } }));
		_confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 } }));
	}, 250);
}