可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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/
回答2:
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});
回答3:
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
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;
};
回答4:
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
回答5:
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 ;)