2013-04-04 11 views
5

Abbiamo ottenuto 3 punti: iniziare, fine e la posta.punto Javascript per punto di calcolo angolo

description

L'immagine elettronica, si muove in una linea curva dal punto di inizio e di fine, questo è fatto da jQuery animare.

Ora il passaggio successivo consiste nel ruotare l'immagine della posta mentre l'animazione è in esecuzione. Quindi al punto iniziale e al punto finale sarebbe ruotato di 0 gradi, ma durante l'animazione dovrebbe ruotare di fronte al percorso dell'animazione. (Vedi immagine)

Quello che ho cercato:

JSFiddle

// Init dom elements 
var $start = $('#start'); 
var $end = $('#end'); 
var $mail = $('#mail'); 

// Get position coordinates 
var startPos = $start.position(); 
var endPos = $end.Position(); 

// Angle calculation 
var getAngle = function(currX, currY, endX, endY) { 
    var angle = Math.atan2(currX - endX, currY - endY) * (180/Math.PI); 

    if (angle < 0) { 
    angle = Math.abs(angle); 
    } else { 
    angle = 360 - angle; 
    } 

    return angle; 
}; 

// Mail angle 
var getMailAngle = function() { 
    var currPos = $mail.position(); 
    var endPos = $end.position(); 
    return getAngle(currPos.left, currPos.top, endPos.left, endPos.top); 
}; 

// Animate 
$mail.animate({top: endPos.top, left: endPos.left}, { 
    specialEasing: {left: "easeInSine", top: "linear"}, 

    // Executed each "animation" frame, so we rotate here. 
    step: function() { 
    var angle = getMailAngle(); 
    $(this).css('transform', 'rotate(' + angle + 'deg')); 
    } 
}); 

Ma il codice di cui sopra non è corretto, l'angolo non faccia quando ha iniziato/finito, ho molto poco Esperienza con la matematica geometrica, quindi apprezzo molto l'aiuto per i calcoli rotanti.

+0

Non vedo perché dovrebbe essere rivolto verso l'alto quando è stato avviato/terminato dato che il percorso nella foto non esce dalla partenza e immette la fine con un angolo di 90 °. –

+0

@MattBall l'animazione vera effettivamente inizia e termina con un angolo di 90 °, l'immagine è stata rapidamente in Photoshop e ha un offset tristemente – randomKek

+1

È questo che vedi? http://jsfiddle.net/R5dRd/ – bfavaretto

risposta

4

Prima di tutto, è necessario utilizzare un'animazione di andamento che inizi e termini con lo stesso "angolo". Se si guardano i diversi easing options, swing, easeInOutQuad e easeInOutSine sono alcune delle opzioni valide.

Per calcolare un'approssimazione dell'angolo, è possibile osservare la posizione corrente dell'icona della posta e la sua posizione successiva (nel fotogramma di animazione successivo). Per ottenere una buona approssimazione è necessario calcolare "manualmente" la posizione corrente e successiva usando la funzione di andamento. Ciò significa anche che è necessario controllare manualmente l'animazione.

Ecco uno snippet di codice e lo puoi anche vedere su JSFiddle.

// Init dom elements 
var $start = $('#start'); 
var $end = $('#end'); 
var $mail = $('#mail'); 

// Get position coordinates 
var startPos = $start.offset(); 
var endPos = $end.offset(); 

// Angle calculation 
var getAngle = function(currX, currY, endX, endY) { 
    var angle = Math.atan2(currX - endX, currY - endY) * (180/Math.PI); 

    if (angle < 0) { 
    angle = Math.abs(angle); 
    } else { 
    angle = 360 - angle; 
    } 

    return angle; 
}; 

// Animate 
var maxframe = 1000; 
$({frame: 0}).animate({frame: maxframe}, { 
    easing: "linear", 
    duration: 1000, 

    // Executed each "animation" frame, so we rotate here. 
    step: function() { 
     var easing = $.easing.easeInOutQuad; 
     var left = easing(0, this.frame, startPos.left, endPos.left - startPos.left, maxframe); 
     var leftNext = easing(0, this.frame+1, startPos.left, endPos.left - startPos.left, maxframe); 

     var top = startPos.top + (endPos.top - startPos.top) * this.frame/maxframe; 
     var topNext = startPos.top + (endPos.top - startPos.top) * (this.frame + 1)/maxframe; 

     var angle = getAngle(left, top, leftNext, topNext);  
     $mail.offset({left: left, top: top}); 
     $mail.css('transform', 'rotate(' + angle + 'deg)'); 
    }, 

    // Set the final position 
    complete: function() { 
     $mail.offset($end.offset()); 
     $mail.css('transform', ''); 
    } 
}); 
+0

Queste formule faranno sì che l'icona della posta provi sempre a puntare direttamente verso il punto finale, non necessariamente tangente al suo percorso corrente. – thelr

+2

Ciao Seth. No, non punta sempre verso il punto finale. Puoi vedere questo facendo una funzione di andamento più complessa. Vedi questo [JSFiddle] (http://jsfiddle.net/Mn88E/1/). –

+0

Hai ragione. Ho pensato che il tuo frammento di codice fosse lo stesso di quello menzionato in precedenza (il quale punta sempre al punto finale). Funziona perfettamente su JSFiddle. – thelr