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