jquery animate for element attributes not style

前端 未结 5 498
心在旅途
心在旅途 2021-01-11 18:40

ASAIK jquery animate function accepts style properties only. but i want to animate the attributes of an element. consider a SVG element rectangle

         


        
相关标签:
5条回答
  • 2021-01-11 18:49

    I like the Hoffmann approach, but i think is more elegant without creating a virtual dom object.

    This is my coffeescript snippet

    $rects.each ->
      that = @
      $({width: 0}).animate
      width: parseInt($(@).attr('width'))
      ,
      duration: 2000
      easing: 'easeIn'
      step: ->
        $(that).attr 'width', Math.round(@.width)
      done: ->
        console.log 'Done'
    

    which compiles into

    return $rects.each(function() {
      var that;
      that = this;
      return $({
        width: 0
      }).animate({
        width: parseInt($(this).attr('width'))
      }, {
        duration: 1000,
        easing: 'easeIn',
        step: function() {
          return $(that).attr('width', Math.round(this.width));
        },
        done: function() {
          return console.log('Done');
        }
      });
    });
    
    0 讨论(0)
  • 2021-01-11 18:54

    I would try something like this

    <svg>
        <rect class="myElement" id="rect1" x="10" y="20" width="100px" height="100px">
    </svg>
    

    in the script :

    var myElemX = $('.myElement').attr('x');
    var myElemY = $('.myElement').attr('y');
    $("#rect1").animate({
        left: myElemX+'px',
        top:  myElemY+'px'
    }, 1500 );
    
    0 讨论(0)
  • 2021-01-11 18:57

    Alright all answers here are either specific to SVG or reimplement the .animate() jQuery call, 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:

    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

    0 讨论(0)
  • 2021-01-11 19:03

    just animate the old fashioned way:

    you can call animate in a jquery like fashion.

    http://jsfiddle.net/wVv9P/7/

    function animate($el, attrs, speed) {
    
        // duration in ms
        speed = speed || 400;
    
        var start = {}, // object to store initial state of attributes
            timeout = 20, // interval between rendering loop in ms
            steps = Math.floor(speed/timeout), // number of cycles required
            cycles = steps; // counter for cycles left
    
        // populate the object with the initial state
        $.each(attrs, function(k,v) {
            start[k] = $el.attr(k);
        });
    
        (function loop() {
            $.each(attrs, function(k,v) {  // cycle each attribute
                var pst = (v - start[k])/steps;  // how much to add at each step
                $el.attr(k, function(i, old) {
                    return +old + pst;  // add value do the old one
                });
            });
    
            if (--cycles) // call the loop if counter is not exhausted
                setTimeout(loop, timeout);
            else // otherwise set final state to avoid floating point values
                $el.attr(attrs);
    
        })(); // start the loop
    }
    
    $('button').on('click', function() {       
        animate(
            $('#rect1'), // target jQuery element
            { x:100, y:300, width:50, height:100 }, // target attributes
            2000 // optional duration in ms, defaults to 400
        );
    });
    
    0 讨论(0)
  • 2021-01-11 19:13

    this may fits you simple

    $("your div id").css("position", "absolute").animate({
        left: 159,
        top:  430
    });
    
    0 讨论(0)
提交回复
热议问题