<canvas id="canvas" width="400" height="400" style="background: #ccc;"></canvas>
// 圆球的构造函数
function Ball(radius, color) {
  if(radius === undefined) { radius = 40; }
  if(color === undefined) { color = "#ff0000"; }
  this.x = 0;
  this.y = 0;
  this.radius = radius;
  this.rotation = 0;
  this.scaleX = 1;
  this.scaleY = 1;
  this.color = color;
  this.lineWidth = 1;
}
Ball.prototype.draw = function(context) {
  context.save();
  context.translate(this.x, this.y);
  context.rotate(this.rotation);
  context.scale(this.scaleX, this.scaleY);
  context.lineWidth = this.lineWidth;
  context.fillStyle = this.color;
  context.beginPath();
  context.arc(0, 0, this.radius, 0, Math.PI * 2, true);
  context.closePath();
  context.fill();
  if(this.lineWidth > 0) {
    context.stroke();
  }
  context.restore();
}

window.cancelRequestAnimFrame = ( function() {
  return window.cancelAnimationFrame ||
    window.webkitCancelRequestAnimationFrame ||
    window.mozCancelRequestAnimationFrame ||
    window.oCancelRequestAnimationFrame ||
    window.msCancelRequestAnimationFrame ||
    clearTimeout;
} )();

window.onload = function() {
  var canvas = document.getElementById("canvas"),
      context = canvas.getContext("2d"),
      ball = new Ball(2),
      angle = 0,
      centerX = canvas.width / 2,
      centerY = canvas.height / 2,
      radiusX = 150,
      radiusY = 100,
      speed = 0.05,
      timer = null;

  ball.lineWidth = 0;

  (function drawFrame() {
    timer = window.requestAnimationFrame(drawFrame, canvas);
    if(angle > Math.PI * 2 && timer) {
      window.cancelRequestAnimFrame(timer);
      timer = null;
    }
    // context.clearRect(0, 0, canvas.width, canvas.height);
    ball.y = centerY + Math.sin(angle) * radiusY;
    ball.x = centerX + Math.cos(angle) * radiusX;
    angle += speed;

    ball.draw(context);
  })();
};

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.