Advertisement
chayanforyou

bubblify

May 19th, 2025
429
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 10.57 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <title>Bubble Solution Calculator</title>
  6.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7.   <style>
  8.     body {
  9.       font-family: system-ui, sans-serif;
  10.       background: #f0f7fb;
  11.       display: flex;
  12.       justify-content: center;
  13.       padding: 40px 16px;
  14.       margin: 0;
  15.     }
  16.     .card {
  17.       position: relative;
  18.       background: white;
  19.       padding: 24px;
  20.       border-radius: 16px;
  21.       box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  22.       max-width: 600px;
  23.       width: 100%;
  24.       box-sizing: border-box;
  25.     }
  26.     .lang-toggle {
  27.       position: absolute;
  28.       top: 16px;
  29.       right: 16px;
  30.     }
  31.     .lang-toggle button {
  32.       padding: 6px 12px;
  33.       font-size: 14px;
  34.       border: 1px solid #007BFF;
  35.       background: #fff;
  36.       color: #007BFF;
  37.       border-radius: 6px;
  38.       cursor: pointer;
  39.     }
  40.     h2 {
  41.       text-align: center;
  42.       margin-bottom: 24px;
  43.       font-size: 1.5rem;
  44.       display: flex;
  45.       align-items: center;
  46.       justify-content: center;
  47.       gap: 0.5rem;
  48.     }
  49.     label {
  50.       font-weight: 600;
  51.       display: block;
  52.       margin-top: 15px;
  53.     }
  54.     input[type="number"] {
  55.       width: 100%;
  56.       padding: 10px;
  57.       margin-top: 5px;
  58.       font-size: 16px;
  59.       border-radius: 6px;
  60.       border: 1px solid #ccc;
  61.       box-sizing: border-box;
  62.     }
  63.     .unit-button-container {
  64.       display: flex;
  65.       align-items: flex-end;
  66.       justify-content: space-between;
  67.       margin-top: 10px;
  68.       flex-wrap: wrap;
  69.       gap: 10px;
  70.     }
  71.     .unit-selection {
  72.       display: flex;
  73.       gap: 20px;
  74.       flex-wrap: wrap;
  75.     }
  76.     .unit-selection label {
  77.       font-weight: normal;
  78.     }
  79.     button {
  80.       padding: 12px 20px;
  81.       font-size: 16px;
  82.       background-color: #007BFF;
  83.       color: white;
  84.       border: none;
  85.       border-radius: 6px;
  86.       cursor: pointer;
  87.       white-space: nowrap;
  88.     }
  89.     .divider {
  90.       height: 1px;
  91.       background: #ccc;
  92.       margin: 30px 0 20px;
  93.     }
  94.     .result {
  95.       background: #EAF4FE;
  96.       padding: 20px;
  97.       border-radius: 10px;
  98.     }
  99.     .result h3 {
  100.       margin-top: 0;
  101.       display: flex;
  102.       align-items: center;
  103.       gap: 0.5rem;
  104.     }
  105.     .result ul {
  106.       list-style: none;
  107.       padding-left: 0;
  108.     }
  109.     .result ul li {
  110.       position: relative;
  111.       padding-left: 2em;
  112.       margin-bottom: 6px;
  113.     }
  114.     .result ul li::before {
  115.       content: '';
  116.       position: absolute;
  117.       left: 0.6em;
  118.       top: 0.5em;
  119.       width: 8px;
  120.       height: 8px;
  121.       border-radius: 50%;
  122.     }
  123.     .result ul li:nth-child(1)::before { background-color: #6c4f2c; }
  124.     .result ul li:nth-child(2)::before { background-color: #0056b3; }
  125.     .result ul li:nth-child(3)::before { background-color: #00796b; }
  126.     .result ul li:nth-child(4)::before { background-color: #6a1b9a; }
  127.  
  128.     .instructions {
  129.       background: #FFF7E1;
  130.       padding: 20px;
  131.       border-left: 5px solid #F7C132;
  132.       margin-top: 25px;
  133.       border-radius: 10px;
  134.     }
  135.     .instructions h3 {
  136.       margin-top: 0;
  137.       display: flex;
  138.       align-items: center;
  139.       gap: 0.5rem;
  140.     }
  141.     ol {
  142.       padding-left: 20px;
  143.     }
  144.     #instruction-steps {
  145.       list-style: none;
  146.       padding-left: 0;
  147.     }
  148.     #instruction-steps li {
  149.       position: relative;
  150.       left: 0.1em;
  151.       padding-left: 1.2em;
  152.     }
  153.     .list-num {
  154.       position: absolute;
  155.       left: 0;
  156.       font-weight: normal;
  157.     }
  158.     @media (max-width: 480px) {
  159.       .unit-button-container {
  160.         flex-direction: column;
  161.         align-items: stretch;
  162.       }
  163.       .unit-selection {
  164.         justify-content: space-around;
  165.       }
  166.       button {
  167.         width: 100%;
  168.       }
  169.     }
  170.   </style>
  171. </head>
  172. <body>
  173.   <div class="card" id="capture-area">
  174.     <div class="lang-toggle">
  175.       <button onclick="toggleLanguage()" id="lang-btn"></button>
  176.     </div>
  177.     <h2 id="title"></h2>
  178.  
  179.     <label for="amount" id="label-amount"></label>
  180.     <input type="number" id="amount" value="1" min="0.1" step="0.1">
  181.  
  182.     <div class="unit-button-container">
  183.       <div class="unit-selection">
  184.         <label><input type="radio" name="unit" value="l" checked> <span id="label-liter"></span></label>
  185.         <label><input type="radio" name="unit" value="ml"> <span id="label-ml"></span></label>
  186.       </div>
  187.       <button onclick="calculateSolution()" id="calc-btn"></button>
  188.     </div>
  189.  
  190.     <div class="divider"></div>
  191.  
  192.     <div class="result" id="result"></div>
  193.  
  194.     <div class="instructions">
  195.       <h3 id="instructions-title"></h3>
  196.       <ol id="instruction-steps"></ol>
  197.     </div>
  198.   </div>
  199.  
  200.   <script>
  201.     const translations = {
  202.       en: {
  203.         title: 'đŸĢ§ Bubble Solution Calculator',
  204.         amountLabel: 'Enter Total Solution Amount',
  205.         liter: 'Liter (L)',
  206.         ml: 'Milliliter (ml)',
  207.         button: 'Calculate Ingredients',
  208.         ingredientsTitle: '🧴 Required Ingredients',
  209.         restLine: 'Let the mixture rest for at least 1 hour for best bubbles!',
  210.         items: [
  211.           'Warm Water',
  212.           'Dish Soap',
  213.           'Glycerin (or Sugar/Corn Syrup)',
  214.           'Baking Powder (optional)'
  215.         ],
  216.         instructionsTitle: 'đŸ§Ē Instructions',
  217.         instructions: [
  218.           'Pour the calculated amount of warm water into a large container.',
  219.           'Add the measured dish soap and stir gently to avoid bubbles.',
  220.           'Mix in the glycerin (or sugar/corn syrup).',
  221.           'Stir in the baking powder (optional).',
  222.           'Let the mixture rest for at least 1 hour or overnight for best results.',
  223.           'Enjoy making big and strong bubbles!'
  224.         ]
  225.       },
  226.       bn: {
  227.         title: 'đŸĢ§ āĻŦāĻžāĻŦāϞ āϏāĻ˛ā§āϝ⧁āĻļāύ āĻ•ā§āϝāĻžāϞāϕ⧁āϞ⧇āϟāϰ',
  228.         amountLabel: 'āĻŽā§‹āϟ āĻŦāĻžāĻŦāϞ āϏāĻ˛ā§āϝ⧁āĻļāύ⧇āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āϞāĻŋāϖ⧁āύ',
  229.         liter: 'āϞāĻŋāϟāĻžāϰ (L)',
  230.         ml: 'āĻŽāĻŋāϞāĻŋāϞāĻŋāϟāĻžāϰ (ml)',
  231.         button: 'āωāĻĒāĻžāĻĻāĻžāύ āĻšāĻŋāϏāĻžāĻŦ āĻ•āϰ⧁āύ',
  232.         ingredientsTitle: '🧴 āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āωāĻĒāĻžāĻĻāĻžāύ',
  233.         restLine: 'āϏāĻ°ā§āĻŦā§‹āĻ¤ā§āϤāĻŽ āĻŦāĻžāĻŦāϞ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāĻ¨ā§āϏ⧇āϰ āϜāĻ¨ā§āϝ āĻ•āĻŽāĻĒāĻ•ā§āώ⧇ ā§§ āϘāĻŖā§āϟāĻž āĻŦāĻŋāĻļā§āϰāĻžāĻŽ āĻĻāĻŋāύāĨ¤',
  234.         items: [
  235.           'āωāĻˇā§āĻŖ āĻĒāĻžāύāĻŋ',
  236.           'āĻĄāĻŋāĻļ āϏ⧋āĻĄāĻž',
  237.           'āĻ—ā§āϞāĻŋāϏāĻžāϰāĻŋāύ (āĻ…āĻĨāĻŦāĻž āϚāĻŋāύāĻŋ/āϭ⧁āĻŸā§āϟāĻžāϰ āϏāĻŋāϰāĻžāĻĒ)',
  238.           'āĻŦ⧇āĻ•āĻŋāĻ‚ āĻĒāĻžāωāĻĄāĻžāϰ (āϐāĻšā§āĻ›āĻŋāĻ•)'
  239.         ],
  240.         instructionsTitle: 'đŸ§Ē āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻžāĻŦāϞ⧀',
  241.         instructions: [
  242.           'āωāĻˇā§āĻŖ āĻĒāĻžāύāĻŋ āĻāĻ•āϟāĻŋ āĻŦāĻĄāĻŧ āĻĒāĻžāĻ¤ā§āϰ⧇ āύāĻŋāύāĨ¤',
  243.           'āĻĄāĻŋāĻļ āϏ⧋āĻĄāĻž āĻŽāĻŋāĻļāĻŋā§Ÿā§‡ āφāĻ¸ā§āϤ⧇ āύāĻžāĻĄāĻŧ⧁āύ āϝāĻžāϤ⧇ āĻĢ⧇āύāĻž āύāĻž āωāϠ⧇āĨ¤',
  244.           'āĻ—ā§āϞāĻŋāϏāĻžāϰāĻŋāύ (āĻ…āĻĨāĻŦāĻž āϚāĻŋāύāĻŋ/āϭ⧁āĻŸā§āϟāĻžāϰ āϏāĻŋāϰāĻžāĻĒ) āĻŽā§‡āĻļāĻžāύāĨ¤',
  245.           'āĻŦ⧇āĻ•āĻŋāĻ‚ āĻĒāĻžāωāĻĄāĻžāϰ (āϐāĻšā§āĻ›āĻŋāĻ•) āĻĻāĻŋā§Ÿā§‡ āĻŽāĻŋāĻļāĻŋā§Ÿā§‡ āύāĻŋāύāĨ¤',
  246.           'āĻ•āĻŽāĻĒāĻ•ā§āώ⧇ ā§§ āϘāĻŖā§āϟāĻž āĻŦāĻž āϰāĻžāϤāĻ­āϰ āϰ⧇āϖ⧇ āĻĻāĻŋāύāĨ¤',
  247.           'āϤāĻžāϰāĻĒāϰ āĻŽāϜāĻžāϰ āĻŦāĻžāĻŦāϞ āϤ⧈āϰāĻŋ āωāĻĒāĻ­ā§‹āĻ— āĻ•āϰ⧁āύ!'
  248.         ]
  249.       }
  250.     };
  251.  
  252.     let currentLang = 'en';
  253.  
  254.     function toggleLanguage() {
  255.       currentLang = currentLang === 'en' ? 'bn' : 'en';
  256.       setLanguage();
  257.       calculateSolution();
  258.     }
  259.  
  260.     function setLanguage() {
  261.       const t = translations[currentLang];
  262.       document.getElementById('title').innerText = t.title;
  263.       document.getElementById('label-amount').innerText = t.amountLabel;
  264.       document.getElementById('label-liter').innerText = t.liter;
  265.       document.getElementById('label-ml').innerText = t.ml;
  266.       document.getElementById('calc-btn').innerText = t.button;
  267.       document.getElementById('instructions-title').innerText = t.instructionsTitle;
  268.       document.getElementById('lang-btn').innerText = currentLang === 'en' ? 'āĻŦāĻžāĻ‚āϞāĻž' : 'English';
  269.  
  270.       document.getElementById('instruction-steps').innerHTML = t.instructions.map((text, index) => {
  271.         const num = currentLang === 'bn' ? convertToBanglaNumber(index + 1) : index + 1;
  272.         return `<li><span class="list-num">${num}.</span> ${text}</li>`;
  273.       }).join('');
  274.     }
  275.  
  276.     function convertToBanglaNumber(str) {
  277.       const bnDigits = ['ā§Ļ', 'ā§§', '⧍', 'ā§Š', 'ā§Ē', 'ā§Ģ', 'ā§Ŧ', 'ā§­', 'ā§Ž', '⧝'];
  278.       return str.toString().replace(/[0-9]/g, d => bnDigits[d]);
  279.     }
  280.  
  281.     function formatVolume(value) {
  282.       const formatted = value >= 1000 ? `${(value / 1000).toFixed(1)} L` : `${value.toFixed(0)} mL`;
  283.       return currentLang === 'bn' ? convertToBanglaNumber(formatted) : formatted;
  284.     }
  285.  
  286.     function formatNumber(value) {
  287.       return currentLang === 'bn' ? convertToBanglaNumber(value.toString()) : value.toString();
  288.     }
  289.  
  290.     function calculateSolution() {
  291.       const amount = parseFloat(document.getElementById('amount').value);
  292.       const unit = document.querySelector('input[name="unit"]:checked').value;
  293.       const t = translations[currentLang];
  294.  
  295.       if (isNaN(amount) || amount <= 0) {
  296.        alert("Please enter a valid amount.");
  297.        return;
  298.      }
  299.  
  300.      const totalMl = unit === "l" ? amount * 1000 : amount;
  301.      const baseVolume = 1900;
  302.      const multiplier = totalMl / baseVolume;
  303.  
  304.      const water = 1900 * multiplier;
  305.      const dishSoap = 250 * multiplier;
  306.      const glycerinMl = 60 * multiplier;
  307.      const glycerinTbsp = glycerinMl / 15;
  308.      const bakingPowderGm = 10 * multiplier;
  309.      const bakingPowderTsp = bakingPowderGm / 5;
  310.  
  311.      const result = `
  312.        <h3>${t.ingredientsTitle}</h3>
  313.         <ul>
  314.           <li><strong>${t.items[0]}:</strong> ${formatVolume(water)}</li>
  315.           <li><strong>${t.items[1]}:</strong> ${formatVolume(dishSoap)}</li>
  316.           <li><strong>${t.items[2]}:</strong> ${formatVolume(glycerinMl)} (${formatNumber(glycerinTbsp.toFixed(1))} tbsp)</li>
  317.           <li><strong>${t.items[3]}:</strong> ${formatNumber(bakingPowderGm.toFixed(0))} g (${formatNumber(bakingPowderTsp.toFixed(1))} tsp)</li>
  318.         </ul>
  319.         <p style="margin-top: 10px;">${t.restLine}</p>
  320.       `;
  321.  
  322.       document.getElementById('result').innerHTML = result;
  323.     }
  324.  
  325.     window.onload = () => {
  326.       setLanguage();
  327.       calculateSolution();
  328.     };
  329.   </script>
  330. </body>
  331. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement