From dac234a142c1cc7d604f7ad77bc8bf1c4e34d203 Mon Sep 17 00:00:00 2001 From: Ronnie Date: Mon, 26 May 2025 21:25:19 -0400 Subject: [PATCH] first commit --- README.md | 37 ++++++++ index.html | 79 ++++++++++++++++ script.js | 270 +++++++++++++++++++++++++++++++++++++++++++++++++++++ styles.css | 214 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 600 insertions(+) create mode 100644 README.md create mode 100644 index.html create mode 100644 script.js create mode 100644 styles.css diff --git a/README.md b/README.md new file mode 100644 index 0000000..fcb0010 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# HoldThisButton + +A fun, interactive web game: see how long you can hold the button. Challenge yourself and share your best time! + +## Features + +- Sleek dark-themed design +- Animated particle background +- Live timer while holding the button +- Random snarky messages +- Modern, clean UI +- Fully responsive design + +## How to Use + +1. Open `index.html` in your web browser +2. Press and hold the "Hold Me" button +3. Release to see your time and a snarky comment! + +## Technologies Used + +- HTML5 +- CSS3 +- JavaScript +- Particles.js for the animated background + +## Local Development + +Simply clone the repository and open `index.html` in your browser. No build process or dependencies required! + +```bash +git clone https://github.com/Ronniie/HoldThisButton.git +cd HoldThisButton +``` + +## License +MIT License - feel free to use this project for whatever you want! \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..1649e52 --- /dev/null +++ b/index.html @@ -0,0 +1,79 @@ + + + + + + HoldThisButton | How long can you hold it? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+

HoldThisButton

