Js 跟手轉動的羅盤指標

小蟲巨蟹發表於2019-02-27

或許跟手拖拽已經足夠普遍,可是跟手沿著圓弧轉動的羅盤指標,卻依然足夠挑戰,先來看看我們要實現的小目標,檢視效果(請用手機開啟,或者用chrome的手機模式開啟)

任務分解、分析

一、 跟手拖拽的一般套路

  1. touchstart 的時候記錄初始位置:ox,oy
  2. touchmove 的過程中移動到新的位置:x = x1-ox, y = x1 – oy
  3. touchend 的時候,這步好像也不需要幹啥

二、圓弧轉盤轉動的一般做法

  1. 設定圓心轉動的原點
  2. 動態的修改旋轉的角度(或者弧度)

三、合二為一
如何將手勢動作反應到圓弧的角度或者弧度變更上,這是問題的癥結所在,起初我也為此而困頓不已

先是通過設定某一位移而旋轉固定的角度,但是很難確定圓弧的有效位移,就算確定了有效位移,當旋轉到一百八十度之後也蒙圈,反著動了~~
而且這種不均勻的運動實在也難以服眾

糾結之際,我拿起了紙和筆,重新尋找靈感:

注意到圖片紅色的點是圓心,綠色的點是 touchstart 時候記錄下的起始點,藍色的點是 touchmove 的過程中不斷變化的目標點。我們的目標很明確,計算指標變化的角度(或弧度),用我僅有的初中數學知識思考得知,知道三角形的每個頂點,是可以求出每個頂角的角度。運用三角形的餘弦定理,求弧度值:

    //獲得point2頂角的弧度值
    //point1傳入起始點,point2傳入圓心,point3傳入結束點,可求得指標運動的夾角弧度
    function getAngle(point1, point2, point3) {
        var bb = (point2.y - point1.y)*(point2.y - point1.y) + (point2.x - point1.x)*(point2.x - point1.x);
        var aa = (point3.y - point1.y)*(point3.y - point1.y) + (point3.x - point1.x)*(point3.x - point1.x);
        var cc = (point3.y - point2.y)*(point3.y - point2.y) + (point3.x - point2.x)*(point3.x - point2.x);
        var cosa = (bb + cc - aa)/(2*Math.sqrt(bb)*Math.sqrt(cc));
        return Math.acos(cosa);
    }複製程式碼

剛才只考慮了順時針的情況,不能忽略逆時針的方向:

這種情況的弧度值為 -getAngle(point1, point2, point3),這並不難理解,難點在於如何判斷到底是逆時針還是順時針,可以通過如下的面積量的方法來判斷順時針還是逆時針


    //通過面積量的方法來判斷順時針還是逆時針
    //point1傳入圓心,point2傳入起始點,point3傳入終點
    function duration(point1, point2, point3) {
        var sp = (point1.x-point3.x)*(point2.y-point3.y)-(point1.y-point3.y)*(point2.x-point3.x);
        console.log(sp);
        if(sp>0) {//順時針
            return 1
        } else if(sp<0) {="" 逆時針="" return="" -1="" }="" else="" 0;="" }<="" code="">複製程式碼

完整的程式程式碼

go ~~

結語

Js 特效,有時候程式碼不需要很多,但是找到其中的規律再轉化為機器認識的語言絕非易事,難就難在這個數學建模的過程,需要一點想象力,可以給予的經驗就是,拿起你的筆和紙,去畫,靈感自來

歡迎來到我的會客廳:

相關文章