2013-06-28 43 views
10

ASAIK jquery動畫函數只接受樣式屬性。但我想動畫元素的屬性。考慮SVG元素矩形jquery動畫爲元素屬性不風格

<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函數中執行此操作。

這是可能的嗎?

感謝,

溼婆

+1

是x和y的元素的位置? – caramba

+0

@caramba yes.it是矩形元素的位置 – SivaRajini

+1

[jquery動畫的特定屬性]的可能重複(http://stackoverflow.com/questions/6670718/jquery-animation-of-specific-attributes) –

回答

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); 
+1

謝謝。如果使用left和top意味着元素中仍然存在x和y屬性。那麼元素需要什麼位置? – SivaRajini

6

只是動畫的老式方法:

你可以打電話animate像jquery一樣的時尚。

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

你能否詳細解釋一下。什麼是步驟,速度和超時功能?這裏的東西是什麼?你可以請更具體 – SivaRajini

+0

@ ram只是改變了代碼 –

+1

獎金:瘋狂的動畫http://jsfiddle.net/EpMVN/4/ –

-1

這或許適合你簡單

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

據我所知,「頂」和「左」將是CSS的屬性。這個問題明確指出「元素屬性不是風格」。如果我錯了,我會刪除倒票 –

1

好吧,這裏所有的答案或者是特別針對SVG或重新實現.animate()jQuery的電話,我發現了一種使用jQuery調用時不會遇到動畫啓動時屬性被重置爲0的問題:

假設我們想要動畫widthheight img標籤元素的屬性,其ID爲image。爲了從當前值動畫播放到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") 
     } 
    } 
) 

在這種方法中,我們使用一個div是不是DOM內部和其動畫的價值觀,我們再使用DIV + CSS值動畫我們元件。不是很漂亮,但完成工作,如果你需要停止動畫,你可以在animationDiv上調用.stop()

jsfiddle

+2

如果投票結束這個問題作爲您剛剛回答這個問題的其他問題的重複,那不是更好嗎? –

0

我喜歡霍夫曼的做法,但我認爲是沒有創建虛擬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'); 
    } 
    }); 
});