Version: v.0.1A
Cupid's Shot is a personalized, interactive, and emotionally resonant web experience designed to convey a heartfelt love confession. The project combines a beautiful, animated canvas background with a branching narrative and atmospheric music to create a memorable and impactful single-page application. It's a digital love letter for the modern age.
The experience is a linear progression through several key emotional stages.
- Interactive Narrative: A story-driven experience that guides the user through a romantic confession.
- Branching Paths: The story's conclusion and background music change based on the user's response, leading to different endings.
- Dynamic Animated Background: A visually stunning background created with the HTML5 Canvas API, featuring pulsating particles, flowing waves, and gentle vortexes in a dark, romantic theme.
- Atmospheric Audio: Includes two separate music tracks that fade in and out to match the emotional tone of the narrative path.
- Responsive Design: The interface is fully responsive and optimized for a seamless experience on desktops, tablets, and mobile devices.
- Personalizable: The core text in
index.htmlcan be easily edited to personalize the message, including the recipient's name. - Pure Frontend: Runs entirely in the browser with no server-side dependencies, making it easy to host or share.
- A modern web browser (e.g., Chrome, Firefox, Safari, Edge).
- (Optional) A local web server for development to avoid potential browser restrictions on loading local files (
file:///).
-
Clone the repository:
git clone https://github.com/Jacqquard/CupidsShot.git cd CupidsShot -
(Optional) Personalize the message:
- Open
index.htmlin a text editor. - Find and replace the placeholder
{girl's name}with the desired name. - You can also edit the text within the
<p>tags to customize the confession.
- Open
-
Open the application:
- Simply open the
index.htmlfile in your web browser. - For the best experience without browser security issues (especially for audio), run it from a local server. If you have Python, you can run:
# For Python 3 python -m http.serverThen, navigate to
http://localhost:8000in your browser. - Simply open the
Cupid's Shot/
β
βββ index.html # The main file: structure, text content, and narrative slides.
βββ script.js # Core logic: slide transitions, canvas animation, and audio management.
βββ style.css # All styles: layout, theme, animations, and responsive design.
β
βββ img/
β βββ heart.png # Animated heart icon used in the loader screen.
β βββ location.png # img displayed in the positive outcome of the story.
β
βββ music/
βββ music.mp3 # The main, uplifting background music track.
βββ music1.mp3 # The alternative, melancholic music for the other ending.
This file defines the entire structure of the experience. It is not a traditional webpage, but a series of "slides" that are shown or hidden by JavaScript.
- Loader Screen: The initial screen (
#loader) with a beating heart animation that hides the page while assets load. - Canvas & Frosted Glass: The
<canvas>element for the background animation and a<div>for abackdrop-filtereffect. - Slides (
.slide): Each slide is adivrepresenting a step in the story. They contain a message box (.message-box) and buttons (.fancy-button). - Branching Logic: The structure includes separate slides for the different outcomes:
#slide-7-yesand#slide-8-yesfor the positive path.#slide-7-noand#slide-8-no-yesfor the negative path.
- Assets: Contains
<audio>tags to declare the music sources and<img>tags for imgs used in the story.
This file contains all the client-side logic that brings the story to life.
- Canvas Animation: The top section of the script is dedicated to the background.
- It initializes a canvas context and populates arrays of
particles,waves, andvortexeswith random properties. - The
animate()function runs on arequestAnimationFrameloop, continuously redrawing the canvas. It calculates the position and appearance of each element based on time, creating a living, dynamic visual.
- It initializes a canvas context and populates arrays of
- State Management: Simple variables like
activeSlideIdandaudioTransitionInProgresscontrol the current state of the application, preventing user actions from overlapping with animations. - Core Narrative Flow:
showSlide(slideId): Manages which slide is visible. It handles the CSS classes that trigger the fade-in/fade-out animations for slides and their content (message boxes, buttons).nextSlide(context, option): This is the central navigation function. It determines which slide to show next based on the button the user clicked, implementing the story's branching logic.startCountdown(): Controls the dramatic countdown sequence before the final confession is revealed.
- Audio Management:
fadeAudio(audio, targetVolume, duration, callback): A crucial function for atmosphere. It smoothly fades audio in or out over a set duration, allowing for seamless transitions between the happy and sad music tracks without abrupt cuts.
This file defines the entire aesthetic of the project.
- Theme & Atmosphere: Establishes the dark, romantic color palette (
#000000,#5c0101) and usestext-shadowandbox-shadowto create a glowing, ethereal effect. - Layout: Uses modern CSS like Flexbox to perfectly center content both vertically and horizontally, ensuring the presentation is clean and focused.
- Animations & Transitions:
@keyframesare defined for theheartbeateffect on the loading icon and theloadingbar animation.transitionproperties are used extensively to create smooth, professional-looking fades and movements as slides and their elements appear and disappear.
- Component Styling: Provides distinct styles for each component: the
.message-boxwith its semi-transparent background, the stylish.fancy-buttonwith hover and active states, and the loader. - Responsiveness:
@mediaqueries adjust font sizes, padding, and layout (e.g., stacking buttons vertically) to ensure the experience is just as impactful on small mobile screens as it is on a large desktop monitor.
The project is a classic single-page application (SPA) running entirely on the frontend.
- Loading: On page load,
index.htmldisplays a loading screen (.loader-screen) and a preloader animation styled by CSS. The backgroundscript.jsbegins loading assets. - Initialization: Once the window is loaded,
script.jshides the loader and fades in the canvas background and the first slide of the story. The canvas animation begins its continuous loop. - User-Driven Progression: The user interacts with the application by clicking buttons. Each click triggers a JavaScript function (e.g.,
nextSlide). - DOM Manipulation: The script doesn't reload the page. Instead, it manipulates the DOM by changing CSS classes on the slide
divs. This triggers the fade-out of the old slide and the fade-in of the new one. - Conditional Logic: At the story's climax, the
nextSlidefunction checks which button was pressed ("Yes" or "No"). This choice determines which slide ID is passed toshowSlidenext and also triggers thefadeAudiofunction to transition to the appropriate music track, creating a dynamic and emotionally responsive experience.
The architecture elegantly combines HTML for content, CSS for presentation and animation, and JavaScript for the logic that ties it all together into a cohesive and interactive narrative.
This project is distributed under the MIT License.

