canvas中的三角運動(2) —— 旋轉動畫

xqlw3528 8年前發布 | 7K 次閱讀 JavaScript開發 canvas

一. 需求:

來一個挑戰: 繪制一個物體,并讓它隨著鼠標旋轉,使它總能指向鼠標。

假設這個可供旋轉的對象為箭頭對象,箭頭的構造函數如下:

// 箭頭繪制的構造函數
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屬性。

箭頭應旋轉的角度如下圖所示:

該過程如下:

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

arrow.rotation = Math.atan2(dy, dx); // 計算箭頭旋轉的弧度</code></pre>

完整代碼如下:

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

演示如下: 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;

 

來自:http://www.dengzhr.com/js/953

 

Save

 本文由用戶 xqlw3528 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!