Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/widget/chatConfetti.ts
5251 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as dom from '../../../../../base/browser/dom.js';
7
8
const confettiColors = [
9
'#f44336', '#e91e63', '#9c27b0', '#673ab7',
10
'#3f51b5', '#2196f3', '#03a9f4', '#00bcd4',
11
'#009688', '#4caf50', '#8bc34a', '#ffeb3b',
12
'#ffc107', '#ff9800', '#ff5722'
13
];
14
15
let activeOverlay: HTMLElement | undefined;
16
17
/**
18
* Triggers a confetti animation inside the given container element.
19
*/
20
export function triggerConfetti(container: HTMLElement) {
21
if (activeOverlay) {
22
return;
23
}
24
25
const overlay = dom.$('.chat-confetti-overlay');
26
overlay.style.position = 'absolute';
27
overlay.style.inset = '0';
28
overlay.style.pointerEvents = 'none';
29
overlay.style.overflow = 'hidden';
30
overlay.style.zIndex = '1000';
31
container.appendChild(overlay);
32
activeOverlay = overlay;
33
34
const { width, height } = container.getBoundingClientRect();
35
for (let i = 0; i < 250; i++) {
36
const part = dom.$('.chat-confetti-particle');
37
part.style.position = 'absolute';
38
part.style.width = `${Math.random() * 8 + 4}px`;
39
part.style.height = `${Math.random() * 8 + 4}px`;
40
part.style.backgroundColor = confettiColors[Math.floor(Math.random() * confettiColors.length)];
41
part.style.borderRadius = Math.random() > 0.5 ? '50%' : '0';
42
part.style.left = `${Math.random() * width}px`;
43
part.style.top = '-10px';
44
part.style.opacity = '1';
45
46
overlay.appendChild(part);
47
48
const targetX = (Math.random() - 0.5) * width * 0.8;
49
const targetY = Math.random() * height * 0.8 + height * 0.1;
50
const rotation = Math.random() * 720 - 360;
51
const duration = Math.random() * 1000 + 1500;
52
const delay = Math.random() * 400;
53
54
part.animate([
55
{
56
transform: 'translate(0, 0) rotate(0deg)',
57
opacity: 1
58
},
59
{
60
transform: `translate(${targetX * 0.5}px, ${targetY * 0.5}px) rotate(${rotation * 0.5}deg)`,
61
opacity: 1,
62
offset: 0.3
63
},
64
{
65
transform: `translate(${targetX}px, ${targetY}px) rotate(${rotation}deg)`,
66
opacity: 1,
67
offset: 0.75
68
},
69
{
70
transform: `translate(${targetX * 1.1}px, ${targetY + 40}px) rotate(${rotation + 30}deg)`,
71
opacity: 0
72
}
73
], {
74
duration,
75
delay,
76
easing: 'linear',
77
fill: 'forwards'
78
});
79
}
80
81
setTimeout(() => {
82
overlay.remove();
83
activeOverlay = undefined;
84
}, 3000);
85
}
86
87