# 《每周一点canvas动画》——三角函数(2)

• 波形运动

• 圆周运动

• 两点间的距离

## 一.波形运动

sin函数的波形想必骚年们不会感到陌生，如果只是考虑一个周期以内的函数波形，如下图所示：

``    for(var angle=0; angle<Math.PI*2; angle+=0.1){         console.log(Math.sin(angle)); //打印出角度对应的sin值     }``

• js

• arrow.js

• ball.js

ball.js代码具体如下，这里就不做过多解释了。我们只是画了一个圆。

``ball.js文件      function Ball(radius,color){         if(radius === undefined) {radius = 40;}         if(color === undefined){color = '#00ff00';}         this.x = 0;         this.y = 0;         this.vx = 0;         this.vy = 0;         this.radius = radius;         this.rotation = 0;         this.mass = 1;         this.scaleX = 1;         this.scaleY = 1;         this.color = utils.parseColor(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.strokeStyle = this.color;         context.beginPath();         context.arc(0,0,this.radius,0,Math.PI*2,false);         context.closePath();         context.fill();         context.stroke();         context.restore();     }``

### 1.平滑运动(Smooth motion)

``  <canvas id="canvas" width="500" height="500" style="background:#000009;">        your browser not support canvas!    </canvas>    <script src="../js/utils.js"></script>    <script src="../js/ball.js"></script>    <script>        window.onload = function(){            var canvas = document.getElementById("canvas");            var context = canvas.getContext("2d");             var ball = new Ball();                   ball.x = canvas.width/2;                   ball.y = canvas.height/2;             var angle = 0,                range = 50; //振幅             (function drawFram(){                window.requestAnimationFrame(drawFram,canvas);                context.clearRect(0,0,canvas.width,canvas.height);                 ball.x = canvas.width/2 + Math.sin(angle)*range; //核心                angle += 0.1;                 ball.draw(context);            })();        }     </script>``

### 2.线性运动(Linear motion)

``<canvas id="canvas" width="500" height="500" style="background:#000;">        you browser not support canvas!    </canvas>    <script src="../js/utils.js"></script>    <script src="../js/ball.js"></script>    <script>        window.onload = function(){            var canvas = document.getElementById('canvas'),                  context = canvas.getContext('2d');            var angle = 0,                range = 50,                xspeed = 1,                yspeed = 0.05;             var ball = new Ball();                        (function drawFrame(){                window.requestAnimationFrame(drawFrame,canvas);                context.clearRect(0,0,canvas.width,canvas.height);                 ball.x += xspeed; //水平，沿x轴方向水平运动                                if(ball.x > canvas.width + ball.radius){                    ball.x = -ball.radius;                }                //垂直， 由于angle角度没发生变化，所以纵坐标保持不变                ball.y = canvas.height/2+Math.sin(angle)*range;                               // angle += 0.05; //取消注释看看发生了什么？                ball.draw(context);            })();        }     </script>``

### 3.脉冲运动(Pulsing motion)

``window.onload = function(){             var canvas = document.getElementById('canvas');             var context  = canvas.getContext('2d');              var angle = 0,                 range = 0.5,                 speed = 0.05,                 centerScale = 1;              var ball = new Ball();                 ball.x = canvas.width/2;                    ball.y = canvas.height/2;              (function drawFrame(){                 window.requestAnimationFrame(drawFrame,canvas);                 context.clearRect(0,0,canvas.width,canvas.height);                                  //sin值的变化，导致 ball.scaleX ， ball.scaleY属性变化                 ball.scaleX = ball.scaleY = centerScale + Math.sin(angle)*range;                 angle += speed;                  ball.draw(context);             })();         }``

## 二、圆周运动

### 1.正圆运动

``    window.onload = function(){                var canvas = document.getElementById('canvas'),                    context = canvas.getContext('2d');                 var ball = new Ball();                 var angle = 0, // 旋转的角度                    centerX = canvas.width/2,                    centerY = canvas.height/2,                    radius = 100, // 定义半径                    speed =0.05; // 每帧旋转角度的增加值                 (function drawFrame(){                    window.requestAnimationFrame(drawFrame, canvas);                    context.clearRect(0,0,canvas.width, canvas.height);                     //centerX, centerY 的作用是让球绕画布中心旋转                    ball.x = centerX + Math.sin(angle)*radius;                    ball.y = centerY + Math.cos(angle)*radius;                     //角度增加                    angle += speed;                    ball.draw(context);                }());            }``

ok,自己动手试试吧！看看是不是球体绕着画布中心做着圆周运动呢！这里我们需要的条件比较多 angle 和 R，在后面的章节中我们将介绍如何只通过 angle 就实现圆周运动。为了更容易理解，我劝你最好复习一下中学的知识，哈哈！！！

### 2.椭圆运动

``window.onload = function(){             var canvas = document.getElementById('canvas');             var context = canvas.getContext('2d');             var ball = new Ball();                          var centerX = canvas.width/2,                 centerY = canvas.height/2,                 angle = 0,                 radiusX = 50,                 radiusY = 100,                 speed = 0.05;                              ball.x = centerX;                 ball.y = centerY;                          (function drawFrame(){                 window.requestAnimationFrame(drawFrame,canvas);                 context.clearRect(0,0,canvas.width,canvas.height);                                  //当radius的值相等时为圆周运动                 //当radius的值不想等是为椭圆运动                 ball.x = centerX + Math.sin(angle)*radiusX; //radiusX = 50                 ball.y = centerY + Math.cos(angle)*radiusY; //radiusY = 100                 angle += speed;                                  ball.draw(context);             })();         }``

## 三、两点之间的距离

``    dx = x2 - x1;     dy = y2 - y1;     distance = Math.sqrt(dx*dx + dy*dy); //这不就是勾股定理``

``    <canvas id="canvas" width="500" height="500" style="background:#000;">            your browser not support canvas!        </canvas>        <p id="log"></p>        <script src="../js/utils.js"></script>        <script>        window.onload = function(){                var canvas = document.getElementById('canvas');                var log = document.getElementById('log');                var mouse = utils.captureMouse(canvas);                var context = canvas.getContext('2d');                 //中心位置创建一个方块                var rect = {                    x:canvas.width/2,                    y:canvas.height/2                };                 (function drawFrame(){                    window.requestAnimationFrame(drawFrame,canvas);                    context.clearRect(0,0,canvas.width,canvas.height);                     var dx = mouse.x - rect.x;                    var dy = mouse.y - rect.y;                    var dis = Math.sqrt(dx*dx + dy*dy);                     //画方块                    context.fillStyle = '#ffffff';                    context.fillRect(rect.x-2,rect.y-2,4,4);                    //画线                    context.save();                    context.strokeStyle = '#ffffff';                    context.beginPath()                    context.moveTo(rect.x,rect.y);                    context.lineTo(mouse.x,mouse.y);                    context.closePath();                    context.stroke();                    context.restore();                    //显示距离                    log.style.left = (mouse.x + rect.x)/2 + 'px';                    log.style.top = (mouse.y + rect.y)/2 + 'px';                    log.innerHTML = dis;                })();            }     </script>``

## 四、总结

``    ## 角度旋转     dx = mouse.x - object.x;     dy = mouse.y - object.y;     object.rotation = Math.atan2(dy,dx)*180/Math.PI      ## 平滑运动        value = center + Math.sin(angle)*range;        angle += speed;      ## 正圆运动        x_position = centerX + Math.sin(angle)*radius;        y_position = centerY + Math.cos(angle)*radius;        angle += speed;      ## 椭圆运动        x_position = centerX + Math.cos(angle)*radiusX;        y_position = centerY + Math.sin(angle)*radiusY;        angle += speed;      ##两点间距离     dx = x2 - x1;     dy = y2 - y1;     dist = Math.sqrt(dx*dx + dy*dy); ``