关于canvas画原子运动模型

参考链接:http://selinayu.cc/2018/07/23/canvas-%E5%B0%8F%E7%90%83%E8%BF%90%E5%8A%A8%E8%BD%A8%E8%BF%B9/

就是在原子能图标上椭圆运动的小球,效果如下

代码如下

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4   <title>原子运动模型</title>
 5   <style>
 6     div {
 7       position: relative;
 8     }
 9     canvas {
10       position: absolute;
11     }
12   </style>
13 </head>
14 <body>
15 <div>
16   <canvas id="canvas" style="transform: rotate(0deg);">浏览器不支持canvas</canvas>
17   <canvas id="canvas1" style="transform: rotate(60deg);">浏览器不支持canvas</canvas>
18   <canvas id="canvas2" style="transform: rotate(120deg);">浏览器不支持canvas</canvas>
19 </div>
20 </body>
21 <script type="text/javascript">
22   function circleRunEllipse(elemId, canvasWidth, canvasHeight, circleColor, ellipseColor, ellipseHeight, ellipseWidth, ellipseSpeed) {
23     let canvas = document.getElementById(elemId);
24     let context=canvas.getContext("2d");
25 
26     let width = canvas.width = canvasWidth;
27     let height = canvas.height = canvasHeight;
28     let radius = 3;
29     let animationFrame = null; // 记录执行的动画,用于取消
30     // 画实体圆
31     function drawCircle(x,y,radius,color){
32       context.save();
33       context.fillStyle = color;
34       context.globalAlpha=0.95
35       context.beginPath();
36       context.arc(x,y,radius,0,Math.PI *2);
37       context.closePath();
38       context.fill();
39       context.restore();
40     }
41 
42 
43     // 画椭圆,使用lineTo,把椭圆分割许多片段
44     // 椭圆的三角函数表达式 x = a*cos(t), y = b * sin(t);
45     function drawEllipse(color,x,y,a,b){
46       //这样可以使得每次循环所绘制的路径(弧线)接近1像素
47       let step = (a > b) ? 1 / a : 1 / b;
48       context.save();
49       context.strokeStyle = color;
50       context.beginPath();
51       context.moveTo(x + a,y);
52       for(let i = 0; i < Math.PI *2; i += step){
53         context.lineTo(x + a * Math.cos(i),y + b * Math.sin(i))
54       }
55       context.closePath();
56       context.stroke();
57       context.restore();
58     }
59 
60     // 椭圆运动
61     let ellipseA = ellipseWidth; // 长轴 a
62     let ellipseB = ellipseHeight; // 短轴 b
63     let ellipseTime = 0;
64     let ellipseStep = ellipseSpeed;  //控制运动速度
65 
66     ellipseRun();
67     function ellipseRun(){
68       window.cancelAnimationFrame(animationFrame);
69       animationFrame = window.requestAnimationFrame(ellipseRun);
70       context.clearRect(0,0,width,height);
71       drawEllipse(ellipseColor,width/2,height/2, ellipseA ,ellipseB );
72       drawCircle(width/2 + ellipseA * Math.cos(ellipseTime),height/2 + ellipseB * Math.sin(ellipseTime),radius,circleColor);
73       ellipseTime += ellipseStep;
74     }
75   }
76   circleRunEllipse('canvas', 300, 300, 'red', 'blue', 70, 30, 0.01)
77   circleRunEllipse('canvas1', 300, 300, 'red', 'blue', 70, 30, 0.01)
78   circleRunEllipse('canvas2', 300, 300, 'red', 'blue', 70, 30, 0.01)
79 
80 </script>
81 </html>
原文地址:https://www.cnblogs.com/nightfallsad/p/9512502.html