Как бы вы оживили что-то, чтобы оно повторяло кривую? - PullRequest
23 голосов
/ 10 февраля 2010

Если у меня есть
<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]. Почему не работает задержка?

Ответы [ 5 ]

16 голосов
/ 10 февраля 2010

Плагин jQuery.path - это то, что вы хотите:

Пример: анимация по дуге

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});
15 голосов
/ 10 февраля 2010

Я думаю, что в этот раз вы должны пересчитать анимированную кривую часть за частью в js, а затем сделать это, перемещаясь на маленькие части (= вы, вероятно, можете найти плагин, ИЛИ вам придется делать всю математику самостоятельно) 1001 *

Редактировать 2 : ранее добавленная ссылка была перемещена => http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/. Спасибо, Зак.

Редактировать 1 : это заинтриговало меня, поэтому я провел небольшое исследование Google - как я и думал: плагин готов к использованию здесь: http://foxparker.wordpress.com/2009/09/22/bezier-curves-and-arcs-in-jquery/

11 голосов
/ 12 декабря 2011

Вот простая небольшая библиотека, которую я написал, которая позволяет произвольные кубические кривые Безье для пути анимации и даже вычисляет угол поворота для вас. (Библиотека еще не отшлифована и не документирована, но показывает, как легко стоять на плечах DOM SVG, даже если на вашей странице нет элементов SVG.)

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

Screenshot of website

Вы можете либо отредактировать код и посмотреть изменение кривой / анимации, либо отредактировать кривую и увидеть обновление кода.

Если мой сайт не работает, вот соответствующий код для потомков:

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;
};
6 голосов
/ 11 февраля 2010

Вы используете jQuery 1.4?

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

Для этого вам потребуется плагин замедления: http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js

например. http://jsbin.com/ofiye3/2

1 голос
/ 24 апреля 2013

Есть крошечный скрипт, предназначенный только для анимации, который не имеет прямой линии, и называется pathAnimator

Это очень очень маленький и очень эффективный. и вам даже не нужен jQuery;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...