How would you animate something so that it follows

2019-01-13 06:32发布

If I have
<div id="curve" style="position:relative; height:100px; width:100px; />

How would I make it move on a curve? I've googled and everything but can't seem to find another example that would call two functions at once. This is the kind of code I would like, but doesn't work:

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

Even if that's not correct code, I believe animate only takes "destinations" for something to go to, so a dynamic destination wouldn't work I think. What am I looking for to make this work?

EDIT:: I'll definitely pick up that plugin, but I'm also wonder why this bit of code doesn't work as I'd expect it to.

Here's another attempt using a for loop and the delay method

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

Except it just instantly goes to that position, no delay or anything. so if it was starting at [0,0], as soon as I click it it teleports to [400,600]. Why doesn't the delay work?

5条回答
Explosion°爆炸
2楼-- · 2019-01-13 06:34

There's a tiny script, just for animation which isn't in straight lines, called pathAnimator

It's very very small and super efficient. and you don't even need jQuery ;)

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-13 06:43

I think that this time, you have to recalculate animated curve part by part in js and then do it by moving by little parts (= you probably could find plugin OR you'll have to do all the math by yourself)

Edit 2: Previously added link was moved=> http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/. Thanks, Zach.

Edit 1: this intrigued me, so I did little google research - just as I thought: plugin ready for use here: http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/

查看更多
男人必须洒脱
4楼-- · 2019-01-13 06:47

Here's a simple little library I wrote that allows arbitrary cubic Bézier curves for an animation path, and even calculates the rotation angle for you. (The library isn't polished or documented yet, but it shows how easy it is to stand on the shoulders of SVG's DOM even when you have no SVG elements in your page.)

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

Screenshot of website

You can either edit the code and watch the curve/animation change, or edit the curve and see the code update.

In case my site is down, here's the relevant code for posterity:

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;
};
查看更多
Deceive 欺骗
5楼-- · 2019-01-13 06:54

The jQuery.path plugin is what you want:

Example: animate along an arc

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

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

Example: animate along a sine wave

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});
查看更多
ゆ 、 Hurt°
6楼-- · 2019-01-13 06:59

Are you using jQuery 1.4?

$(this).animate({
    left: [500, 'easeInSine'],
    top: 500
});

You'll require the easing plugin for this to work: http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js

E.g. http://jsbin.com/ofiye3/2

查看更多
登录 后发表回答