+
+ Ready to test your patience? +
+ +
+ 0.00s +
+ + + +
+ +
+ + +
+ + + + + + \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..292b7d7 --- /dev/null +++ b/script.js @@ -0,0 +1,270 @@ +// Initialize particles.js +particlesJS('particles-js', { + particles: { + number: { + value: 80, + density: { + enable: true, + value_area: 800 + } + }, + color: { + value: '#ffffff' + }, + shape: { + type: 'circle' + }, + opacity: { + value: 0.5, + random: false + }, + size: { + value: 3, + random: true + }, + line_linked: { + enable: true, + distance: 150, + color: '#ffffff', + opacity: 0.4, + width: 1 + }, + move: { + enable: true, + speed: 2, + direction: 'none', + random: false, + straight: false, + out_mode: 'out', + bounce: false + } + }, + interactivity: { + detect_on: 'canvas', + events: { + onhover: { + enable: true, + mode: 'grab' + }, + onclick: { + enable: true, + mode: 'push' + }, + resize: true + } + }, + retina_detect: true +}); + +// DOM elements +const holdButton = document.getElementById('holdButton'); +const timer = document.getElementById('timer'); +const message = document.getElementById('message'); +const resultContainer = document.getElementById('resultContainer'); +const result = document.getElementById('result'); + +// Variables +let startTime; +let timerInterval; +let isHolding = false; +let buttonText = holdButton.querySelector('span'); + +// Random messages while holding +const holdingMessages = [ + "Time is just a construct, right?", + "You're transcending reality.", + "The universe is watching you.", + "Is your arm okay?", + "Do you do this for sport?", + "You're redefining persistence.", + "You're officially holding reality together.", + "Just you and the void now.", + "What are you trying to prove?", + "I hope you're charging rent for your dedication.", + "This is borderline mythological.", + "Even statues blink eventually.", + "Are you trying to summon something?", + "You're writing history with your finger.", + "Blink twice if you're stuck.", + "You might be stuck in a time loop.", + "Legends start just like this.", + "Have you considered letting go... just kidding!", + "Still? I'm out of things to say!", + "I should be charging for this show.", + "You're more committed than some relationships.", + "Your screen is going to imprint your fingerprint.", + "Can we get a slow clap going?", + "You're raising the bar and then some.", + "I'm starting to believe you're a machine.", + "Even the code is impressed.", + "Reality might bend soon.", + "You're a digital monk now.", + "Still holding? Your screen says hi.", + "This is what dedication smells like... probably.", + "If effort was money, you'd be a billionaire.", + "Time is melting around you.", + "Every second, you enter deeper legend.", + "You may be achieving enlightenment.", + "This is your legacy now.", + "You clearly don’t fear cramps.", + "Heroes don't always wear capes.", + "I'm speechless... you're not.", + "You're holding like the Wi-Fi signal depends on it.", + "I think you unlocked ultra-hold mode.", + "Even gravity is impressed.", + "You're ignoring the laws of boredom.", + "This isn't even your final form.", + "The simulation is glitching just watching you.", + "You're becoming folklore.", + "You’ve reached the point of no return.", + "You broke the give-up meter.", + "You outlasted my motivational quotes.", + "Are you aiming for the Guinness World Record?", + "At this point, I'm emotionally invested.", + "You're becoming legend in real time.", + "All of this for what? Oh right—immortality.", + "Hold level: Ascended.", + "You're now an honorary statue.", + "Existential crises start here.", + "You're challenging the laws of patience.", + "Your willpower could power a small town.", + "You're so deep in, I can’t let you stop.", + "This is how digital devotion looks.", + "You’ll need a recovery arc after this.", + "Even I’m nervous for you.", + "You’ve reached ‘overachiever’ mode.", + "You're passing into the mythos now.", + "The button might be scared of you.", + "I think you just invented a new sport.", + "This is your endurance saga.", + "Still holding. The stars are aligning.", + "You’re one hold away from godhood.", + "Your thumb deserves its own biography.", + "There are monks less dedicated than this.", + "You’re holding onto greatness—literally.", + "You’ve entered the Matrix hold level.", + "Reality checks in... still holding.", + "Are your bones okay?", + "You're breaking records in another dimension.", + "You're now holding the universe together.", + "Your phone might evolve from this.", + "NASA might want to study you.", + "You're showing the world what's possible.", + "The screen is probably sweating now.", + "Who needs sleep when you have this?", + "I bet the device is questioning its purpose.", + "You're entering final form: Hold God.", + "Still? I'm writing a song about you.", + "This isn't holding—it's art.", + "I can feel the strain through the code.", + "You're distorting time with your will.", + "You're holding like a black hole grips light.", + "You may have just glitched reality.", + "You’re now part of the code.", + "A statue couldn’t keep up with you.", + "You’re outperforming machines.", + "Your name shall echo through holding halls.", + "Still here? You’re writing digital lore.", + "This is holdvana. Welcome.", + "If there was a throne, you'd sit on it.", + "You’ve held longer than most people dream.", + "Reality salutes your grip.", + "You're in another timeline now.", + "I hope this gets written in history books.", + "You're unshakable. Literally.", + "I stopped counting. You're still holding.", + "A galaxy was born during this hold." +]; + + +// Snarky result messages +const resultMessages = [ + "You should screenshot this as no one will believe you", + "That's... actually pretty impressive", + "Did you use tape or something?", + "Your finger must be numb by now", + "That's a new world record... probably", + "Are you okay? That's a long time", + "Your patience is... concerning", + "Did you fall asleep?", + "That's dedication right there", + "Your finger deserves a medal" +]; + +// Format time +function formatTime(ms) { + return (ms / 1000).toFixed(2) + 's'; +} + +// Update timer display +function updateTimer() { + const currentTime = Date.now(); + const elapsedTime = currentTime - startTime; + timer.textContent = formatTime(elapsedTime); +} + +// Get random message from array +function getRandomMessage(array) { + return array[Math.floor(Math.random() * array.length)]; +} + +// Change message with animation +function changeMessage(newMessage) { + message.classList.remove('changed'); + void message.offsetWidth; // Trigger reflow + message.textContent = newMessage; + message.classList.add('changed'); +} + +// Start holding +holdButton.addEventListener('mousedown', () => { + if (!isHolding) { + isHolding = true; + startTime = Date.now(); + timerInterval = setInterval(updateTimer, 10); + resultContainer.classList.remove('show'); + buttonText.textContent = "Holding..."; + + // Start random messages + const messageInterval = setInterval(() => { + if (isHolding) { + changeMessage(getRandomMessage(holdingMessages)); + } else { + clearInterval(messageInterval); + } + }, 3000); + } +}); + +// Stop holding +holdButton.addEventListener('mouseup', () => { + if (isHolding) { + isHolding = false; + clearInterval(timerInterval); + const finalTime = Date.now() - startTime; + + // Show result + result.textContent = `${formatTime(finalTime)} - ${getRandomMessage(resultMessages)}`; + resultContainer.classList.add('show'); + + // Reset message and button text + message.textContent = "Ready to try again?"; + buttonText.textContent = "Hold Me"; + } +}); + +// Prevent context menu on long press +holdButton.addEventListener('contextmenu', (e) => { + e.preventDefault(); +}); + +// Handle touch events for mobile +holdButton.addEventListener('touchstart', (e) => { + e.preventDefault(); + holdButton.dispatchEvent(new MouseEvent('mousedown')); +}); + +holdButton.addEventListener('touchend', (e) => { + e.preventDefault(); + holdButton.dispatchEvent(new MouseEvent('mouseup')); +}); \ No newline at end of file diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..ae8cb12 --- /dev/null +++ b/styles.css @@ -0,0 +1,214 @@ +/* reset some default browser styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +/* main page styles */ +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: #0f172a; + position: relative; + overflow: hidden; +} + +/* particles container */ +#particles-js { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 1; + opacity: 0.3; +} + +/* center everything */ +.container { + text-align: center; + padding: 2rem; + position: relative; + z-index: 2; + max-width: 800px; + width: 90%; + background: rgba(30, 41, 59, 0.7); + backdrop-filter: blur(20px); + border-radius: 24px; + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); +} + +/* make the title look nice and fade in */ +.title { + font-size: 4rem; + margin-bottom: 2rem; + color: #fff; + font-weight: 800; + background: linear-gradient(135deg, #60a5fa, #c084fc); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + opacity: 0; + animation: fadeIn 1s ease forwards; + letter-spacing: -0.02em; +} + +/* message container styling */ +.message-container { + background: rgba(255, 255, 255, 0.05); + padding: 1.5rem; + border-radius: 16px; + margin-bottom: 2rem; + transition: all 0.3s ease; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.message { + font-size: 1.5rem; + color: #e2e8f0; + display: inline-block; + transition: all 0.3s ease; + font-weight: 500; +} + +/* timer container styling */ +.timer-container { + margin-bottom: 2rem; + padding: 1rem; + background: rgba(255, 255, 255, 0.05); + border-radius: 16px; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.timer { + font-size: 4rem; + font-weight: 700; + color: #60a5fa; + text-shadow: 0 0 20px rgba(96, 165, 250, 0.3); + font-variant-numeric: tabular-nums; +} + +/* hold button styling */ +.hold-button { + background: linear-gradient(135deg, #60a5fa, #c084fc); + border: none; + padding: 2rem 4rem; + font-size: 2rem; + color: white; + border-radius: 16px; + cursor: pointer; + transition: all 0.3s ease; + font-weight: 600; + box-shadow: 0 0 30px rgba(96, 165, 250, 0.3); + margin-bottom: 2rem; + width: 100%; + max-width: 400px; + position: relative; + overflow: hidden; +} + +.hold-button::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(135deg, #c084fc, #60a5fa); + opacity: 0; + transition: opacity 0.3s ease; + z-index: 1; +} + +.hold-button:hover::before { + opacity: 1; +} + +.hold-button:hover { + transform: translateY(-2px); + box-shadow: 0 0 40px rgba(96, 165, 250, 0.4); +} + +.hold-button:active { + transform: translateY(0); + box-shadow: 0 0 20px rgba(96, 165, 250, 0.2); +} + +.hold-button span { + position: relative; + z-index: 2; + color: white; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); +} + +/* result container styling */ +.result-container { + background: rgba(255, 255, 255, 0.05); + padding: 1.5rem; + border-radius: 16px; + margin-bottom: 2rem; + opacity: 0; + transform: translateY(20px); + transition: all 0.3s ease; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.result-container.show { + opacity: 1; + transform: translateY(0); +} + +.result { + font-size: 1.5rem; + color: #e2e8f0; + font-weight: 500; +} + +/* footer styling */ +.footer { + margin-top: 2rem; + padding-top: 2rem; + border-top: 1px solid rgba(255, 255, 255, 0.1); +} + +.website { + color: #94a3b8; + font-size: 1rem; + font-weight: 500; +} + +/* fade in animation for the title */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* message change animation */ +@keyframes messageChange { + 0% { + transform: scale(1); + opacity: 1; + } + 50% { + transform: scale(1.05); + opacity: 0.5; + } + 100% { + transform: scale(1); + opacity: 1; + } +} + +.message.changed { + animation: messageChange 0.3s ease; +} \ No newline at end of file