JSFiddle - React, Tailwind, and code Playground
by Mert Ener
HTML
<div id="ui">
<h3>Yuvarlanan Top — Eğim Demo</h3>
<div class="small">Model: kaymadan yuvarlanma. Sabit yerçekimi g = 9.81 m/s²</div>
<label>kütle m (kg): <span id="mVal" class="num">1.0</span></label>
<input id="m" type="range" min="0.1" max="5" step="0.1" value="1">
<label>açı θ (derece): <span id="thVal" class="num">30</span>°</label>
<input id="theta" type="range" min="0" max="60" step="1" value="30">
<label>yarıçap R (m): <span id="RVal" class="num">0.2</span></label>
<input id="R" type="range" min="0.05" max="0.5" step="0.01" value="0.2">
<label>atalet katsayısı β (I = β m R²): <span id="bVal" class="num">0.4</span></label>
<input id="beta" type="range" min="0.0" max="1.0" step="0.01" value="0.4">
<label>başlangıç hız v₀ (m/s, rampa boyunca yukarı): <span id="vVal" class="num">3.0</span></label>
<input id="v0" type="range" min="0" max="10" step="0.1" value="3">
<div style="display:flex; gap:8px;">
<button id="play">Çalıştır</button>
<button id="pause">Duraklat</button>
<button id="reset">Sıfırla</button>
</div>
<div class="stat">
<div>zaman t: <span id="tVal">0.00</span> s</div>
<div>konum s (m): <span id="sVal">0.00</span></div>
<div>hız v (m/s): <span id="vNow">0.00</span></div>
<div>ivme a (m/s²): <span id="aNow">0.00</span></div>
</div>
<div class="stat">
<div><strong>Torklar</strong></div>
<div>τ<sub>grav</sub> = m g R sinθ : <span id="tauG">0.00</span> N·m</div>
<div>τ<sub>rot</sub> = β m R a : <span id="tauRot">0.00</span> N·m</div>
<div>τ<sub>req</sub> = mgR sinθ + mR(1+β)a : <span id="tauReq">0.00</span> N·m</div>
</div>
<div class="stat">
<div><strong>Enerjiler</strong></div>
<div>Potansiyel ΔU: <span id="U">0.00</span> J</div>
<div>K_trans = 1/2 m v² : <span id="Ktr">0.00</span> J</div>
<div>K_rot = 1/2 I ω² = 1/2 β m v² : <span id="Krot">0.00</span> J</div>
<div>rot payı / toplam: <span id="Kratio">0.00</span></div>
</div>
<div style="margin-top:10px; font-size:13px;...
CSS
#ui{width:360px; padding:18px; box-sizing:border-box; border-right:1px solid #eee; background:#fafafa}
#canvasWrap{flex:1; display:flex; align-items:center; justify-content:center; background:linear-gradient(180deg,#f6f9fc,#ffffff)}
canvas{background:transparent}
label{display:block; margin-top:10px; font-size:13px; color:#333}
input[type=range]{width:100%}
.num{font-weight:700}
.row{display:flex; gap:8px; align-items:center}
button{margin-top:12px; padding:8px 10px; border-radius:6px; border:1px solid #ccc; background:white; cursor:pointer}
.stat{background:#fff; border-radius:6px; padding:8px; margin-top:10px; border:1px solid #eee}
pre{background:#111; color:#0f0; padding:8px; border-radius:6px; font-size:12px; overflow:auto}
.small{font-size:12px; color:#666}
JavaScript
(() => {
const tau_rot = beta * m * R * a; // note: a is negative when slowing
const tau_req = tau_grav + m * R * (1 + beta) * a;
tauG.textContent = tau_grav.toFixed(4);
tauRot.textContent = tau_rot.toFixed(4);
tauReq.textContent = tau_req.toFixed(4);
const U = m * g * (s * Math.sin(theta)); // change in height = s sinθ (approx if starting height 0)
const K_translation = 0.5 * m * v * v;
const K_rotation = 0.5 * (beta * m * R * R) * (v*v/(R*R)); // = 1/2 β m v^2
const Ktot = K_translation + K_rotation;
Uel.textContent = U.toFixed(4);
Ktr.textContent = K_translation.toFixed(4);
Krot.textContent = K_rotation.toFixed(4);
Kratio.textContent = (Ktot>0? (K_rotation / Ktot).toFixed(3) : '0.000');
}
// drawing
function drawScene(){
ctx.clearRect(0,0,canvas.width,canvas.height);
const {thetaDeg,R} = readUI();
const theta = thetaDeg * Math.PI/180;
// layout: ramp center
const baseX = 120; const baseY = canvas.height - 60;
const rampLenPx = 600;
const ux = Math.cos(-theta); // along ramp direction (to the right-up)
const uy = Math.sin(-theta);
// draw ramp line
ctx.lineWidth = 4; ctx.strokeStyle = '#444'; ctx.beginPath();
ctx.moveTo(baseX, baseY);
ctx.lineTo(baseX + rampLenPx * Math.cos(-theta), baseY + rampLenPx * Math.sin(-theta));
ctx.stroke();
// draw ball position: map s (m) to pixels: choose scale so that R meters ~ 40 px
const scale = 200; // px per meter (adjust visually)
const ballPx = baseX + s * scale * Math.cos(-theta);
const ballPy = baseY + s * scale * Math.sin(-theta);
const ballRadiusPx = Math.max(8, R * scale);
// draw ball
ctx.beginPath();
ctx.fillStyle = '#2b8cff';
ctx.arc(ballPx, ballPy - ballRadiusPx, ballRadiusPx, 0, Math.PI*2);
ctx.fill();
ctx.lineWidth = 2; ctx.strokeStyle = '#003a8c'; ctx.stroke();
// draw arrow for velocity
if(v > 0){
const arrowLen = Math.min(80, v * 15);
ctx.beginPath(); ctx.strokeStyle = '#0a0'; ctx.lineWidth=3;
ctx.moveTo(ballPx, ballPy -...