jquery动画元素属性而不是样式

时间:2013-06-28 08:47:03

标签: jquery svg jquery-animate jquery-svg

ASAIK jquery animate函数仅接受样式属性。但我想动画一个元素的属性。考虑一个SVG元素矩形

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

我想为矩形元素属性“x”和“y”设置动画,如下面的

$("#rect1").animate({
    x: 30,
    y: 40
  }, 1500 );

但这种方法不正确,因为动画功能会影响元素的样式而不是属性。

我知道很多自定义插件就像 raphel.js

http://raphaeljs.com/

但我不想使用自定义插件来执行此操作。我想在jquery.animate函数中完成这个。

这可能吗?

谢谢,

希瓦

5 个答案:

答案 0 :(得分:6)

只是用老式的方式制作动画:

你可以像jquery一样调用animate

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

答案 1 :(得分:1)

我会尝试这样的事情

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

var myElemX = $('.myElement').attr('x');
var myElemY = $('.myElement').attr('y');
$("#rect1").animate({
    left: myElemX+'px',
    top:  myElemY+'px'
}, 1500 );

答案 2 :(得分:1)

好的,这里的所有答案都是特定于SVG或重新实现.animate()jQuery调用,我发现了一种使用jQuery调用的方法,而没有遇到动画启动时属性重置为0的问题:

假设我们想要为ID为width的img标记元素的heightimage属性设置动画。要将它从当前值设置为300,我们可以这样做:

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

在这种方法中,我们使用不在DOM内部的div并在其中设置动画值,然后我们使用div CSS值来​​动画我们的元素。不是很漂亮,但完成工作,如果你需要停止动画,你可以在animationDiv上调用.stop()

jsfiddle

答案 3 :(得分:0)

我喜欢Hoffmann的方法,但我认为在没有创建虚拟dom对象的情况下会更优雅。

这是我的coffeescript片段

$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'

编译成

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');
    }
  });
});

答案 4 :(得分:-1)

这可能适合你简单

$("your div id").css("position", "absolute").animate({
    left: 159,
    top:  430
});