[ACCEPTED]-jquery animation of specific attributes-graphael

Accepted answer
Score: 11

I'm working on project which uses svgs. While 4 I got the above to work, the animated value 3 went from 0 to where-ever even if it has 2 a value before the animation. So I used 1 this instead (initial value for cy is 150):

$('#navlet .li1').mouseenter(function(){
    $({cy:$('#nav_dot').attr('cy')})
    .animate(
    {cy: 60},
    {duration:200,step:function(now){$('#nav_dot').attr('cy', now);}});
});
Score: 10

You can definitely animate a property by 2 doing so

$("rect")
    .animate(
        { x: 100 },
        {
            duration: 1000,
            step: function(now) { $(this).attr("x", now); }
        });

You do not need to save that property 1 in CSS.

Score: 3

In fact, there is a way to animate a specific 1 attribute:

$("rect").each(function(){
   $(this).css("MyX",$(this).attr("x"))
   .animate({MyX:500},{step:function(v1){$(this).attr("x",v1)}})
})
Score: 2

I found a way to use the jQuery call without 12 running into the problem that the attribute 11 gets reset to 0 when the animation starts 10 like some other answers here

Lets say we 9 want to animate the width and height attribute of an 8 img tag element with id image. To animate it 7 from its current value to 300 we could do 6 this:

var animationDiv= $("<div></div>"); //we don't add this div to the DOM
var image= $("img#image");
//could use any property besides "top" and "left", but the value must be valid, that means concatenating a "px" to numerical attributes if they don't have it already (and removing them in the step callback if they do)
animationDiv.css("left", image.attr("width")); 
animationDiv.css("top", image.attr("height")); 
animationDiv.animate(
    {
        left: 300,
        top: 300
    },
    {
        duration: 2500,
        step: function(value, properties) {
            if (properties.prop == "left")
                 image.attr("width", value + "px")
            else
                 image.attr("height", value + "px")
        }
    }
)

In this approach we use a div that 5 is not inside the DOM and animate values 4 in it, we then use the div CSS values to 3 animate our element. Not very pretty but 2 gets the job done, if you need to stop the 1 animation you can call .stop() on animationDiv.

jsfiddle

Score: 0

I, like @rslm, was working on animating 7 an SVG and needed to modify the viewBox 6 property. This is my solution:

(note, I used 5 ES6 so you might have to rewrite or use 4 babel to make the code ES5 compatible)

let scrollTimeOut;

/**
 * Animate the viewBox property for the logo
 * @param {object} start
 * @param {object} finish
 */
let animateLogo = (start, finish) => {
    let svg = $('.logo-container svg');

    $(start).finish().animate(finish, {duration: 400, step: (newVal, item) => {
        let split = svg.attr('viewBox').split(' ');
        let width = split[2];
        let height = split[3];


        if (item.prop === 'vbw') {
            width = newVal;
        } else {
            height = newVal;
        }


        svg.attr({viewBox: `${split[0]} ${split[1]} ${width} ${height}`})
    }});
};

/**
 * Set the height of the header
 */
let setHeaderHeight = () => {
    let split = $('.logo-container svg').attr('viewBox').split(' ');
    let finish;
    let start = {vbw: +split[2], vbh: +split[3]};

    if (window.scrollY < 50) {
        finish = {vbw: 1000, vbh: 1000};
    } else {
        finish = {vbw: 1600, vbh: 300};
    }

    if (finish.vbw !== start.vbw && finish.vbh !== start.vbh) {
        // If there is something to animate
        animateLogo(start, finish)
    }
};

$(window).off('scroll.staggered').on('scroll.staggered', () => {
    // Only do something every 50ms
    window.clearTimeout(scrollTimeOut);

    scrollTimeOut = window.setTimeout(() => {
        setHeaderHeight();
    }, 50);
});

I 3 added the $(window).off('scroll.staggered').... section for completeness, but 2 you just need to change that to call setHeaderHeight() as 1 needed.

More Related questions