2010-02-10 16 views
23

Si tengo
<div id="curve" style="position:relative; height:100px; width:100px; />¿Cómo animarías algo para que siga una curva?

¿Cómo voy a hacer que se mueva en una curva? Busqué en Google y todo pero parece que no puedo encontrar otro ejemplo que llame a dos funciones a la vez. Este es el tipo de código que me gustaría, pero no funciona:

$('#curve').click(function() { 
    $(this).animate(
     { 
      top: 400, 
      left = $(this).left() + $(this).left()*$(this).left() 
     }, 
     'slow', 
     function() { $(this).animate({ left: 600 }, 'fast'); } 
    ); 
}); 

Incluso si eso no es código correcto, creo animar sólo toma "destinos" de algo para ir, por lo que un destino wouldn dinámico' t trabajo, creo. ¿Qué estoy buscando para que esto funcione?

EDIT :: Definitivamente voy a retomar ese complemento, pero también me pregunto por qué este código no funciona como esperaba.

Aquí hay otro intento de utilizar un bucle y el método de retardo

$('#curve').click(function() { 
    for (var i=0; i<400; i++) 
    { 
     $(this).delay(1000); 
     $(this).css({ top: i, left: i*1.5 }); 
    } 
}); 

Excepto que acaba al instante va a esa posición, sin retraso ni nada. entonces, si comenzaba en [0,0], tan pronto como hago clic en él, se teletransporta a [400,600]. ¿Por qué no funciona el retraso?

+0

No creo que haya una función de retardo en jQuery, a menos que use el plugin de retraso ... –

+0

http://api.jquery.com/delay/ – Justen

+0

asegúrese de que está usando v1.4 + de jQuery – philfreo

Respuesta

15

Creo que esta vez, debes recalcular la curva animada parte por parte en js y luego hacerlo moviendo por partes pequeñas (= probablemente puedas encontrar el plugin O tendrás que hacer todas las operaciones matemáticas por ti mismo)

Editar 2: Se ha movido el enlace previamente agregado =>http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/. Gracias, Zach.

Editar 1: esto me intrigó, así que lo hice poca investigación Google - al igual que pensé: Plugin listo para su uso aquí: http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/

+0

Gracias por el enlace. Te será muy útil, ¿podrías mirar mi edición? – Justen

+2

enlace actualizado: http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/ –

+0

@Gracias Zach, voy a seguir adelante y editarlo en la respuesta –

16

El jQuery.path plugin es lo que quiere:

Ejemplo: Animación a lo largo de un arco

var arc_params = { 
    center: [285,185], 
    radius: 100,  
    start: 30, 
    end: 200, 
    dir: -1 
}; 

$("my_elem").animate({path : new $.path.arc(arc_params)}); 

Ejemplo: animar a lo largo de una onda sinusoidal

var SineWave = function() { 
    this.css = function(p) { 
     var s = Math.sin(p*20); 
     var x = 500 - p * 300; 
     var y = s * 50 + 150; 
     var o = ((s+2)/4+0.1); 
     return {top: y + "px", left: x + "px", opacity: o}; 
    } 
}; 

$("my_elem").animate({path : new SineWave}); 
+0

Gracias por el código de ejemplo. +1 – Justen

+0

@philfreo, el plugin jquery.path ya no parece funcionar. Alguna idea de como hacer esto? – alias51

+0

El enlace sigue funcionando, por lo que no estoy seguro de lo que quiere decir. – philfreo

11

Aquí hay una pequeña biblioteca simple que escribí que permite curvas Bézier arbitrarias para una ruta de animación, e incluso calcula el ángulo de rotación para usted. (La biblioteca no se pule o documentado todavía, pero muestra lo fácil que es ponerse de pie sobre los hombros de DOM de SVG, incluso cuando no tiene elementos SVG en su página.)

http://phrogz.net/SVG/animation_on_a_curve.html

Screenshot of website

Puede editar el código y ver la curva/animación cambiar, o editar la curva y ver la actualización del código.

En caso de que mi sitio está desactivado, aquí está el código relevante para la posteridad:

function CurveAnimator(from,to,c1,c2){ 
    this.path = document.createElementNS('http://www.w3.org/2000/svg','path'); 
    if (!c1) c1 = from; 
    if (!c2) c2 = to; 
    this.path.setAttribute('d','M'+from.join(',')+'C'+c1.join(',')+' '+c2.join(',')+' '+to.join(',')); 
    this.updatePath(); 
    CurveAnimator.lastCreated = this; 
} 
CurveAnimator.prototype.animate = function(duration,callback,delay){ 
    var curveAnim = this; 
    // TODO: Use requestAnimationFrame if a delay isn't passed 
    if (!delay) delay = 1/40; 
    clearInterval(curveAnim.animTimer); 
    var startTime = new Date; 
    curveAnim.animTimer = setInterval(function(){ 
    var elapsed = ((new Date)-startTime)/1000; 
    var percent = elapsed/duration; 
    if (percent>=1){ 
     percent = 1; 
     clearInterval(curveAnim.animTimer); 
    } 
    var p1 = curveAnim.pointAt(percent-0.01), 
     p2 = curveAnim.pointAt(percent+0.01); 
    callback(curveAnim.pointAt(percent),Math.atan2(p2.y-p1.y,p2.x-p1.x)*180/Math.PI); 
    },delay*1000); 
}; 
CurveAnimator.prototype.stop = function(){ 
    clearInterval(this.animTimer); 
}; 
CurveAnimator.prototype.pointAt = function(percent){ 
    return this.path.getPointAtLength(this.len*percent); 
}; 
CurveAnimator.prototype.updatePath = function(){ 
    this.len = this.path.getTotalLength(); 
}; 
CurveAnimator.prototype.setStart = function(x,y){ 
    var M = this.path.pathSegList.getItem(0); 
    M.x = x; M.y = y; 
    this.updatePath(); 
    return this; 
}; 
CurveAnimator.prototype.setEnd = function(x,y){ 
    var C = this.path.pathSegList.getItem(1); 
    C.x = x; C.y = y; 
    this.updatePath(); 
    return this; 
}; 
CurveAnimator.prototype.setStartDirection = function(x,y){ 
    var C = this.path.pathSegList.getItem(1); 
    C.x1 = x; C.y1 = y; 
    this.updatePath(); 
    return this; 
}; 
CurveAnimator.prototype.setEndDirection = function(x,y){ 
    var C = this.path.pathSegList.getItem(1); 
    C.x2 = x; C.y2 = y; 
    this.updatePath(); 
    return this; 
}; 
+0

Estoy confundido: ¿Se puede usar su biblioteca para animar a lo largo de una curva bezier definida por bezierCurveTo o necesita tener una ruta SVG? – Thomas

+1

@Thomas El constructor 'CurveAnimator', como se muestra arriba, toma cuatro puntos y crea una ruta simple para usted. Sin embargo, si establece la propiedad '.path' del animador en una ruta SVG con una ruta arbitraria (que no tiene que estar en la página) puede hacer lo que desee. – Phrogz

1

Hay un pequeño script, sólo por la animación que no es en línea recta, llamados pathAnimator

Es muy muy pequeño y súper eficiente. y ni siquiera necesita jQuery;)

Cuestiones relacionadas