本節主要內容有:javascript
三角函數介紹html
經常使用三角函數解析java
鼠標跟隨角度旋轉canvas
看到三角函數,勾股定理這樣的數學名詞是否是有種雙腿打顫的感受啊!好吧,就算你已經嚇尿了,也不可否認咱們中學學習的知識終於有了用武之地,挽起袖子,開整!!!bash
什麼是三角函數呢?簡單的定義:所謂三角函數,在幾何上來講就是夾角與邊的關係!爲了更直觀的表示,也爲了讓忘記的同窗回憶起來,這裏我給個示意圖。函數
在上圖中例出了幾個經常使用的三角函數,角度與邊(x, y和R)之間的關係如公式所示!那麼在canvas中角度與邊之間的關係是怎樣的呢?首先,咱們須要知道的是canvas中座標是如何定義的。工具
如圖所示,與普通座標不一樣,canvas座標以整個畫布的左上角做爲座標原點,y軸朝下爲正,x軸水平向右。座標不一樣,對應的角度表示就有所差別,這個差別主要體如今角度的正負上。學習
上圖中canvas的座標與普通座標感受同樣,但我想表達的是在canvas中順時針方向爲正,逆時針爲負。動畫
前面咱們簡單的介紹了三角函數的表示方法以及canvas的座標系統。可是,在實際開發中咱們不只想要經過角度來推出兩邊的距離長度比值。而更關心的是如何經過已知的距離(由於座標的位置很好肯定)來推出角度。這裏咱們要用到反三角函數this
sin(θ)=x/R ---> θ = arcsin(x/R) cos(θ)=y/R ---> θ = arccos(y/R) tan(θ)=x/y ---> θ = arctan(x/y)
對應到javascript中,相應表示方法以下。
sin(θ) ---> Math.sin( θ * Math.PI/180 ) cos(θ) ---> Math.cos( θ * Math.PI/180 ) tan(θ) ---> Math.tan( θ * Math.PI/180 ) θ = arcsin(x/R) ---> Math.asin(x/R)*(180/Math.PI) θ = arccos(y/R) ---> Math.acos(y/R)*(180/Math.PI) θ = arctan(x/y) ---> Math.atan(x/y)*(180/Math.PI)
好吧!看到這裏也許你已經噁心得想吐了。可是,沒辦法這就是數學的魅力!這裏須要強調的是:canvas中角度的表示採用的是弧度制。這樣你就能夠理解 θ * Math.PI/180
是將角度轉成弧度,好比:30° = 30 * π /180 = π / 6
。 而將弧度轉成角度天然就要用弧度值
`Math.asin(x/R) 乘上
180/Math.PI`。這之間的轉換關係,慢慢想一想就明白了!
相比於Math.asin(
)和Math.cos()
這兩個函數,Math.atan()
在開發中用到的更多。它能夠直接經過兩個直角邊獲得對應的角度值。相比於其餘兩個須要經過計算長邊來獲得角度值來講,計算過程更加簡單!可是,該函數在角度的斷定上回出現一個問題——存在兩個相同的角度值而沒法斷定物體具體的旋轉角度。詳細說明以下圖所示。
由於,tan函數的週期是(-π/2, π/2),因爲這一特性致使電腦是沒法判斷旋轉的究竟是哪一個角度!!!這時,另外一個函數就橫空出世了,噹噹噹當,他就是Math.atan2(dy, dx)
!他不只解決了上面咱們說的問題,並且只須要傳入橫縱座標距離就能夠計算出對應的角度值!是否是很酷。
本章的理論知識已經介紹完成。如今,開始咱們的第一個demo——rotate-to-mouse.html
顧名思義就是跟隨鼠標旋轉。首先建立一個文件arrow.js
,這個文件是使用canvas畫一個箭頭,而且爲了從此方便使用,將它寫成一個類文件!代碼以下:
arrow.js文件 function Arrow() { this.x = 0; //初始位置 this.y = 0; this.rotation = 0; //初始旋轉角度 this.color = '#ffff00'; } //在原型上定義draw方法 Arrow.prototype.draw = function(context){ context.save(); context.translate(this.x , this.y); //將座標移到this.x 和 this.y context.rotate(this.rotation); //設置旋轉角度 context.lineWidth = 5; //設置線寬 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.closePath(); //路徑閉合 context.stroke(); //描邊 context.fill(); //填充 context.restore(); }
如今咱們在rotate-to-mouse.html
文件中引入它,來建立一個箭頭
rotate-to-mouse.html 文件 <canvas id='canvas' width="500" height="500" style="background:#ccc;"> you browser not support canvas </canvas> <script src="../js/utils.js"></script> //引入咱們的工具函數文件 <script src="../js/arrow.js"></script> //引入咱們的箭頭函數文件 <script> window.onload = function(){ var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); var centerX = canvas.width/2; var centerY = canvas.height/2; //傳入canvas,獲取鼠標在canvas上移動是的座標 var mouse = utils.captureMouse(canvas); //新建一個arrow對象 var arrow = new Arrow(); //將arrow的座標設置爲canvas的中心 arrow.x = centerX; arrow.y = centerY; //動畫循環函數 (function drawFrame(){ window.requestAnimationFrame(drawFrame,canvas); context.clearRect(0, 0, canvas.width, canvas.height); //獲取dy,dx值 var dx = mouse.x - arrow.x, dy = mouse.y - arrow.y; //設置旋轉角度 arrow.rotation = Math.atan2(dy, dx); //調用draw方法畫出 arrow.draw(context); })(); } </script>
咱們最終獲得的結果就是一個,能夠跟隨鼠標旋轉的箭頭。
這節你應該學會了如何運用三角函數,控制物體的旋轉。重點公式:
dx = mouse.x - object.x; dy = mouse.y - object.y; object.rotation = Math.atan2(dy,dx);