JQuery анимировать для атрибутов элемента не стиль
Функция jaquery animate ASAIK принимает только свойства стиля. но я хочу оживить атрибуты элемента. рассмотрим прямоугольник элемента SVG
<svg>
<rect id="rect1" x=10 y=20 width="100px" height="100px">
</svg>
я хочу, чтобы анимировать атрибут элемента прямоугольника "х" и "у" что-то вроде ниже
$("#rect1").animate({
x: 30,
y: 40
}, 1500 );
но это не правильный путь, потому что функция animate влияет на стиль, а не на атрибут элемента.
Я знал, что существует много пользовательских плагинов, таких как Raphel.js.
но я не хочу использовать пользовательский плагин, чтобы сделать это. Я хочу сделать это просто в функции jquery.animate.
Это возможно?
Спасибо,
Сива
5 ответов
Просто оживи по старинке:
ты можешь позвонить animate
в моде.
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
);
});
Я бы попробовал что то подобное
<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 );
Хорошо, что все ответы здесь относятся либо к SVG, либо к повторной реализации вызова.animate() jQuery, я нашел способ использовать вызов jQuery, не сталкиваясь с проблемой, что атрибут сбрасывается в 0 при запуске анимации:
Допустим, мы хотим оживить width
а также height
атрибут элемента тега img с идентификатором 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, и анимируем значения в нем, затем мы используем CSS-значения div для анимации нашего элемента. Не очень красиво, но выполняет свою работу, если вам нужно остановить анимацию, вы можете позвонить .stop()
на animationDiv.
Мне нравится подход Хоффмана, но я думаю, что он более элегантен без создания виртуального объекта dom.
Это мой фрагмент кода
$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');
}
});
});
Это может подходит вам просто
$("your div id").css("position", "absolute").animate({
left: 159,
top: 430
});