The problem

Objects that move at constant speed and stop instantly look robotic. Real motion — and good UI — eases: slow start, fast middle, gentle stop. The smoothest easings are sine curves.

The three sine easings

For progress \(t \in [0, 1]\), mapping to eased progress \(e(t) \in [0, 1]\):

$$ \text{easeInSine: } e = 1 - \cos\!\left(\tfrac{\pi}{2}t\right), \qquad \text{easeOutSine: } e = \sin\!\left(\tfrac{\pi}{2}t\right), \qquad \text{easeInOutSine: } e = -\tfrac{1}{2}\left(\cos(\pi t) - 1\right) $$

Check the boundaries: at \(t = 0\) all give 0, at \(t = 1\) all give 1. The difference is the slope: ease-in starts flat (zero velocity) and ease-out ends flat. Ease-in-out does both — which is why it is the default choice for moving things on screen.

Derivatives confirm the feel (velocity = slope):

$$ \frac{d}{dt}\text{easeInOutSine} = \tfrac{\pi}{2}\sin(\pi t) $$

— zero velocity at both ends, peak velocity mid-way. Exactly like a pendulum, because it is the same math.

Compare them live

function easeInOutSine(t) { return -(Math.cos(Math.PI * t) - 1) / 2; }
function easeOutSine(t) { return Math.sin((t * Math.PI) / 2); }
function linear(t) { return t; }

var tracks = [
  { e: linear, color: '#64748b', y: 80, label: 'linear' },
  { e: easeOutSine, color: '#38bdf8', y: 180, label: 'ease-out' },
  { e: easeInOutSine, color: '#fbbf24', y: 280, label: 'ease-in-out' }
];
var D = 2.2; // seconds per trip

loop(function (t) {
  clear();
  var phase = (t % (D * 2)) / D;          // 0→2→0 sawtooth
  var fwd = phase < 1 ? phase : 2 - phase; // ping-pong 0→1→0
  tracks.forEach(function (tr) {
    var x = 60 + (W - 120) * tr.e(fwd);
    ctx.fillStyle = tr.color;
    ctx.beginPath(); ctx.arc(x, tr.y, 16, 0, Math.PI * 2); ctx.fill();
    ctx.fillStyle = '#e2e8f0';
    ctx.font = '16px sans-serif';
    ctx.fillText(tr.label, 60, tr.y - 26);
  });
});
print('watch: linear jerks at the ends, eased dots glide');

Try it

  1. Add easeInSine to the race. Which end looks abrupt, and does the slope math predict it?
  2. Apply easing to the turret projectiles: ease a laser beam’s width from 0 to full over 0.15 s.
  3. CSS also eases (transition-timing-function), but has no sine keyword — approximate ease-in-out with cubic-bezier(0.37, 0, 0.63, 1) and compare against the true sine visually.

Next: Project: Maps & Bearings — compass math and real GPS distances.