一. 需求:

来一个挑战:绘制一个物体,并让它随着鼠标旋转,使它总能指向鼠标。

假设这个可供旋转的对象为箭头对象,箭头的构造函数如下:

// 箭头绘制的构造函数
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();
}

二. 解决思路:

鼠标的位置可以通过getMouse(e).x和getMouse(e).y属性获得它的坐标值。

箭头的位置可以通过arrow.x和arrow.y得到。

通过这两个坐标的差值,就可以计算到三角形两边的长度dx、dy。此时,只需要通过Math.atan2(dy, dx)方法即可计算出角度的大小,并将其赋值给箭头对象的rotation属性。

箭头应旋转的角度如下图所示:

image_1aqjs39q1194kue1h1k1ri4kj99.png-20.7kB

该过程如下:

var dx = getMouse(e).x - arrow.x,
    dy = getMouse(e).y - arrow.y;

arrow.rotation = Math.atan2(dy, dx); // 计算箭头旋转的弧度

完整代码如下:

<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>

演示如下:http://codepen.io/dengzhirong/pen/rLbkXj

三. 总结:

实际上,旋转功能不限于鼠标。可以将该功能演变成强制一个物体围绕特定的点旋转。

旋转动画用到的三角函数是:Math.atan2(dy, dx)。根据直角三角形的对边和邻边,获得角的弧度。从而计算出旋转的角度。

朝鼠标(或任意一点)旋转的公式如下:

// 假设mouse为旋转跟随点,object为旋转物体
dx = mouse.x - object.x;
dy = mouse.y - object.y;
object.rotation = Math.atan2(dy, dx) * 180 / Math.PI;
本文作者:子匠_Zijor,转载请注明出处:http://www.dengzhr.com/js/953