canvas中的三角运动(2) —— 旋转动画

xqlw3528 8年前
   <h2>一. 需求:</h2>    <p>来一个挑战: 绘制一个物体,并让它随着鼠标旋转,使它总能指向鼠标。</p>    <p>假设这个可供旋转的对象为箭头对象,箭头的构造函数如下:</p>    <pre>  <code class="language-java">// 箭头绘制的构造函数  function Arrow() {      this.x = 0;      this.y = 0;      this.color = "#ffff00";      this.rotation = 0;  }  Arrow.prototype.draw = function(context) {      context.save();      context.translate(this.x, this.y);      context.rotate(this.rotation);      context.lineWidth = 2;      context.fillStyle = this.color;      context.beginPath();      context.moveTo(-50, -25);      context.lineTo(0, -25);      context.lineTo(0, -50);      context.lineTo(50, 0);      context.lineTo(0, 50);      context.lineTo(0, 25);      context.lineTo(-50, 25);      context.lineTo(-50, -25);      context.closePath();      context.fill();      context.stroke();      context.restore();  }</code></pre>    <h2>二. 解决思路:</h2>    <p>鼠标的位置可以通过getMouse(e).x和getMouse(e).y属性获得它的坐标值。</p>    <p>箭头的位置可以通过arrow.x和arrow.y得到。</p>    <p>通过这两个坐标的差值,就可以计算到三角形两边的长度dx、dy。此时,只需要通过 <strong>Math.atan2(dy, dx)</strong> 方法即可计算出角度的大小,并将其赋值给箭头对象的rotation属性。</p>    <p>箭头应旋转的角度如下图所示:</p>    <p><img src="https://simg.open-open.com/show/ba03e0aec73843c475ecd7eceb5f2dad.png"></p>    <p>该过程如下:</p>    <pre>  <code class="language-java">var dx = getMouse(e).x - arrow.x,      dy = getMouse(e).y - arrow.y;    arrow.rotation = Math.atan2(dy, dx); // 计算箭头旋转的弧度</code></pre>    <p>完整代码如下:</p>    <pre>  <code class="language-java"><canvas id="canvas" width="200" height="200" style="background: #ccc;"></canvas>  <script type="text/javascript">      // 箭头绘制的构造函数      function Arrow() {          this.x = 0;          this.y = 0;          this.color = "#ffff00";          this.rotation = 0;      }      Arrow.prototype.draw = function(context) {          context.save();          context.translate(this.x, this.y);          context.rotate(this.rotation);          context.lineWidth = 2;          context.fillStyle = this.color;          context.beginPath();          context.moveTo(-50, -25);          context.lineTo(0, -25);          context.lineTo(0, -50);          context.lineTo(50, 0);          context.lineTo(0, 50);          context.lineTo(0, 25);          context.lineTo(-50, 25);          context.lineTo(-50, -25);          context.closePath();          context.fill();          context.stroke();          context.restore();      }        var canvas = document.getElementById("canvas"),          context = canvas.getContext("2d"),          arrow = new Arrow();        arrow.x = canvas.width / 2;      arrow.y = canvas.height / 2;        // 鼠标跟随事件      canvas.addEventListener("mousemove", function(e) {          context.clearRect(0, 0, canvas.width, canvas.height);          var dx = getMouse(e).x - arrow.x,              dy = getMouse(e).y - arrow.y;            arrow.rotation = Math.atan2(dy, dx); // 计算箭头旋转的弧度          arrow.draw(context);      }, false);        // 获取鼠标的当前位置      function getMouse(event) {          var event = event || window.event;          var mouse = {};          var x, y;          if(event.pageX || event.pageY) {              x = event.pageX;              y = event.pageY;          } else if(event.clientX || event.clientY) {              var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;              var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;              x = event.clientX + scrollLeft;              y = event.clientY + scrollTop;          }          mouse.x = x;          mouse.y = y;          return mouse;      }  </script></code></pre>    <p>演示如下: <a href="/misc/goto?guid=4959677072273599888" rel="nofollow,noindex">http://codepen.io/dengzhirong/pen/rLbkXj</a></p>    <h2>三. 总结:</h2>    <p>实际上,旋转功能不限于鼠标。可以将该功能演变成强制一个物体围绕特定的点旋转。</p>    <p>旋转动画用到的三角函数是: Math.atan2(dy, dx) 。根据直角三角形的对边和邻边,获得角的弧度。从而计算出旋转的角度。</p>    <p>朝鼠标(或任意一点)旋转的公式如下:</p>    <pre>  <code class="language-java">// 假设mouse为旋转跟随点,object为旋转物体  dx = mouse.x - object.x;  dy = mouse.y - object.y;  object.rotation = Math.atan2(dy, dx) * 180 / Math.PI;</code></pre>    <p> </p>    <p>来自:http://www.dengzhr.com/js/953</p>    <p> </p>    <p><span style="color:rgb(255, 255, 255)">Save</span></p>