【问题标题】:How would you animate something so that it follows a curve?您将如何制作动画以使其遵循曲线?
【发布时间】:2010-02-10 20:20:14
【问题描述】:

如果我有
<div id="curve" style="position:relative; height:100px; width:100px; />

如何让它在曲线上移动?我已经搜索了所有内容,但似乎找不到另一个可以同时调用两个函数的示例。这是我想要的那种代码,但不起作用:

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

即使这不是正确的代码,我相信 animate 只会将“目的地”带到某事去,所以我认为动态目的地行不通。我在寻找什么来完成这项工作?

编辑:: 我肯定会选择那个插件,但我也想知道为什么这段代码不能像我期望的那样工作。

这是另一个使用 for 循环和延迟方法的尝试

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

除了它只是立即转到那个位置,没有延迟或任何东西。所以如果它从 [0,0] 开始,只要我点击它,它就会传送到 [400,600]。为什么延迟不起作用?

【问题讨论】:

  • 我认为jQuery中没有延迟功能,除非你使用延迟插件...
  • 确保您使用的是 v1.4+ 的 jQuery
  • 试试$(this).delay(1000).css( { top: i, left: i*1.5 } );
  • 好吧,我想它有效。所以不是让它成为一个循环,而是让它递归。 JS 中使用递归的频率如何?
  • 啊酷。所以它只是 +'px' 部分 =/。很高兴知道递归。感谢所有帮助和示例

标签: javascript jquery animation


【解决方案1】:

jQuery.path plugin 是你想要的:

示例:沿弧线制作动画

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

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

示例:沿正弦波制作动画

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});

【讨论】:

  • @philfreo,jquery.path 插件似乎不再工作。关于如何做到这一点的任何想法?
【解决方案2】:

我认为这一次,你必须在 js 中逐部分重新计算动画曲线,然后通过小部分移动来完成(= 你可能可以找到插件或者你必须自己做所有的数学运算)

编辑 2:之前添加的链接已移动=> http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/。谢谢,扎克。

编辑 1:这引起了我的兴趣,所以我做了一些谷歌研究 - 正如我所想的那样:插件可以在这里使用:http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/

【讨论】:

【解决方案3】:

这是我编写的一个简单的小库,它允许动画路径的任意三次贝塞尔曲线,甚至可以为您计算旋转角度。 (该库尚未完善或记录在案,但它表明即使您的页面中没有 SVG 元素,站在 SVG DOM 的肩膀上是多么容易。)

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

您可以编辑代码并观察曲线/动画的变化,也可以编辑曲线并查看代码更新。

如果我的网站出现故障,以下是相关代码:

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;
};

【讨论】:

  • 我很困惑:您的库能否用于沿 bezierCurveTo 定义的贝塞尔曲线制作动画,或者您是否需要 SVG 路径?
  • @Thomas 如上所示的CurveAnimator 构造函数需要四个点并为您创建一个简单的路径。但是,如果您将动画器的 .path 属性设置为具有任意路径(不必在页面上)的 SVG 路径,您就可以为所欲为。
【解决方案4】:

您使用的是 jQuery 1.4 吗?

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

您需要 easing 插件才能工作:http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js

例如http://jsbin.com/ofiye3/2

【讨论】:

    【解决方案5】:

    有一个小脚本,仅用于非直线动画,称为pathAnimator

    它非常小而且非常高效。你甚至不需要 jQuery ;)

    【讨论】:

      猜你喜欢
      • 2021-10-30
      • 1970-01-01
      • 2018-09-09
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      • 2013-01-17
      相关资源
      最近更新 更多