feat(#23): triggering fireworks when everyone's on board 🎆

This commit is contained in:
OllyNicholass
2024-02-09 01:31:05 +00:00
parent 04d78a1aad
commit f671236e18
3 changed files with 135 additions and 9 deletions
+102
View File
@@ -0,0 +1,102 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { writable } from 'svelte/store';
type Rocket = {
id: number;
x: string;
y: string;
colour: string;
}
const rockets = writable<Rocket[]>([]);
let rocketIntervalId;
let rocketCount: number = 0;
function randomLocation(): { x: string; y: string;} {
return {
x: `${Math.random() * window.innerWidth - window.innerWidth / 2}px`,
y: `${Math.random() * window.innerHeight - window.innerHeight / 2}px`,
};
}
function randomColour(): string {
return `hsl(${Math.floor(Math.random() * 361)}, 100%, 50%)`;
}
function randomTimer(): number {
return Math.floor(Math.random() * (150 - 30 + 1)) + 30;
}
function setupRocket(): Rocket {
const colour = randomColour();
const { x, y } = randomLocation();
const newRocket: Rocket = { id: rocketCount++, x, y, colour };
return newRocket;
}
function launchRockets() {
const newRocket = setupRocket();
rockets.update((currentRockets) => {
if (currentRockets.length > 25) {
// only keep 100 rockets
currentRockets.shift();
}
return [...currentRockets, newRocket]
});
}
onMount(() => {
rocketIntervalId = setInterval(launchRockets, randomTimer());
setTimeout(()=>{ clearInterval(rocketIntervalId) }, 13000)
});
onDestroy(() => {
clearInterval(rocketIntervalId);
});
</script>
<style>
.rocket {
--x: 0;
--y: 0;
background-color: rebeccapurple;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
height: 5px;
width: 5px;
z-index: -1;
}
.rocket.move {
animation: move 1000ms linear forwards;
}
@keyframes move {
to {
transform: translate(var(--x), var(--y));
}
95% {
opacity: 1;
}
100% {
opacity: 0;
}
}
</style>
<div class="launch-pad">
{#each $rockets as rocket (rocket.id)}
<span
class="rocket move"
style="
--x: {rocket.x};
--y: {rocket.y};
background: {rocket.colour};
"
></span>
{/each}
</div>
+26 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
const changesLog = [ const changesLog = [
{ timestamp: '2024-01-05T00:00:00', message: 'Added the ability to kick a user' }, { timestamp: '2024-01-05T00:00:00', message: 'Added the ability to kick a user' },
{ timestamp: '2024-01-05T00:00:00', message: 'Added update notes' }, { timestamp: '2024-01-05T00:00:00', message: 'Added update notes' }
]; ];
let newChanges = []; let newChanges = [];
@@ -36,6 +36,7 @@
import EstimateGroupsList from '../../../components/EstimateGroupsList.svelte'; import EstimateGroupsList from '../../../components/EstimateGroupsList.svelte';
import Modal from '../../../components/Modal.svelte'; import Modal from '../../../components/Modal.svelte';
import Estimates from '../../../components/Estimates.svelte'; import Estimates from '../../../components/Estimates.svelte';
import FireworkShow from '../../../components/FireworkShow.svelte';
import { connectToWebSocket, sendMessage, generateId } from '../estimation.js'; import { connectToWebSocket, sendMessage, generateId } from '../estimation.js';
@@ -89,7 +90,9 @@
let showEstimates = false; let showEstimates = false;
let disableEstimates: boolean = false; let disableEstimates: boolean = false;
let audioElement; let audioElement;
let fireworks;
let selectedCardSet; let selectedCardSet;
let showFireworks = false;
function closeModal() { function closeModal() {
showModal = false; showModal = false;
@@ -142,6 +145,16 @@
sendMessage(socket, { roomId: data.roomId, type: 'restart-estimation' }); sendMessage(socket, { roomId: data.roomId, type: 'restart-estimation' });
} }
function areEstimatesSame(estimateGroups: { [key: number | string]: string[] }): boolean {
const estimates = Object.keys(estimateGroups);
const users = Object.values(estimateGroups);
const allUsers = users.flat();
if (allUsers.length > 2 && estimates.length === 1) {
return true;
}
}
function onMessageReceived(message) { function onMessageReceived(message) {
if (message.type === 'user-joined') { if (message.type === 'user-joined') {
sendMessage(socket, { type: 'get-user-estimates' }); sendMessage(socket, { type: 'get-user-estimates' });
@@ -166,10 +179,17 @@
users = users.filter((user) => user.userId !== message.userId); users = users.filter((user) => user.userId !== message.userId);
} else if (message.type === 'estimation-closed') { } else if (message.type === 'estimation-closed') {
estimateGroups = message.groupedEstimates; estimateGroups = message.groupedEstimates;
showFireworks = areEstimatesSame(estimateGroups);
if (showFireworks) {
fireworks.play();
}
showRestartButton = true; showRestartButton = true;
showEstimates = true; showEstimates = true;
disableEstimates = true; disableEstimates = true;
} else if (message.type === 'estimation-restarted') { } else if (message.type === 'estimation-restarted') {
showFireworks = false;
fireworks.pause();
fireworks.currentTime = 0;
estimateGroups = {}; estimateGroups = {};
showRestartButton = false; showRestartButton = false;
showEstimates = false; showEstimates = false;
@@ -244,7 +264,12 @@
<EstimateGroupsList {estimateGroups} /> <EstimateGroupsList {estimateGroups} />
{/if} {/if}
{#if showFireworks}
<FireworkShow />
{/if}
<audio src="/call-to-attention-50-percent-volume.mp3" bind:this={audioElement} /> <audio src="/call-to-attention-50-percent-volume.mp3" bind:this={audioElement} />
<audio src="/fireworks.mp3" bind:this={fireworks} />
{#if showTooltip && newChanges.length > 0} {#if showTooltip && newChanges.length > 0}
<div id="tooltip-container" on:click={toggleTooltip}> <div id="tooltip-container" on:click={toggleTooltip}>
@@ -254,7 +279,6 @@
<li>{new Date(change.timestamp).toLocaleDateString()}: {change.message}</li> <li>{new Date(change.timestamp).toLocaleDateString()}: {change.message}</li>
{/each} {/each}
</ul> </ul>
</div> </div>
{/if} {/if}
Binary file not shown.