JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<script src="https://www.gstatic.com/firebasejs/10.3.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.3.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.3.0/firebase-auth-compat.js"></script>
<html>
<head>
</head>
<body>
<div class="canvas">
<div id="totalCounter" class="total-counter"></div>
<div id="clap" onmouseover="clapHovered()" onmouseup="clapReleased('clapId-1')" onmousedown="clapPressed()" class="clap-container">
<i class="clap-icon fa-solid fa-hands-clapping"></i>
</div>
<div id="clicker" class="click-counter">
<span class="counter"></span>
</div>
<div id="sonar-clap" class="clap-container-sonar"></div>
<div id="particles" class="particles-container">
<div class="triangle">
<div class="square"></div>
</div>
<div class="triangle">
<div class="square"></div>
</div>
<div class="triangle">
<div class="square"></div>
</div>
<div class="triangle">
<div class="square"></div>
</div>
<div class="triangle">
<div class="square"></div>
</div>
</div>
<div id="particles-2" class="particles-container">
<div class="triangle">
<div class="square"></div>
</div>
<div class="triangle">
<div class="square"></div>
</div>
<div class="triangle">
<div class="square"></div>
</div>
<div class="triangle">
<div class="square"></div>
</div>
<div class="triangle">
<div class="square"></div>
</div>
</div>
<div id="particles-3" class="particles-container">
<div class="triangle">
<div class="square"></div>
</div>
...
CSS
.canvas {
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 300px;
position: relative;
.total-counter {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
position: absolute;
margin-top: 100px;
color: gray;
font-family: sans-serif;
font-size: 16px;
}
.total-counter.fader {
animation: fade-in 1400ms forwards;
}
.clap-container {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width: 60px;
height: 60px;
border: 1px solid rgba(0,0,0,.15);
border-radius: 50%;
z-index: 2;
background: #fff;
cursor: pointer;
.clap-icon {
font-size: 30px;
color: #03a87c;
width: 30px;
height: 30px;
}
}
.clap-container:hover {
border: 1px solid #03a87c;
}
.clap-container.scale {
animation: scaleAndBack 700ms forwards;
}
.click-counter {
display: flex;
justify-content: center;
align-items: center;
width: 35px;
height: 35px;
position: absolute;
top: 132px;
background-color: #03a87c;
border-radius: 50%;
z-index: 1;
.counter {
font-family: sans-serif;
font-size: 14px;
color: #fff;
}
}
.click-counter.first-active {
animation: first-bump-in 1s forwards;
}
.click-counter.active {
animation: bump-in 1s forwards;
}
.clap-container-sonar {
width: 60px;
height: 60px;
background: #03a87c;
border-radius: 50%;
position: absolute;
opacity: 0;
z-index: 0;
}
.hover-active {
animation: sonar-wave 2s forwards;
}
.particles-container {
display: flex;
...
JavaScript
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "<your-firestore-api-key>",
authDomain: "<your-firestore-auth-domain>",
projectId: "<your-firestore-project-id>",
storageBucket: "<your-firestore-storage-bucket>",
messagingSenderId: "<your-firestore-messaging-sender-id>",
appId: "<your-firestore-app-id>",
measurementId: "<your-firestore-measurement-id>"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
const auth = firebase.auth();
const collection = db.collection("claps")
// Setup authentication
var userid;
function authenticate() {
return auth.signInAnonymously()
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ...
console.log("catch", errorCode, errorMessage)
});
}
auth.onAuthStateChanged((user) => {
console.log("onAuthStateChanged:", user)
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/v8/firebase.User
userid = user.uid;
} else {
// User is signed out
userid = undefined
}
});
function getClaps(id) {
collection.doc(id).get().then((doc) => {
totalCount = 0
console.log(doc)
if (doc.exists) {
totalCount = doc.data().value
}
document.getElementById('totalCounter').innerText = totalCount;
})
}
// Adding claps
function saveClaps(id, count) {
collection.doc(id).set({
"value": firebase.firestore.FieldValue.increment(count)
}, {merge: true})
.then((docRef) => {
console.log("Document written with ID: ", docRef.id);
})
.catch((error) => {
console.error("Error adding claps: ", error);
})
}
// counter vars
let clapCounter = 0;
let totalCount = 0;
const minDeg = 1;
const maxDeg = 72;
const particlesClasses = [
{
class: "pop-top"
},
{
class: "pop-top-left"
},
{
class: "pop-top-right"
},
{
class: "pop-bottom-right"
},
{
...