简体   繁体   English

自定义jQuery轻松功能可访问值

[英]Custom jQuery Easing Function With Access to Value

I looking up to make a custom easing function to jQuery animate, and I Found a great example to how extend the easing in jQuery. 我想为jQuery动画创建自定义缓动函数,并且找到了一个很好的示例来说明如何在jQuery中扩展缓动。 Check it out: Looking for jQuery easing functions without using a plugin . 检查一下: 寻找jQuery缓动函数而无需使用插件

But this approach does not fit my case. 但是这种方法不适合我的情况。
I have a function that need to process the value not only base in time but also base in start and and value. 我有一个函数,不仅需要根据时间来处理值,还需要根据start和and值来处理值。 Example: 例:

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

the approach that I found uses a function that receives 5 parameters, all of then related with time. 我发现的方法使用了一个接收5个参数的函数,所有这些参数都与时间相关。

But I need more thatn that. 但是我需要更多。 I also need the start value (the value that the DOM has before the animation) and the end value (the value that the DOM will be after the animation). 我还需要开始值(动画之前DOM的值)和结束值(动画之后DOM的值)。

In my example the value refers to height (original height and 1400px). 在我的示例中,该值是指高度(原始高度和1400px)。

I know that you're wondering why I need the value info, so I already wrote my custom function: 我知道您想知道为什么我需要值信息,所以我已经编写了自定义函数:

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
}

But my problem is how to incorporate this function to jQuery.animate() . 但是我的问题是如何将此函数合并到jQuery.animate() Anyone can help me? 有人可以帮助我吗?

These are my first keystrokes on SO, I have neither an account or profile nor any reputation, but I'm working on a jQuery plugin that will allow additional arguments for easing functions. 这是我的第一个SO击键,我没有帐户或个人资料,也没有任何声誉,但是我正在开发jQuery插件,该插件将允许使用其他参数来简化函数。

To answer your question I make following assumptions (if I'm wrong please tell me and I will update my answer): 1. You use jQuery >= 1.8 (they modified their animation routine there). 为了回答您的问题,我做出以下假设(如果我错了,请告诉我,我将更新答案):1.您使用jQuery> = 1.8(它们在那里修改了动画例程)。 2. Your $("selector") may contain more than one element. 2.您的$(“选择器”)可能包含多个元素。 3. The startValue of the animated property (here: "height") may differ from one element to another. 3.动画属性的startValue(此处为“ height”)在一个元素之间可能有所不同。 4. Whenever there's a way to incorporate your function, you won't insist on using a custom easing. 4.只要有一种方法可以合并您的功能,您就不会坚持使用自定义缓动。

I see two solutions. 我看到两个解决方案。 To explain what I do and why, here's a snippet from jQuery core: 为了解释我的工作和原因,这是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;
    }
};

Solution 1: You have done the modification of jQuery described above. 解决方案1:您已经完成了上述jQuery的修改。 Then: 然后:

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

Solution 2: You won't mess around inside jQuery. 解决方案2:您不会在jQuery中弄乱。 Then: 然后:

Instead of discrete arguments for duration, easing and complete you can pass an options object to .animate(). 您可以将选项对象传递给.animate(),而不是使用持续时间的离散参数来简化和完成。 For details see http://api.jquery.com/animate/ . 有关详细信息,请参见http://api.jquery.com/animate/ With specialEasing you can define the easing of each property separately. 使用specialEasing可以分别定义每个属性的缓动。 This way you keep all possibilities to animate other properties than "height" in the same call without affecting them with "myFunction". 这样,您可以在同一调用中保留除“高度”以外的其他所有属性的动画,而不会受到“ 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
            }
        }
    }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM