├── assets ├── fonts │ ├── steph-font.ttf │ └── steph-font-bold.ttf └── images │ ├── togepi-love.gif │ ├── togepi-crying.gif │ ├── togepi-happy.gif │ ├── togepi-sad-1.gif │ ├── togepi-sad-2.gif │ └── togepi-and-pikachu.gif ├── yay.html ├── index.html ├── README.md ├── script.js └── styles.css /assets/fonts/steph-font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanieran/valentines/HEAD/assets/fonts/steph-font.ttf -------------------------------------------------------------------------------- /assets/images/togepi-love.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanieran/valentines/HEAD/assets/images/togepi-love.gif -------------------------------------------------------------------------------- /assets/fonts/steph-font-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanieran/valentines/HEAD/assets/fonts/steph-font-bold.ttf -------------------------------------------------------------------------------- /assets/images/togepi-crying.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanieran/valentines/HEAD/assets/images/togepi-crying.gif -------------------------------------------------------------------------------- /assets/images/togepi-happy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanieran/valentines/HEAD/assets/images/togepi-happy.gif -------------------------------------------------------------------------------- /assets/images/togepi-sad-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanieran/valentines/HEAD/assets/images/togepi-sad-1.gif -------------------------------------------------------------------------------- /assets/images/togepi-sad-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanieran/valentines/HEAD/assets/images/togepi-sad-2.gif -------------------------------------------------------------------------------- /assets/images/togepi-and-pikachu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanieran/valentines/HEAD/assets/images/togepi-and-pikachu.gif -------------------------------------------------------------------------------- /yay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Thanks for being my Valentine! 7 | 8 | 9 | 10 |
11 | 12 | a cute picture of togepi 13 | 14 |

15 | Thanks for being my Valentine! ⸜(。˃ ᵕ ˂ )⸝♡ 16 |

17 |
18 | 19 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | will you be my valentine? 7 | 8 | 9 | 10 |
11 | 12 | a cute picture of togepi 13 | 14 |

15 | Will you be my Valentine? (˶ᵔ ᵕ ᵔ˶) 16 |

