发一个之前学习HTML5和Javascript的code, 这个是在HTML5画布上,动态画出了一个滚动的圆形,演示Pi是圆的周长与直径的比值。HTML5 使用window.requestAnimationFrame()函数自动刷新画面,并且FPS能自适应浏览器的刷新率,比直接使用setInterval 这样的函数显示的效果更好,不会有丢帧或卡顿的现象。

image image image

 
let canvas = document.getElementById("circleCanvas");
let ctx = canvas.getContext("2d");
const WIDTH = canvas.width, HEIGHT = canvas.height ;
const START_X = 120, START_Y = 180, R = 100; 
const Pi = Math.PI, C=2*Pi*R; 

let circle = {
  x: START_X,
  y: START_Y,  
  
  stopMove: function() {
    return (this.x >= START_X + C) ; 
  },
  move: function() {
    if (!this.stopMove()) { 
      this.x = this.x + 2;
    } else{
      this.x = START_X + C;
    }
  }
}

window.requestAnimationFrame (animate); 

function animate (){ 
  drawBackground();	//clear the canvas in draw background
  draw();
  requestAnimationFrame (animate); 
}


function drawBackground(){
  ctx.clearRect(0, 0, WIDTH, HEIGHT);	// clear first
  ctx.strokeStyle = "black";
  ctx.lineWidth = 1;
  ctx.setLineDash([]);
  for (let i = 1; i<= WIDTH / 10; i++){
    let lineH = i%5==0? 8 :4; 
    ctx.moveTo(10 * i, 0);
    ctx.lineTo(10 * i, lineH);
  }

  for (let i = 1; i<= HEIGHT / 10; i++){
    let lineH = i%5==0? 8 :4; 
    ctx.moveTo(0, 10 * i);
    ctx.lineTo(lineH, 10 * i);
  }

  ctx.stroke();
}


function draw() {  
  if (circle.stopMove()) { 
    displayInfo();
  }
  circle.move();
  ctx.strokeStyle = "black";
  ctx.lineWidth = 1;
  ctx.setLineDash([]);
  drawCenterPoint();
  drawCircle();
  drawBottomLine();
  drawShortLine();
  drawArc();
  drawDiameter();
}

function drawCenterPoint() {
  ctx.beginPath();
  ctx.arc(circle.x, circle.y, 1, 0, 2 * Pi);
  ctx.fillStyle="black" 
  ctx.fill(); 
}

function drawCircle() {
  ctx.beginPath();
  ctx.arc(circle.x, circle.y, 100, 0, 2 * Pi);
  ctx.stroke();
}

function drawBottomLine(){
  ctx.strokeStyle = "red";
  ctx.lineWidth = 2;
  ctx.setLineDash([]);
  ctx.beginPath();
  ctx.moveTo(START_X, START_Y + R);
	ctx.lineTo(circle.x, START_Y + R);  
  ctx.stroke();
}

function drawShortLine(){  // the short line on the bottom line 
  for(let n=0; n<4; n++){
    if (circle.x - START_X > n*2*R){
      ctx.beginPath();
      ctx.moveTo(START_X + n*2*R, START_Y + R);
      ctx.lineTo(START_X + n*2*R, START_Y + R - 7); 
      ctx.stroke();

      ctx.font = "14px Arial"; 
      ctx.fillStyle = "red";
      ctx.fillText(n, START_X + n*2*R -4, START_Y + R - 12);
    }
  } 

  if(circle.stopMove()){ 
    ctx.beginPath();
    ctx.moveTo(START_X + Pi*2*R, START_Y + R);
    ctx.lineTo(START_X + Pi*2*R, START_Y + R - 7); 
    ctx.stroke();  
  }
}

function drawDiameter(){
  if(circle.stopMove()){
    ctx.strokeStyle = "white";
    ctx.setLineDash([1,1]);
    ctx.lineWidth = 1;

    let alpha = (circle.x - START_X) / R; 
    ctx.beginPath();
    ctx.moveTo(circle.x + R*Math.sin(alpha), circle.y - R*Math.cos(alpha));
    ctx.lineTo(circle.x - R*Math.sin(alpha), circle.y + R*Math.cos(alpha));
    ctx.stroke(); 
  }
}

function drawArc() {
  let alpha = (circle.x - START_X) / R; 
  ctx.strokeStyle = "blue";
  ctx.lineWidth = 2;
  ctx.setLineDash([]);

  ctx.beginPath();
  ctx.arc(circle.x, circle.y, 100, Pi/2, Pi/2 + alpha);  
  ctx.stroke();
}


function displayInfo(){    
  ctx.strokeStyle = "black";
  ctx.lineWidth = 1;
  ctx.setLineDash([]);
  ctx.beginPath();
  // the {
  ctx.moveTo(START_X, START_Y + R + 5);
  ctx.lineTo(START_X +8, START_Y + R + 5 + 8);
  ctx.lineTo(START_X + C/2  -5, START_Y + R + 5 + 8);
  ctx.lineTo(START_X + C/2, START_Y + R + 5 + 8 +5);
  ctx.lineTo(START_X + C/2 +5 , START_Y + R + 5 + 8);
  ctx.lineTo(START_X + C -8, START_Y + R + 5 + 8);
  ctx.lineTo(START_X + C , START_Y + R + 5);
      
  // another }
  ctx.moveTo(START_X + C + 5, START_Y - R);
  ctx.lineTo(START_X + C + 5 + 8, START_Y - R + 8);
  ctx.lineTo(START_X + C + 5 + 8, START_Y -5);
  ctx.lineTo(START_X + C + 5 + 8 + 5, START_Y);
  ctx.lineTo(START_X + C + 5 + 8, START_Y +5);    
  ctx.lineTo(START_X + C + 5 + 8, START_Y + R - 8);
  ctx.lineTo(START_X + C + 5, START_Y + R);
  
  ctx.stroke(); 

  ctx.font = "italic 26px Arial"; 
  ctx.fillStyle = "black";
  ctx.fillText("1",START_X + C + 5 + 8 + 5 + 8, START_Y+10);
  ctx.fillText("π",START_X + C/2 -10, START_Y + R + 5 + 8 +5 + 24);
}