用戶交互也許是咱們學習canvas動畫中首先須要掌握的部分。畢竟,若是沒有交互或者向動畫中作一些動態的輸入,那麼這跟看電影有什麼區別呢?用戶交互基於事件,通常來講包括:鼠標事件
,觸摸事件
和鍵盤事件
。canvas
在理解事件以前,你須要明白什麼是listener
和handler
。
listener(即監聽器)決定當一個事件發生時是否作出反應。handler(即執行者)是一個函數,當事件發生時被調用。好了,扯了這麼多直接上代碼:瀏覽器
element.addEventListener(type, handler[, useCapture]); type: 事件類型 handler: 事件執行函數 useCapture: 可選,爲布爾值false/true, 表示在冒泡/捕獲階段執行
經過方法addEventListener
來爲某一元素添加事件,具體到咱們的canvas上是什麼樣的呢?加入咱們如今想要在canvas上綁定一個mousedown
事件,具體代碼以下:函數
canvas.addEventListener('mousedown', function(event){ console.log("Mouse pressed on element"); }, false)
這樣咱們就爲canvas綁定了鼠標點擊事件,當在canvas上按下鼠標是就會在控制檯看到打印出 "Mouse pressed on element"。工具
那麼既然有添加事件(addEventListener
),就有移除事件(removeEventListener
),使用方式與添加事件幾乎徹底同樣:學習
element.removeEventListener(type, handler[, useCapture]); type: 事件類型 handler: 事件執行函數 useCapture: 可選,爲布爾值false/true, 表示在冒泡/捕獲階段執行
惟一須要注意的是handler
,即移除事件的函數,這裏只能寫函數名,而不能像添加事件同樣將整個功能函數所有寫入。也就是說,在添加某個事件的時候,咱們能夠將須要執行的函數寫在事件監聽以外並命名,這樣若是你想要在後續的代碼中移除該事件,直接將函數名傳入移除事件的handler
中便可。動畫
如今讓咱們來實驗下先爲canvas添加一個事件,再將其移除code
<body> <canvas id="canvas" width="500" height="500"></canvas> <script></script> <script> window.onload = function(){ var canvas = document.getElementById('canvas'); //定義的執行函數add function add(event){ console.log("mouse down"); } canvas.addEventListener('mousedown', add, false); //移除事件mousedown canvas.removeEventListener('mousedown', add, false) } </script> </body>
如今你能夠看看控制檯是否還能打印出「mouse down」!對象
鼠標事件一共能夠分爲:seo
mousedown事件
mouseup
click
dbclick
mousewheel
mouseover
mouseout
每個鼠標事件都包含兩個屬性來決定當前鼠標的位置:pageX
和pageY
。經過pageX
和pageY
,還有canvas元素的偏移位置,咱們就可以計算出鼠標具體是在canvas元素的什麼位置。爲了考慮不一樣瀏覽器的兼容性,以防萬一你可使用clientX
和clientY
。在這裏,咱們建立一個js文件,名爲**utils.js**
,這個文件是咱們的一個工具函數,裏面會逐漸加入一些咱們重複使用的方法,那麼如今咱們向咱們的工具函數中添加第一個方法captureMouse
,具體代碼以下:
utils.js文件 //將utils定義爲window對象下的一個屬性,屬性值爲對象 window.utils = {}; //在utils對象上定義捕獲座標的方法 window.utils.captureMouse = function(element){ //定義一個名爲mouse的對象 var mouse = {x:0,y:0}; //爲元素綁定mousemove事件 element.addEventListener('mousemove',function(event){ var x,y; //獲取鼠標位於當前屏幕的位置, 並做兼容處理 if(event.pageX||event.pageY){ x = event.pageX; y = event.pageY; }else{ x = event.clientX + document.body.scrollLeft +document.documentElement.scrollLeft; y = event.clientY + document.body.scrollTop +document.documentElement.scrollTop; } //將當前的座標值減去元素的偏移位置,即爲鼠標位於當前canvas的位置 x -= element.offsetLeft; y -= element.offsetTop; mouse.x = x; mouse.y = y; },false); //返回值爲mouse對象 return mouse; }
這個方法將DOM元素做爲參數傳入,這樣咱們只要將canvas傳入就能夠獲取到鼠標在當前canvas的位置。具體代碼以下:
<canvas id="canvas" width='500' height="500" style="background:#000"> <p>you browser not support canvas!<p> </canvas> <script src='../js/utils.js'></script> <script> window.onload = function(){ var canvas = document.getElementById('canvas'), //將canvas傳入,該方法會返回一個包含屬性x和y的對象 mouse = utils.captureMouse(canvas); //爲canvas綁定mousedown事件,當鼠標按下的時候打印出當前鼠標相對於canvas的座標值 canvas.addEventListener('mousedown',function(event){ console.log("x:" +mouse.x +",y:" + mouse.y); }); </script>
Have a try!!!看看可否成功。
其實,關於canvas的鼠標位置獲取的方法還能夠應用它自身的一個方法getBoundingClientRect
,這裏作一個介紹,你可使用,但本系列文章主要使用上面這種更具普遍性的方法。具體代碼能夠參考以下:
canvas.addEventListener('mousedown',function(event){ //event兼容處理 var event = event || window.event; //兼容處理,獲取當前鼠標相對屏幕的座標 var winX = event.clientX+document.body.scrollLeft +document.documentElement.scrollLeft || event.pageX; var winY = event.clientY+document.body.scrollTop +document.documentElement.scrollTop || event.pageY; //定義一個對象 var can = {x:0, y:0}; //調用getBoundingClientRect方法,該方法返回一個對象,包含canvas的left、 top、 width、 height等值 var canBox = canvas.getBoundingClientRect(); //(winX - canBox.left):與上面的含義同樣,是減去canvas的偏移量 //(canvas.width/canBox.width):通常來講canvas.width和canBox.width是同樣的,也就是說這兩個的比值爲1.但不排除你會爲canvas設置邊框,這是實際的座標位置就會有所變化,好比canvas.width = 500, 你可能設置了一個1px的邊框,那麼canBox.width = 502, 因此比值就不爲1了。這樣作只是讓數據更精確。 can.x = (winX - canBox.left)*(canvas.width/canBox.width); can.y = (winY - canBox.top)*(canvas.height/canBox.height); //輸出 console.log(can.x,can.y); },false);
鍵盤事件就兩個:
keydown
keyup
咱們一樣能夠向綁定鼠標事件那樣爲canvas綁定鍵盤事件。好吧!如今咱們來看看,如何將一個鍵盤事件綁定到window(爲何不直接綁定到canvas上呢?想一想)上:
<body > <p>任意按下按鍵</p> <script> window.onload = function(){ //定義鍵盤事件 function onKeyboard(event){ switch (event.keyCode){ case 38: console.log('up!'); break; case 40: console.log('down!'); break; case 37: console.log('left!'); break; case 39: console.log('right!'); break; default: console.log(event.keyCode); } } //爲window對象綁定鍵盤事件 window.addEventListener('keydown',onKeyboard,false); } </script> </body>
試一試,當按下鼠標的方向鍵是是否在控制檯打印出了相應的信息!
觸摸事件包括如下3種:
touchstart
touchend
touchmove
觸摸實踐中,手指就充當了鼠標的做用。一樣咱們最爲關心的是當前觸摸的位置。和captureMouse
方法同樣,這裏在咱們的工具函數文件中,須要添加一新的方法來捕獲觸摸的位置,名爲captureTouch
,如今在utils.js文件中添加以下方法:
utils.js文件 window.utils.captureTouch = function (element) { var touch = { x: null, y: null, isPressed: false, event: null }; var body_scrollLeft = document.body.scrollLeft, element_scrollLeft = document.documentElement.scrollLeft, body_scrollTop = document.body.scrollTop, element_scrollTop = document.documentElement.scrollTop, offsetLeft = element.offsetLeft, offsetTop = element.offsetTop; // 綁定touchstart事件 element.addEventListener('touchstart', function (event) { touch.isPressed = true; touch.event = event; }, false); // 綁定touchend事件 element.addEventListener('touchend', function (event) { touch.isPressed = false; touch.x = null; touch.y = null; touch.event = event; }, false); //綁定touchmove事件 element.addEventListener('touchmove', function (event) { var x, y, touch_event = event.touches[0]; //第一次touch if (touch_event.pageX || touch_event.pageY) { x = touch_event.pageX; y = touch_event.pageY; } else { x = touch_event.clientX + body_scrollLeft + element_scrollLeft; y = touch_event.clientY + body_scrollTop + element_scrollTop; } //剪去偏移量 x -= offsetLeft; y -= offsetTop; touch.x = x; touch.y = y; touch.event = event; }, false); //返回touch對象 return touch; };
這一節主要介紹用戶與canvas交互的各類事件,重要的是你應該在你本身的工具函數文件中包含了如下兩個方法:utils.captureTouch
和utils.captureMouse
這兩個方法都是爲了獲取當前相對於canvas元素的位置。咱們將在後面的章節中頻繁使用。固然,除了這兩個方法,因爲咱們使用的requestAnimationFrame
方法一樣也涉及到兼容性的問題,咱們將它一同添加到utils.js
中,具體代碼請查看utils.js
文件。下一節,三角函數座標旋轉敬請期待!!!