开发者

jquery animation of specific attributes

So I'm using gRaphael to create some charts. This is creating a cool bar chart line with some dots in it. Those dots have the ... nodes with x=10 y=20 as their attributes. Example

rect x="135.8" y="115.8" width="8.399999999999999" height="8.399999999999999" r="0" rx="0" ry="0" fill="#ff0000" stroke="none"

I want to use jquery to animate this guy if possible. The thing is if I do

$("rect").click(function({
 $(this).animate({
   'x':30
 });
});

In order to animate the x coordenate it doesn't开发者_StackOverflow社区 work for obvious reasons I guess?? hehe. Also I've tried setting the attribute x to a variable and trying to animate that and nothing. Can any one help me with animation and svg with gRaphael?

This for instance works

$("rect").live('click',function(){  $(this).attr('x',100);});
it moves the node but ofcourse doesn't animate it

Thanks!


I'm working on project which uses svgs. While I got the above to work, the animated value went from 0 to where-ever even if it has a value before the animation. So I used 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);}});
});


You can definitely animate a property by doing so

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

You do not need to save that property in CSS.


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

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


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

Lets say we want to animate the width and height attribute of an img tag element with id image. To animate it from its current value to 300 we could do 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 is not inside the DOM and animate values in it, we then use the div CSS values to animate our element. Not very pretty but gets the job done, if you need to stop the animation you can call .stop() on animationDiv.

jsfiddle


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

(note, I used ES6 so you might have to rewrite or use 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 added the $(window).off('scroll.staggered').... section for completeness, but you just need to change that to call setHeaderHeight() as needed.


You can only animate valid CSS properties that have a numeric value. Colors can be animated via some plugins. Since 'x' is not a valid CSS property, you won't be able to animate it using jQuery's built in .anmiate() function.

I think you'd have to pretty much write your own animation function to increment the value of x each passthrough of a timeout.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