The original Start/Reset facility is preserved. The calculation is corrected to convert degrees to radians before using Math.sin() and Math.cos(), and the movement is animated instead of being calculated in one immediate loop.
const image = document.getElementById('i1');
const area = document.getElementById('move-area');
const output = document.getElementById('msg');
const startButton = document.getElementById('start');
const resetButton = document.getElementById('reset');
let animationId = null;
let angle = 0;
function draw() {
const radius = Math.max(20, Math.min(area.clientWidth, area.clientHeight) / 2 - image.offsetWidth);
const centerX = area.clientWidth / 2 - image.offsetWidth / 2;
const centerY = area.clientHeight / 2 - image.offsetHeight / 2;
const radians = angle * Math.PI / 180;
const left = centerX + radius * Math.sin(radians);
const top = centerY - radius * Math.cos(radians);
image.style.left = `${left}px`;
image.style.top = `${top}px`;
output.textContent = `Angle: ${Math.round(angle)}° X: ${Math.round(left)} Y: ${Math.round(top)}`;
angle = (angle + 1) % 360;
animationId = requestAnimationFrame(draw);
}
function start() { if (animationId === null) animationId = requestAnimationFrame(draw); }
function reset() {
if (animationId !== null) cancelAnimationFrame(animationId);
animationId = null; angle = 0;
image.style.left = '40px'; image.style.top = '40px'; output.textContent = '';
}
startButton.addEventListener('click', start);
resetButton.addEventListener('click', reset);
<div id="move-area" class="border rounded mb-3" style="position:relative; min-height:420px; overflow:hidden; touch-action:none;">
<img src="images/help.jpg" id="i1" alt="Help icon used in JavaScript image movement demo" style="position:absolute; left:40px; top:40px; max-width:80px; height:auto;">
</div>
<button type="button" id="start">Start</button>
<button type="button" id="reset">Reset</button>
<div id="msg"></div>