2015-01-14 93 views
2

我有一個圓形項目,點擊後會旋轉到預定義的位置。它幾乎在那裏,但最後一個要求是它總是順時針旋轉到標記。我似乎無法弄清楚如何獲得正確的值,以便當我設置CSS變換:旋轉(Xdeg)時,它將始終順時針旋轉。保持0到360之間的角度對另一部分也是好的,但不是必要的。旋轉元素以點擊位置

看到這個小提琴,下面的JavaScript以及Rotation

$(function() { 
$('body').on('click', '#graph1', function (e) { 

    console.log('********************'); 
    //get mouse position relative to div and center of div for polar origin 
    var pos = getMousePosAndCenter(e, 'graph1'); 

    //get the current degrees of rotation from the css 
    var currentRotationDegrees = getCSSRotation('#graph1'); 
    console.log('CSS Rotation Value: ' + currentRotationDegrees); 

    //current rotation in radians 
    var currentRotationRadians = radians(currentRotationDegrees); 

    //radians where clicked 
    var clickRadiansFromZero = Math.atan2(pos.y - pos.originY, pos.x - pos.originX); 

    //degrees the click is offset from 0 origin 
    var offsetDegrees = degrees(clickRadiansFromZero); 

    //how many degrees to rotate in css to put the mouse click at 0 
    var degreesToZero; 
    if (offsetDegrees >= 0) 
     degreesToZero = currentRotationDegrees - Math.abs(offsetDegrees); 
    else 
     degreesToZero = currentRotationDegrees + Math.abs(offsetDegrees); 

    console.log("Degrees to Zero: " + degreesToZero); 

    //distance in pixels from origin 
    var distance = calculateDistance(pos.originX, pos.originY, pos.x, pos.y); 

    console.log("Distance From Origin(px): " + distance); 

    $('#graph1').css('transform','rotate(' + degreesToZero + 'deg)') 
}); 

}); 

function getMousePosAndCenter(e, id) { 
    var rect = document.getElementById(id).getBoundingClientRect(); 
    return { 
     x: (((e.clientX - rect.left)/rect.width) * rect.width) + 0.5 << 0, 
     y: (((e.clientY - rect.top)/rect.height) * rect.height) + 0.5 << 0, 
     originY: (rect.height/2), 
     originX: (rect.width/2) 
    }; 
} 

function radians(degrees) { 
    return degrees * Math.PI/180; 
}; 

function degrees(radians) { 
    return radians * 180/Math.PI; 
}; 

function calculateDistance(originX, originY, mouseX, mouseY) { 
    return Math.floor(Math.sqrt(Math.pow(mouseX - originX, 2) + Math.pow(mouseY - originY, 2))); 
} 

function getCSSRotation(id) { 
    var matrix = $(id).css('transform'); 
    var values = matrix.split('(')[1], 
    values = values.split(')')[0], 
    values = values.split(','); 

    var a = values[0]; 
    var b = values[1]; 
    var c = values[2]; 
    var d = values[3]; 

    var cssRotation = degrees(Math.atan2(b, a)); 
    return cssRotation; 
} 
+0

加入了小提琴我的答案,給出你的CSS流體幀率。 – jookyone

回答

2

想想開箱:
我們可以CSS3 rotatetransform一個元素即:720° ...
它將使2 順時針圈。(OK,我們UI它只能做一個最大359轉,但讓我們按照數學)
如果我們不是以動畫來810° ...它只是意味着它會做一個90 °順時針移動

所以我們需要做的是永遠增加一個變量程度變量瘋狂!

嘿!如果在某些時候你要保持當前的標準化 0-360度的軌道...
你總可以獲取價值ourCurrentInsanelyHighDegree % 360 = UIdegrees

Here's a jsBin demo

,這是所有你需要的JS。

function getCSSRotation($el) { 
 
    var matrix = $el.css('transform'), 
 
     v = matrix.split('(')[1].split(')')[0].split(','), 
 
     rds = Math.atan2(v[1], v[0]); 
 
    return rds*180/Math.PI <<0; // Degrees 
 
} 
 

 
var $EL = $("#graph1"), 
 
    w = $EL.width(), 
 
    r = w/2,        // Radius 
 
    x = parseInt($EL.css("left"), 10), 
 
    y = parseInt($EL.css("top"), 10), 
 
    d = getCSSRotation($EL);   // Initial degree (ONLY ONCE!) 
 

 
$EL.on("click", function(e){ 
 
    var mx = e.clientX-x-r,    // Click coord X 
 
     my = e.clientY-y-r,    // Click coord Y 
 
     rds = Math.atan2(-my, -mx),  // Radians 
 
     md = (rds*180/Math.PI<<0) + 180; // Mouse Degrees 
 
    d += (360-md);      // always increment to insanity!! 
 
    $(this).css({transform:"rotate("+ d +"deg)"}); 
 
});
#graph1 { 
 
    position:absolute; 
 
    top:10px; left:30px; 
 
    width:200px; height:200px; 
 
    background:url(//placehold.it/200x200&text=IMAGE); 
 
    transition:transform 2s ease; 
 
    transform:rotate(30deg); 
 
    transform-origin:50% 50%; 
 
    border-radius:50%; 
 
} 
 
#marker { 
 
    position: absolute; 
 
    top:110px; 
 
    left:230px; 
 
    border-top:1px solid black; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="graph1"></div> 
 
<div id="marker">Wherever you click, it rotates to here</div>

2

UPDATE: 搞清楚這將是容易做到的,我發現它比我想象的有點困難。 jQuery.animate的另一個解決方案是工作,但animate沒有css動畫所執行的流暢幀率(它運行在GPU上)。

這裏有一個修改撥弄着一個CSS的解決方案:http://jsfiddle.net/2g17cjuL/2/

保持0〜360°之間的角度也將是一個加

你不能不停地前進(即通過旋轉正數),並保持旋轉正向,但是,在我的小提琴offsetDegrees(度數額外旋轉),或者totalDegrees的剩餘部分除以360應該給你你需要在別處使用的東西。

1

要求:它總是順時針旋轉。一件事:如果你使用CSS轉換,它會爲你計算最短路徑。您希望對旋轉方向有更多的控制權,所以我在您的CSS中註釋掉了transition:transform 1s ease;,因爲我們將手動控制它。

JAVASCRIPT

我借this JQuery function和修改,所以我們可以給它一個起始角度和終止角度,它會爲我們的動畫#graph1。 (閱讀鏈接來更改時間,緩解,並使用complete回調)

$.fn.animateRotate = function(angle, start, duration, easing, complete) { 
    var args = $.speed(duration, easing, complete); 
    var step = args.step; 
    return this.each(function(i, e) { 
    args.complete = $.proxy(args.complete, e); 
    args.step = function(now) { 
     $.style(e, 'transform', 'rotate(' + now + 'deg)'); 
     if (step) return step.apply(e, arguments); 
    }; 

    $({deg: start}).animate({deg: angle}, args); 
    }); 
}; 

我還修改了JQuery的,所以它不會逆時針旋轉:當currentRotationDegreesdegreesToZero更大,它會減360,然後使用這個新值作爲animateRotate()的開始位置。

if(currentRotationDegrees > degreesToZero){ 
    currentRotationDegrees -= 360; 
} 

$('#graph1').animateRotate(degreesToZero, currentRotationDegrees); 

這是它的行動。

http://jsfiddle.net/q4nad31t/1/