tilbage til lektionen

Placer bolden i midten af feltet

vigtighed: 5

Her er hvordan kilde dokumentet ser ud:

Hvad er koordinaterne for midten af feltet?

Beregn det og brug det til at placere bolden i midten af det grønne felt:

  • Elementet skal flyttes af JavaScript, ikke CSS.
  • Koden skal virke med enhver boldstørrelse (10, 20, 30 pixels) og enhver feltstørrelse. Den må ikke være bundet til de givne værdier.

P.S. Selvfølgelig kunne centrering gøres med CSS, men her vil vi specifikt have JavaScript. Senere møder vi andre og mere komplekse situationer, hvor JavaScript skal bruges. Betragt dette som en “opvarmning”.

Åbn en sandbox til opgaven.

The ball has position:absolute. It means that its left/top coordinates are measured from the nearest positioned element, that is #field (because it has position:relative).

The coordinates start from the inner left-upper corner of the field:

The inner field width/height is clientWidth/clientHeight. So the field center has coordinates (clientWidth/2, clientHeight/2).

…But if we set ball.style.left/top to such values, then not the ball as a whole, but the left-upper edge of the ball would be in the center:

ball.style.left = Math.round(field.clientWidth / 2) + 'px';
ball.style.top = Math.round(field.clientHeight / 2) + 'px';

Here’s how it looks:

To align the ball center with the center of the field, we should move the ball to the half of its width to the left and to the half of its height to the top:

ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px';
ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px';

Now the ball is finally centered.

Attention: the pitfall!

The code won’t work reliably while <img> has no width/height:

<img src="ball.png" id="ball">

When the browser does not know the width/height of an image (from tag attributes or CSS), then it assumes them to equal 0 until the image finishes loading.

So the value of ball.offsetWidth will be 0 until the image loads. That leads to wrong coordinates in the code above.

After the first load, the browser usually caches the image, and on reloads it will have the size immediately. But on the first load the value of ball.offsetWidth is 0.

We should fix that by adding width/height to <img>:

<img src="ball.png" width="40" height="40" id="ball">

…Or provide the size in CSS:

#ball {
  width: 40px;
  height: 40px;
}

Åbn løsningen i en sandbox.