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