gpt4 book ai didi

javascript - 具有访问值的自定义 jQuery 缓动函数

转载 作者:行者123 更新时间:2023-11-28 03:26:56 31 4
gpt4 key购买 nike

我希望为 jQuery 动画制作一个自定义缓动函数,我找到了一个很好的例子来说明如何在 jQuery 中扩展缓动。查看:Looking for jQuery easing functions without using a plugin .

但是这种方法不适合我。
我有一个函数,不仅需要处理基于时间的值,还需要处理基于开始和值的值。示例:

$("selector").animate({ "height": "1400px" }, 1000);

我发现的方法使用一个函数接收 5 个参数,然后所有参数都与时间相关。

但我还需要更多。我还需要起始值(DOM 在动画之前的值)和结束值(DOM 在动画之后的值)。

在我的示例中,该值指的是高度(原始高度和 1400 像素)。

我知道您想知道为什么我需要值信息,所以我已经编写了自定义函数:

var offset = 400;

function myEasing(millisecondsSince, totalMilliseconds, startValue, endValue) {
var t = millisecondsSince / totalMilliseconds;

if (startValue == 0) startValue = 0.000001;

if (t <= 0.5) {
var m = (Math.log(endValue - offset) - Math.log(startValue))
/ (0.5 * Math.LN10);
var n = Math.log(startValue) / Math.LN10;
return Math.pow(10, m * t + n); // y = 10 ^ (mx + n)
}

var m = 2 * Math.pow(offset, 0.2);
return Math.pow(m * t - m, 5) + endValue; // y = (mx - m) ^ 5 + endValue
}

但我的问题是如何将此函数合并到 jQuery.animate() 中。谁能帮帮我?

最佳答案

这是我在 SO 上的第一次击键,我既没有帐户也没有个人资料,也没有任何声誉,但我正在开发一个 jQuery 插件,它允许为缓动函数添加额外的参数。

为了回答您的问题,我做了以下假设(如果我错了请告诉我,我会更新我的答案):1. 你使用 jQuery >= 1.8(他们在那里修改了他们的动画例程)。2. 你的 $("selector") 可能包含多个元素。3. 动画属性的 startValue(此处为“高度”)可能因元素而异。4. 只要有办法合并您的函数,您就不会坚持使用自定义缓动。

我看到了两个解决方案。为了解释我所做的事情和原因,这里是 jQuery 核心的一个片段:

// jQuery creates for each animated property of each animated element a Tween object.
// .run() of its prototype is called at each step of the animation.
Tween.prototype = {
run: function( percent ) {
// percent = actual state of the animation, a number between 0 (start) and 1 (end)
// percent is identic with your var t, you dont need to recalculate it
// this refers to the whole Tween object you are actual in
var eased,
hooks = Tween.propHooks[ this.prop ];

if ( this.options.duration ) {
// here the choosen easing function is called. It must be declared in $.easing under its name
// before animation is running, otherwise an error is thrown. But before starting you don't know
// the startValue, so your function can't reference to it
this.pos = eased = jQuery.easing[ this.easing ](
// here the five arguments are passed in. Every easing function in $.easing, even custom ones,
// have this signature (x, t, b, c, d), they may use the arguments or not. Changing this signature
// breaks any other code that relies on easings
percent, this.options.duration * percent, 0, 1, this.options.duration
// But being shameless, you may extend the signature with the additional arguments you need
/* percent, this.options.duration * percent, 0, 1, this.options.duration, this.start, this.end */
// now there are seven arguments and you can restructure your function to use the three you need
);
} else {
this.pos = eased = percent;
} // at this point the easing result is stored in this.pos. When using 'linear' its identic with percent
// (and with your var t) so we can use this.pos in the second solution

// after calculation this.now holds the actual value of the animated property. When you havn't done
// the modification above, you can't use your function for easing and this.now hasn't the value you want
this.now = ( this.end - this.start ) * eased + this.start;

if ( this.options.step ) {
// if you have defined a function in options.step it gets called now. Two arguments are passed in:
// the actual value, the whole Tween object. The latter holds all values you need
// to recalculate this.now with your function
this.options.step.call( this.elem, this.now, this );
}

if ( hooks && hooks.set ) {
hooks.set( this );
} else {
Tween.propHooks._default.set( this );
}
return this;
}
};

解决方案1:您已经完成上述jQuery 的修改。然后:

var offset = 400;
$.easing["myFunction"] = function(x, t, b, c, d, startValue, endValue) {
/* replace your var t with x; args t b c d not needed; your done; */
};
$("selector").animate({ "height": "1400px" }, 1000, "myFunction");

解决方案 2:您不会在 jQuery 中乱搞。然后:

您可以将选项对象传递给 .animate(),而不是持续时间、缓动和完成的离散参数。详情见http://api.jquery.com/animate/ .使用 specialEasing,您可以分别定义每个属性的缓动。这样你就保留了所有的可能性在同一个调用中为除“height”之外的其他属性设置动画,而不用“myFunction”影响它们。

$("selector").animate(
{ height: "1400px" , otherProp: "otherVal"}, {
duration: 1000, // your duration
specialEasing: {
height: "linear" // easing happens before step, linear won't confuse your calculations
otherProp: "anyEasingYouWant"
},
step: function(now, tween) {
// you are restricted to the two arguments jQuery passes to this function. But the Tween object
// holds all values you need to modify tween.now (= the animation output value) as you like
// if you animate more than one property and want apply your calcs only to one, do exclusions here.
// it's needed cause this function is executed once for each property of each element at each step.
if (tween.prop !== "height") return;
var ofs = 400, // your offset
stv = tween.start || 0.000001, // your startValue
env = tween.end, // your endValue
dif = env - stv, // difference between start and end to recalculate the actual value
pos = tween.pos, // your var t
m, n;
if (pos <= 0.5) {
m = (Math.log(env - ofs) - Math.log(stv)) / (0.5 * Math.LN10);
n = Math.log(stv) / Math.LN10;
tween.now = dif * Math.pow(10, m * pos + n) + stv; // y = 10 ^ (mx + n)
} else {
m = 2 * Math.pow(offset, 0.2);
tween.now = dif * (Math.pow(m * pos - m, 5) + env) + stv; // y = (mx - m) ^ 5 + endValue
}
}
}
);

关于javascript - 具有访问值的自定义 jQuery 缓动函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20638964/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com