Here’s a self-contained HTML example that explains torque and lets you play with the values (force, lever arm, and angle) to see how torque changes. Just copy this into a file like torque.html and open it in your browser.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Torque Demo – HTML + JS</title>
<style>
  :root { --bg:#0f172a; --card:#111827; --ink:#e5e7eb; --muted:#9ca3af; --accent:#38bdf8; }
  * { box-sizing: border-box; }
  body {
    margin: 0; font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Arial, sans-serif;
    background: linear-gradient(180deg, var(--bg), #1f2937); color: var(--ink);
    display: grid; place-items: center; min-height: 100vh; padding: 24px;
  }
  .wrap {
    width: 100%; max-width: 980px; display: grid; gap: 20px;
  }
  .card {
    background: var(--card); border: 1px solid #1f2937; border-radius: 16px; padding: 18px;
    box-shadow: 0 10px 30px rgba(0,0,0,.25);
  }
  h1 { margin: 0 0 8px; font-size: clamp(22px, 3vw, 34px); }
  p { color: var(--muted); margin: 8px 0 0; }
  .grid {
    display: grid; gap: 16px;
    grid-template-columns: 1fr; 
  }
  @media (min-width: 820px) { .grid { grid-template-columns: 1.1fr .9fr; } }

  /* Controls */
  .control { display: grid; gap: 8px; }
  .control label { font-weight: 600; display: flex; justify-content: space-between; }
  .control output { color: var(--accent); font-variant-numeric: tabular-nums; }
  input[type="range"] { width: 100%; }
  .row { display: grid; grid-template-columns: 1fr 90px; align-items: center; gap: 12px; }
  .note { font-size: 14px; color: var(--muted); }

  /* Result */
  .result {
    display: flex; align-items: baseline; gap: 10px; margin-top: 8px;
  }
  .result .big { font-size: clamp(28px, 5vw, 44px); font-weight: 800; color: var(--accent); }
  .result .unit { color: var(--muted); font-weight: 600; }

  /* Diagram */
  .stage { background:#0b1220; border:1px solid #1f2937; border-radius:12px; padding:10px; }
  svg { width: 100%; height: auto; display: block; }
  .lever { stroke:#93c5fd; stroke-width:10; }
  .pivot { fill:#f59e0b; }
  .force { stroke:#f87171; stroke-width:6; marker-end:url(#arrow); }
  .tick { stroke:#94a3b8; stroke-width:2; }
  .text { fill:#cbd5e1; font-size:12px; }
  .thetaArc { fill:none; stroke:#34d399; stroke-width:3; }
</style>
</head>
<body>
  <div class="wrap">
    <div class="card">
      <h1>Torque (τ) Interactive</h1>
      <p><strong>Torque</strong> measures the turning effect of a force about a pivot: 
        <em>τ = F × r × sin(θ)</em>, where <em>F</em> is force (N), <em>r</em> is lever arm (m),
        and <em>θ</em> is the angle between the lever and the force direction.</p>
      <div class="result">
        <div class="big" id="tau">0.00</div>
        <div class="unit">N·m</div>
      </div>
      <div class="note">Positive τ indicates counter-clockwise tendency in this diagram.</div>
    </div>

    <div class="grid">
      <!-- Controls -->
      <div class="card">
        <div class="control">
          <div class="row">
            <label>Force F <span><output id="oF">50</output> N</span></label>
            <input type="number" id="nF" min="0" max="500" step="1" value="50" />
          </div>
          <input type="range" id="rF" min="0" max="500" step="1" value="50"/>

          <div class="row">
            <label>Lever arm r <span><output id="oR">0.50</output> m</span></label>
            <input type="number" id="nR" min="0" max="2" step="0.01" value="0.50" />
          </div>
          <input type="range" id="rR" min="0" max="2" step="0.01" value="0.50"/>

          <div class="row">
            <label>Angle θ <span><output id="oT">90</output> °</span></label>
            <input type="number" id="nT" min="0" max="180" step="1" value="90" />
          </div>
          <input type="range" id="rT" min="0" max="180" step="1" value="90"/>

          <p class="note">
            Max torque at 90° (force ⟂ lever). Zero torque at 0° or 180° (force ∥ lever).
          </p>
        </div>
      </div>

      <!-- Diagram -->
      <div class="card stage">
        <svg viewBox="0 0 640 280" aria-labelledby="ttl desc" role="img">
          <title id="ttl">Torque diagram</title>
          <desc id="desc">Lever about a pivot at left, force arrow at the end, angle shown between lever and force.</desc>

          <!-- defs -->
          <defs>
            <marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
              <path d="M 0 0 L 10 5 L 0 10 z" fill="#f87171"></path>
            </marker>
          </defs>

          <!-- pivot -->
          <circle class="pivot" cx="80" cy="140" r="10"></circle>
          <text class="text" x="68" y="130">Pivot</text>

          <!-- lever (updated via JS) -->
          <line id="lever" class="lever" x1="80" y1="140" x2="380" y2="140" />

          <!-- ticks every 50px -->
          <g id="ticks"></g>

          <!-- force arrow (updated via JS) -->
          <line id="force" class="force" x1="380" y1="140" x2="380" y2="60" />

          <!-- angle arc -->
          <path id="theta" class="thetaArc" d="" />
          <text id="thetaLabel" class="text" x="120" y="120">θ</text>

          <!-- labels -->
          <text class="text" x="280" y="160">Lever (r)</text>
          <text class="text" x="390" y="90">Force (F)</text>
        </svg>
      </div>
    </div>

    <div class="card">
      <h2>What you’re seeing</h2>
      <ul>
        <li><strong>Lever</strong>: blue bar from the pivot to the right — its length is <em>r</em>.</li>
        <li><strong>Force</strong>: red arrow applied at the end. Angle to the lever is <em>θ</em>.</li>
        <li><strong>Torque</strong>: computed as <code>τ = F × r × sin(θ)</code> and shown above.</li>
      </ul>
      <p class="note">Units: F in newtons (N), r in meters (m) → τ in newton-meters (N·m).</p>
    </div>
  </div>

<script>
  // Elements
  const rF = document.getElementById('rF'), nF = document.getElementById('nF'), oF = document.getElementById('oF');
  const rR = document.getElementById('rR'), nR = document.getElementById('nR'), oR = document.getElementById('oR');
  const rT = document.getElementById('rT'), nT = document.getElementById('nT'), oT = document.getElementById('oT');
  const tauEl = document.getElementById('tau');
  const lever = document.getElementById('lever');
  const force = document.getElementById('force');
  const thetaArc = document.getElementById('theta');
  const thetaLabel = document.getElementById('thetaLabel');
  const ticksGroup = document.getElementById('ticks');

  // Sync helpers
  function link(a, b, out, fmt=(v)=>v) {
    const sync = (e) => { a.value = b.value = e.target.value; out.textContent = fmt(e.target.value); update(); };
    a.addEventListener('input', sync);
    b.addEventListener('input', sync);
  }

  // Formatters
  const f2 = (v)=> Number(v).toFixed(2);
  const f0 = (v)=> Number(v).toFixed(0);

  // Init tick marks along lever reference (every 0.1 m assuming 100 px = 0.25 m below)
  function drawTicks(pxLen){
    ticksGroup.innerHTML = '';
    // choose a step in pixels (every 50 px)
    for(let x=130; x<=80+pxLen; x+=50){
      const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
      line.setAttribute('x1', x); line.setAttribute('y1', 130);
      line.setAttribute('x2', x); line.setAttribute('y2', 150);
      line.setAttribute('class','tick');
      ticksGroup.appendChild(line);
    }
  }

  function update() {
    const F = parseFloat(rF.value);
    const R = parseFloat(rR.value);
    const T = parseFloat(rT.value) * Math.PI/180; // radians

    oF.textContent = f0(F);
    oR.textContent = f2(R);
    oT.textContent = f0(rT.value);

    // Torque
    const tau = F * R * Math.sin(T);
    tauEl.textContent = tau.toFixed(2);

    // Map meters to pixels for the diagram (scale: 1 m ≈ 600 px * 0.5 = 300 px at r=2m → end x ≈ 80 + 300)
    const pxPerMeter = 150; // simple scale
    const endX = 80 + R * pxPerMeter;
    const endY = 140;

    // Update lever line
    lever.setAttribute('x2', endX);
    lever.setAttribute('y2', endY);

    // Force arrow direction: angle relative to lever (lever is along +x). Draw at angle θ from vertical/down?
    // We'll draw the force making angle θ with the lever: when θ=90°, arrow is upward.
    const len = 80; // arrow length in px
    const ang = (Math.PI/2) - T; // so θ=90° => ang=0 (pure up)
    const fx = endX + len * Math.sin(ang);
    const fy = endY - len * Math.cos(ang);
    force.setAttribute('x1', endX);
    force.setAttribute('y1', endY);
    force.setAttribute('x2', fx);
    force.setAttribute('y2', fy);

    // Angle arc at pivot to indicate θ (draw small arc)
    const arcR = 40;
    const start = { x: 80, y: 140 - arcR }; // along +y negative (up)
    const end = { x: 80 + arcR * Math.cos(0), y: 140 }; // placeholder
    // We want arc between lever (+x) and force direction; draw arc centered at pivot
    const a0 = 0;               // lever along +x
    const a1 = T;               // angle θ from lever to force
    const xStart = 80 + arcR * Math.cos(a0);
    const yStart = 140 + arcR * Math.sin(a0);
    const xEnd   = 80 + arcR * Math.cos(a1);
    const yEnd   = 140 + arcR * Math.sin(a1);
    const largeArc = (T % (2*Math.PI)) > Math.PI ? 1 : 0;

    thetaArc.setAttribute('d', `M ${xStart} ${yStart} A ${arcR} ${arcR} 0 ${largeArc} 1 ${xEnd} ${yEnd}`);
    thetaLabel.setAttribute('x', 80 + (arcR+12) * Math.cos(T/2));
    thetaLabel.setAttribute('y', 140 + (arcR+12) * Math.sin(T/2));
    
    drawTicks(endX-80);
  }

  // Link inputs
  link(rF, nF, oF, f0);
  link(rR, nR, oR, f2);
  link(rT, nT, oT, f0);

  // First render
  update();
</script>
</body>
</html>

What this does

  • Shows the torque formula τ = F × r × sin(θ).
  • Lets you adjust Force (N), Lever arm (m), and Angle (°) with sliders/inputs.
  • Displays the calculated torque in N·m and an SVG diagram that updates live (lever length, force direction, and angle arc).

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *