在第二章《
用戶交互》中,介紹過鼠標事件和觸摸事件,可是到目前為止,我們用到鼠標事件和觸摸事件還比較少,在本章中,我們將真正的進入交互動畫中,主要介紹下面的內(nèi)容:
1、鼠標事件和觸摸事件
在介紹三種交互動畫前,我們先來回顧一下鼠標事件和觸摸事件。
1.1 鼠標事件
要觸發(fā)鼠標事件,當然得有觸發(fā)它的設備,不能光用眼睛盯著屏幕, 而觸發(fā)鼠標事件的設備當然是鼠標,它會檢測自身的移動以及按鈕是否單擊,隨后計算機會觸發(fā)一系列的事情:追蹤鼠標指針的位置,確定鼠標按鈕被按下時指針的位置,計算鼠標的移動速度以及確定何時發(fā)生雙擊事件等等。
簡單的來說,鼠標要做的事就是 單擊 和 移動 。
單擊事件又可分解為兩個事件: 鼠標鍵按下 的事件及 按鍵彈起 的事件,大多數(shù)情況下,這兩個事件是同時發(fā)生的,但鼠標要做的例外一個事 移動 時,在這兩個事件之間還會多了一個事件: 按下、移動、再釋放 。
在《
用戶交互》這一章曾經(jīng)說過,我們無法捕捉到canvas上的任何繪制圖形、線等,所以我們只能將事件綁定到canvas元素上,然后通過計算鼠標相對于canvas元素的坐標來判斷鼠標落在哪個繪制到canvas上的物體上。
下面我們就來講解一下如何判斷鼠標是否落在某一個物體(比如前面我們多次繪制的ball)上。
還是用圖來分析:
如上圖所示,一般情況下,當要檢測鼠標是否落在物體上時,我們會將物體放置在一個矩形區(qū)域(圖中的紅框)內(nèi),該矩形區(qū)域也稱為物體的邊界,然后通過獲取鼠標位置,判斷是否落在矩形區(qū)域內(nèi)即可。
當然,你要捕捉的物體必須有x、y、width與height屬性(不管是直接獲取還是計算得出),前面我們已經(jīng)知道如何獲取鼠標相對canvas的坐標了,接下來往tool對象中添加一個方法 containsPoint() ,該函數(shù)接受三個參數(shù),第一個是物體(body)對象(包括x、y、width與height屬性),第二個和第三個參數(shù)則分別代表鼠標位置,返回值為true或false,判斷一個指定的坐標位置是否位于矩形邊界內(nèi)。
tool.containsPoint = function(body, x, y){
return !(x < body.x || x > (body.x + body.width)
|| y < body.y || y > (body.y + body.height));
};
containsPoint()方法返回false表示不在矩形邊界內(nèi),否則在矩形邊界內(nèi)。
將物體包裹在一個矩形之內(nèi),這是我們大多數(shù)情況下采取的方法,如果你想更加精確,那就要進行更加精確的計算了,比如:物體是圓形,那你就要使用三角函數(shù)來計算鼠標位置和圓心的距離:
dx = point.x -body.x;
dy = point.y - body.y;
dist = Math.sqrt(dx*dx + dy*dy)
if(dist < body.radius){
console.log('鼠標移到物體上');
}
實例:
1.2 觸摸事件
捕獲觸摸事件與捕獲鼠標事件并沒有太大的區(qū)別,在tool.captureMT()方法中,我已經(jīng)將觸摸事件和鼠標事件封裝在了一起。
與鼠標事件不同的是,要觸發(fā)觸摸事件的不是鼠標,而是手指、觸摸筆等等,而且鼠標會一直都在,而手指卻不是一直處在觸摸狀態(tài),所以添加一個isPressed屬性,用于判斷屏幕上是否有手指在觸摸。
var isPressed = false;
function touchstart(event){
isPressed = true; //
};
function touchend(event){
isPressed = false;
};
2、移動物體
2.1. 拖曳物體
拖曳物體其實就是通過不斷更新物體的坐標位置使其追隨鼠標指針的位置。
拖曳圓球看看:
關(guān)鍵代碼:
ball.x = event.point.x;
ball.y = event.point.y;
2.2 投擲物體
投擲物體就是用鼠標選中一個物體,拖曳著它向某個方向移動,松開鼠標后,物體沿著拖曳的方向繼續(xù)移動。
在投擲物體時,必須在拖曳物體的過程中計算物體的速度向量,并在釋放物體時將這速度向量賦給物體。比如,如果你以每幀10個像素的速度向左拖曳小球,那么在你釋放球時,它的速度向量應該是vx = -10。
那么如何計算出物體被拖曳時的速度向量,只需按照如下計算:
在動畫中,我們以幀為單位,所以時間也可以說是幀數(shù)。在拖曳物體時,它會在每一幀擁有一個新的位置,用當前幀的位置減去上一幀的位置,就可以計算出這一幀所移動的距離,這也就是每幀移動像素的速度向量值。
實例:
拖曳物體,然后松開鼠標看看效果:
關(guān)鍵代碼:
ball.speed.x = ball.x - oldX;
ball.speed.y = ball.y - oldY;
oldX = ball.x;
oldY = ball.y;
用小球當前的x、y軸坐標分別減去oldX與oldY,從而獲得小球當前的速度向量,并將它們保存在球的速度中,最后將oldX與oldY變量更新為小球當前的位置。
總結(jié)
在這一章中,我們進一步了解了動畫中的交互行為。掌握上面這些內(nèi)容,你就可以在動畫中實現(xiàn)對物體的拖曳、釋放以及投資。
到目前為止,《canvas動畫包教不包會》系列已經(jīng)進行了七章,分別介紹了用戶交互、三角函數(shù)、速度與加速度、邊界和摩擦力、移動物體,這些是動畫的基礎知識,要想輕松的實現(xiàn)豐富的動畫,就必須好好掌握這些。
從下一章開始,將進入高級動畫,緩動和彈動。
更多建議: