{"id":267,"date":"2025-09-10T06:00:14","date_gmt":"2025-09-10T06:00:14","guid":{"rendered":"https:\/\/learn-by-animation.com\/?page_id=267"},"modified":"2025-09-10T06:07:29","modified_gmt":"2025-09-10T06:07:29","slug":"molarity","status":"publish","type":"page","link":"https:\/\/learn-by-animation.com\/?page_id=267","title":{"rendered":"Molality"},"content":{"rendered":"\n<div class=\"molality-widget\">\n  <div class=\"wrap\">\n    <h1>Molality slider animation \u2014 \n      <span class=\"tiny\">m = (1000\u00b7w) \/ (M<sub>r<\/sub>(100\u2212w))<\/span>\n    <\/h1>\n    <p class=\"lead\">Use the sliders to change mass % (<strong>w<\/strong>) and molar mass (<strong>M<sub>r<\/sub><\/strong>). Hit play to animate the <em>w<\/em> sweep and watch molality update in real time.<\/p>\n\n    <div class=\"grid\">\n      <div class=\"card\">\n        <div class=\"formula\" aria-live=\"polite\">\n          <div class=\"line\">Formula (mass % \u2192 molality):<\/div>\n          <div class=\"line big\" id=\"formulaDisplay\">m = 1000\u00b7w \/ (M<sub>r<\/sub> \u00b7 (100 \u2212 w))<\/div>\n\n          <div style=\"margin-top:12px\" class=\"tiny\">Substituted:<\/div>\n          <div style=\"margin-top:6px;font-size:18px\" id=\"substituted\">\n            m = <span class=\"value\" id=\"num\">\u2014<\/span> \/ (<span class=\"value\" id=\"den1\">\u2014<\/span>) = \n            <span class=\"value\" id=\"mval\">\u2014<\/span> mol\u00b7kg\u207b\u00b9\n          <\/div>\n        <\/div>\n\n        <div class=\"controls\">\n          <div>\n            <label>Mass percent w (%) <span class=\"value\" id=\"wLabel\">10.0<\/span><\/label>\n            <input id=\"wSlider\" type=\"range\" min=\"0.1\" max=\"99.9\" step=\"0.1\" value=\"10\">\n          <\/div>\n\n          <div>\n            <label>Molar mass M<sub>r<\/sub> (g\u00b7mol\u207b\u00b9) <span class=\"value\" id=\"mrLabel\">180<\/span><\/label>\n            <input id=\"mrSlider\" type=\"range\" min=\"1\" max=\"500\" step=\"0.1\" value=\"180\">\n          <\/div>\n\n          <div style=\"display:flex;gap:12px;align-items:center\">\n            <div class=\"playrow\">\n              <button id=\"playBtn\">\u25b6 Play<\/button>\n              <button id=\"pauseBtn\">\u23f8 Pause<\/button>\n            <\/div>\n            <div style=\"flex:1\">\n              <label style=\"display:block;font-size:12px;color:var(--muted)\">Speed <span id=\"speedLabel\" class=\"value\">1.0x<\/span><\/label>\n              <input id=\"speed\" type=\"range\" min=\"0.1\" max=\"5\" step=\"0.1\" value=\"1\">\n            <\/div>\n          <\/div>\n\n          <div>\n            <label>Auto-reset at limits \n              <input id=\"resetCheck\" type=\"checkbox\" checked style=\"margin-left:8px\">\n            <\/label>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"card\" style=\"display:flex;flex-direction:column;justify-content:space-between\">\n        <div>\n          <div class=\"tiny\">Current values<\/div>\n          <div class=\"result\" style=\"margin-top:10px\">\n            <div>Molar mass <span style=\"float:right\" id=\"mrSmall\">180.0 g\u00b7mol\u207b\u00b9<\/span><\/div>\n            <div style=\"margin-top:8px\">Mass % <span style=\"float:right\" id=\"wSmall\">10.0 %<\/span><\/div>\n            <div style=\"margin-top:12px;border-top:1px dashed rgba(255,255,255,0.04);padding-top:12px\">\n              Molality <div id=\"mBig\" style=\"font-size:30px;margin-top:6px;color:var(--accent)\">\u2014 mol\u00b7kg\u207b\u00b9<\/div>\n            <\/div>\n          <\/div>\n\n          <div style=\"margin-top:12px\" class=\"tiny\">Notes:<\/div>\n          <ul class=\"tiny\" style=\"margin:8px 0 0 18px;color:var(--muted)\">\n            <li>Formula: <code>m = 1000\u00b7w \/ (M<sub>r<\/sub>\u00b7(100\u2212w))<\/code> where <em>w<\/em> is mass % (g solute per 100 g solution).<\/li>\n            <li>Set molar mass and watch how molality rises as <em>w<\/em> \u2192 100% (denominator \u2192 0).<\/li>\n          <\/ul>\n        <\/div>\n\n        \n      <\/div>\n    <\/div>\n\n    <footer>Interactive demo \u2014 tweak sliders or press Play. Safe for teaching and quick calculations.<\/footer>\n  <\/div>\n<\/div>\n\n<style>\n.molality-widget {\n  --bg:#0f1724;--card:#0b1220;--accent:#60a5fa;--muted:#94a3b8;--glass:rgba(255,255,255,0.04);\n  font-family: Inter,Segoe UI,Roboto,Arial,sans-serif;\n  color:#e6eef8;\n}\n.molality-widget .wrap{max-width:920px;margin:32px auto;padding:24px;background:linear-gradient(180deg, rgba(255,255,255,0.02), transparent);border-radius:12px;box-shadow:0 6px 30px rgba(2,6,23,0.7)}\n.molality-widget h1{margin:0 0 8px;font-weight:600;font-size:20px}\n.molality-widget p.lead{margin:0 0 18px;color:var(--muted)}\n.molality-widget .grid{display:grid;grid-template-columns:1fr 360px;gap:20px}\n.molality-widget .card{background:var(--card);padding:18px;border-radius:10px;box-shadow:inset 0 1px 0 rgba(255,255,255,0.02)}\n.molality-widget .formula{font-family:'Georgia','Times New Roman',serif;background:var(--glass);padding:14px;border-radius:8px;margin-bottom:14px}\n.molality-widget .formula .line{font-size:18px}\n.molality-widget .big{font-size:26px;font-weight:700;color:var(--accent)}\n.molality-widget .controls{display:flex;flex-direction:column;gap:12px}\n.molality-widget label{font-size:13px;color:var(--muted);display:flex;justify-content:space-between;align-items:center}\n.molality-widget input[type=range]{width:100%;margin-top:6px}\n.molality-widget .value{font-weight:600;color:#fff;margin-left:8px}\n.molality-widget .playrow{display:flex;gap:10px;align-items:center}\n.molality-widget button{background:transparent;border:1px solid rgba(255,255,255,0.06);padding:8px 12px;border-radius:8px;color:var(--muted);cursor:pointer}\n.molality-widget button.active{border-color:var(--accent);color:var(--accent);box-shadow:0 6px 18px rgba(96,165,250,0.12)}\n.molality-widget .result{font-size:20px;font-weight:700;color:#e6eef8;background:linear-gradient(90deg, rgba(255,255,255,0.02), transparent);padding:12px;border-radius:8px;text-align:center}\n.molality-widget .tiny{font-size:12px;color:var(--muted)}\n.molality-widget footer{margin-top:16px;color:var(--muted);font-size:13px;text-align:center}\n@media (max-width:860px){.molality-widget .grid{grid-template-columns:1fr;}.molality-widget .card{padding:14px}}\n<\/style>\n\n<script>\n(function(){\n  const container = document.querySelector('.molality-widget');\n  const wSlider = container.querySelector('#wSlider');\n  const mrSlider = container.querySelector('#mrSlider');\n  const wLabel = container.querySelector('#wLabel');\n  const mrLabel = container.querySelector('#mrLabel');\n  const wSmall = container.querySelector('#wSmall');\n  const mrSmall = container.querySelector('#mrSmall');\n  const mBig = container.querySelector('#mBig');\n  const num = container.querySelector('#num');\n  const den1 = container.querySelector('#den1');\n  const mval = container.querySelector('#mval');\n  const formulaDisplay = container.querySelector('#formulaDisplay');\n  const playBtn = container.querySelector('#playBtn');\n  const pauseBtn = container.querySelector('#pauseBtn');\n  const speed = container.querySelector('#speed');\n  const speedLabel = container.querySelector('#speedLabel');\n  const resetCheck = container.querySelector('#resetCheck');\n  const copyBtn = container.querySelector('#copyBtn');\n  const downloadBtn = container.querySelector('#downloadBtn');\n\n  function calcMolality(w, Mr){\n    const denom = Mr * (100 - w);\n    if (denom <= 0) return {m: Infinity, numerator: (1000*w).toFixed(6), denom: denom.toFixed(6)};\n    const m = (1000 * w) \/ denom;\n    return {m: m, numerator: (1000*w).toFixed(6), denom: denom.toFixed(6)};\n  }\n\n  function updateUI(){\n    const w = parseFloat(wSlider.value);\n    const Mr = parseFloat(mrSlider.value);\n    wLabel.textContent = w.toFixed(1);\n    mrLabel.textContent = Mr.toFixed(1);\n    wSmall.textContent = w.toFixed(1) + ' %';\n    mrSmall.textContent = Mr.toFixed(1) + ' g\u00b7mol\u207b\u00b9';\n\n    const {m,numerator,denom} = calcMolality(w,Mr);\n    num.textContent = numerator;\n    den1.textContent = Mr.toFixed(3) + ' \u00d7 ' + (100 - w).toFixed(3);\n    mval.textContent = (m === Infinity) ? '\u221e (division by 0)' : m.toFixed(6);\n    mBig.textContent = (m === Infinity) ? '\u221e' : m.toFixed(6) + ' mol\u00b7kg\u207b\u00b9';\n\n    if (100 - w < 0.5) {\n      formulaDisplay.style.boxShadow = '0 8px 40px rgba(255,92,92,0.12)';\n    } else {\n      formulaDisplay.style.boxShadow = 'none';\n    }\n  }\n\n  wSlider.addEventListener('input', updateUI);\n  mrSlider.addEventListener('input', updateUI);\n  speed.addEventListener('input', ()=>{ speedLabel.textContent = speed.value + 'x'; });\n\n  let animId = null;\n  let playing = false;\n  let direction = 1;\n\n  function stepAnimation(){\n    const spd = parseFloat(speed.value);\n    const dt = 0.016 * spd * 4;\n    let w = parseFloat(wSlider.value);\n    w += direction * dt;\n    if (w >= parseFloat(wSlider.max)){\n      w = parseFloat(wSlider.max);\n      if (resetCheck.checked){ direction = -1; }\n      else { stopAnim(); }\n    } else if (w <= parseFloat(wSlider.min)){\n      w = parseFloat(wSlider.min);\n      if (resetCheck.checked){ direction = 1; }\n      else { stopAnim(); }\n    }\n    wSlider.value = Math.max(parseFloat(wSlider.min), Math.min(parseFloat(wSlider.max), w));\n    updateUI();\n    animId = requestAnimationFrame(stepAnimation);\n  }\n\n  function startAnim(){ if (playing) return; playing = true; playBtn.classList.add('active'); pauseBtn.classList.remove('active'); animId = requestAnimationFrame(stepAnimation); }\n  function stopAnim(){ if (!playing) return; playing = false; playBtn.classList.remove('active'); pauseBtn.classList.add('active'); if (animId) cancelAnimationFrame(animId); animId = null; }\n\n  playBtn.addEventListener('click', ()=>{ startAnim(); });\n  pauseBtn.addEventListener('click', ()=>{ stopAnim(); });\n\n  copyBtn.addEventListener('click', async ()=>{\n    const snippet = `const m = (1000*w)\/(Mr*(100-w)); \/\/ w in %, Mr in g\/mol`;\n    try{ await navigator.clipboard.writeText(snippet); copyBtn.textContent = 'Copied!'; setTimeout(()=>copyBtn.textContent='Copy JS snippet',1200); } catch(e){ copyBtn.textContent='Copy failed'; setTimeout(()=>copyBtn.textContent='Copy JS snippet',1200); }\n  });\n\n  downloadBtn.addEventListener('click', ()=>{\n    const html = container.outerHTML;\n    const blob = new Blob([html],{type:'text\/html'});\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement('a');\n    a.href = url; a.download = 'molality-widget.html';\n    document.body.appendChild(a); a.click(); a.remove();\n    setTimeout(()=>URL.revokeObjectURL(url),2000);\n  });\n\n  updateUI();\n  stopAnim();\n})();\n<\/script>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Molality slider animation \u2014 m = (1000\u00b7w) \/ (Mr(100\u2212w)) Use the sliders to change mass % (w) and molar mass (Mr). Hit play to animate the w sweep and watch molality update in real time. Formula (mass % \u2192 molality): m = 1000\u00b7w \/ (Mr \u00b7 (100 \u2212 w)) Substituted: m = \u2014 \/ (\u2014) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-267","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/learn-by-animation.com\/index.php?rest_route=\/wp\/v2\/pages\/267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learn-by-animation.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/learn-by-animation.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/learn-by-animation.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learn-by-animation.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=267"}],"version-history":[{"count":5,"href":"https:\/\/learn-by-animation.com\/index.php?rest_route=\/wp\/v2\/pages\/267\/revisions"}],"predecessor-version":[{"id":278,"href":"https:\/\/learn-by-animation.com\/index.php?rest_route=\/wp\/v2\/pages\/267\/revisions\/278"}],"wp:attachment":[{"href":"https:\/\/learn-by-animation.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}