17 |
18 | 19 |
20 | 21 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 💖 Valentines Project 💖 2 | 3 | ### This is a cute little way you can ask someone to be your valentine! 🌹 4 | 5 | ## Features 6 | - 🥰 A few adorable Togepi gifs 7 | - ❌ Changing "No" button messages 8 | - 🔄 Resizing buttons after clicking 9 | 10 | ## How It Works 11 | This project asks your special someone to be their valentine, but we don't let them say no! (Consent is very important, this is very much just a silly for funsies thing that hopefully won't be used to harass anyone!!). 12 | 13 | ## Clone This Project 14 | 1. Clone this repository: `git clone https://github.com/stephanieran/valentines.git` 15 | 2. Open `index.html` in your browser. 16 | 17 | ## Try It Out & Send it to Someone! 18 | To mess around with this project and get a shareable link, check out this [link on CodeSandbox](temp link) where you can fork the project and modify it however you want (change up the gifs/messages) and grab a link to send to that someone special! 19 | 1. Open [CodeSandbox link](https://ffsvgv.csb.app/) 20 | 2. Click `Fork` in the upper right corner to create your own copy OR just copy the preview link and send it to your crush! 21 | 22 | My only ask is that you let me know what they say!🤭 -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | let noClicks = 1; 2 | const maxNoClicks = 4; 3 | const minNoScale = 0.65; 4 | let noScale = 1; 5 | let yesScale = 1; // This now tracks the scaling factor directly 6 | const gifElement = document.getElementById("togepi-gif"); 7 | const noButton = document.getElementById("no-btn"); 8 | const yesButton = document.getElementById("yes-btn"); 9 | const buttonContainer = document.querySelector(".btn-container"); 10 | const yesButtonStyle = window.getComputedStyle(yesButton); 11 | const maxYesWidth = parseFloat(yesButtonStyle.maxWidth); 12 | 13 | // array of gifs - in order 14 | const gifs = ["assets/images/togepi-happy.gif", "assets/images/togepi-sad-1.gif", "assets/images/togepi-sad-2.gif", "assets/images/togepi-crying.gif"]; 15 | // array of messages 16 | const buttonMessages = ["Are you sure??", "Pookie please", "Pookie PLEASE", "You can't do this to me!"]; 17 | 18 | // no button clicked 19 | noButton.addEventListener("click", () => { 20 | if (noClicks < maxNoClicks) { 21 | // change image 22 | gifElement.src = gifs[noClicks]; 23 | } 24 | 25 | // change no button text 26 | noButton.textContent = buttonMessages[noClicks % maxNoClicks]; 27 | 28 | // Adjust button width to fit text 29 | noButton.style.width = 'auto'; 30 | noButton.style.width = `${noButton.scrollWidth}px`; 31 | 32 | // decrease the size of the no button 33 | if (noScale > minNoScale) { 34 | noScale -= 0.1; 35 | noButton.style.transform = `scale(${noScale})`; 36 | } 37 | 38 | // Calculate the scaled width of the yesButton 39 | const baseWidth = parseFloat(yesButtonStyle.width); 40 | const scaledWidth = baseWidth * yesScale; // Reflects the actual visual size of the button 41 | 42 | console.log(`Scaled Width: ${scaledWidth}, Max Width: ${maxYesWidth}`); 43 | 44 | // Check if the scaled width is less than the max width 45 | if (scaledWidth < maxYesWidth) { 46 | yesScale += 0.5; // Increment scale by a smaller step 47 | yesButton.style.transform = `scale(${yesScale})`; 48 | 49 | // Get the current gap scale factor from CSS 50 | const rootStyles = getComputedStyle(document.documentElement); 51 | const gapScaleFactor = parseFloat(rootStyles.getPropertyValue("--gap-scale-factor")) || 250; 52 | 53 | // Adjust the gap dynamically 54 | const currentGap = parseFloat(buttonContainer.style.gap) || 20; 55 | const newGap = Math.sqrt(currentGap * gapScaleFactor); // Scale based on the factor 56 | buttonContainer.style.gap = `${newGap}px`; 57 | } 58 | 59 | // increment the number of clicks 60 | noClicks++; 61 | }); 62 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --gap-scale-factor: 250; 3 | } 4 | 5 | html, body { 6 | height: 100%; 7 | margin: 0; 8 | padding: 0; 9 | overflow: hidden; 10 | } 11 | 12 | body { 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: flex-start; 16 | text-align: center; 17 | margin: 0; 18 | padding: 75px 0; 19 | background: linear-gradient(#ffffff, #f9d6d6); 20 | font-family: "Steph", sans-serif; 21 | } 22 | 23 | @font-face { 24 | font-family: "Steph"; 25 | src: url("assets/fonts/steph-font.ttf"); 26 | font-weight: normal; 27 | } 28 | 29 | @font-face { 30 | font-family: "Steph"; 31 | src: url("assets/fonts/steph-font-bold.ttf"); 32 | font-weight: bold; 33 | } 34 | 35 | .container { 36 | max-width: 100%; 37 | margin: 20px auto 0 auto; 38 | } 39 | 40 | #togepi-gif { 41 | width: 500px; 42 | height: 400px; 43 | object-fit: cover; 44 | } 45 | 46 | h1 { 47 | font-size: 3rem; 48 | margin: 50px auto; 49 | } 50 | 51 | .btn-container { 52 | display: flex; 53 | justify-content: center; 54 | gap: 75px; 55 | } 56 | 57 | button { 58 | border-radius: 8px; 59 | min-width: 100px; 60 | max-width: 550px; 61 | border: none; 62 | cursor: pointer; 63 | padding: 10px 15px; 64 | white-space: nowrap; 65 | font-size: 1.3rem; 66 | font-weight: 600; 67 | transition: transform 0.1s ease; 68 | } 69 | 70 | button:hover { 71 | scale: 1.05; 72 | } 73 | 74 | #yes-btn { 75 | transform-origin: center top; 76 | color: white; 77 | background-color: #57915e; 78 | } 79 | 80 | #no-btn { 81 | color: white; 82 | background-color: #db4e4e; 83 | } 84 | 85 | @media (max-width: 1150px) { 86 | :root { 87 | --gap-scale-factor: 200; 88 | } 89 | 90 | body { 91 | padding-top: 70px; 92 | } 93 | .container { 94 | max-width: 100%; 95 | margin: 0; 96 | } 97 | 98 | #togepi-gif { 99 | width: 380px; 100 | height: 304px; 101 | object-fit: cover; 102 | } 103 | 104 | h1 { 105 | font-size: 2rem; 106 | margin: 50px auto; 107 | } 108 | 109 | .btn-container { 110 | display: flex; 111 | justify-content: center; 112 | gap: 20px; 113 | } 114 | 115 | button { 116 | border-radius: 8px; 117 | min-width: 100px; 118 | max-width: 400px; 119 | border: none; 120 | cursor: pointer; 121 | padding: 10px 12px; 122 | white-space: nowrap; 123 | font-size: 1rem; 124 | font-weight: 600; 125 | transition: transform 0.1s ease; 126 | } 127 | } 128 | 129 | @media (max-width: 600px) { 130 | :root { 131 | --gap-scale-factor: 50; 132 | } 133 | body { 134 | padding-top: 100px; 135 | } 136 | .container { 137 | max-width: 100%; 138 | margin: 0; 139 | } 140 | 141 | #togepi-gif { 142 | width: 300px; 143 | height: 240px; 144 | object-fit: cover; 145 | } 146 | 147 | h1 { 148 | font-size: 1.4rem; 149 | margin: 32px auto; 150 | } 151 | 152 | .btn-container { 153 | display: flex; 154 | justify-content: center; 155 | gap: 10px; 156 | } 157 | 158 | button { 159 | border-radius: 8px; 160 | min-width: 60px; 161 | max-width: 175px; 162 | border: none; 163 | cursor: pointer; 164 | padding: 10px 12px; 165 | white-space: nowrap; 166 | font-size: 0.8rem; 167 | font-weight: 600; 168 | transition: transform 0.1s ease; 169 | } 170 | } --------------------------------------------------------------------------------