Can this be done ? Basically I want to animate an absolute-positioned image with right:xxxPX, let's say. Well, when the animation is in progress, can I add a "trail" effect to it?
Thanks,
Adrian
This should work:
var box = $('#box'),
// Create some clones (these make up the trail)
clones = $.map(Array(10), function(item, i){
return box.clone().css('opacity', 1 / (i + 1)).hide().insertAfter(box);
});
box.animate({
top: 100,
left: 200
}, {
duration: 1000,
step: function(now, fx) {
// On each step, set a timeout for each clone,
// making it move to the required position.
var prop = fx.prop;
$.each(clones, function(i, clone){
clone = $(clone).show();
setTimeout(function(){
clone.css(prop, now);
}, 50 * i);
});
}
});
Demo: http://jsbin.com/ifobe3
Related
I saw this codepen: https://codepen.io/alex_rodrigues/pen/ogYZdr You can see the javascipt code here:
setTimeout(function start (){
$('.bar').each(function(i){
var $bar = $(this);
$(this).append('<span class="count"></span>')
setTimeout(function(){
$bar.css('width', $bar.attr('data-percent'));
}, i*100);
});
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).parent('.bar').attr('data-percent')
}, {
duration: 2000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now) +'%');
}
});
});
}, 500)
I want the graph to complete the animation, stall for 3-5 seconds then repeat the animation. Currently, it completes the animation, but there is no loop. Any help is much appreciated. Thank you!
You can create a function that:
Resets the bar's width and content
Restarts the animation.
This function can be set to be called after:
($('.bar').length - 1) * 100 + 2000 + your_chosen_delay_in_ms
For this to work, we have to pull out all the things that don't need repeating, like $(this).append('<span class="count"></span>').
Combined, it would look like this:
var animation_offset = 100;
var animation_duration = 2000;
var reanimate_delay = 3000;
function animateBars() {
$('.bar').each(function(i){
var $bar = $(this);
setTimeout(function(){
$bar.css('width', $bar.attr('data-percent'));
}, i*animation_offset);
});
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).parent('.bar').attr('data-percent')
}, {
duration: animation_duration,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now) +'%');
}
});
});
setTimeout(
reAnimateBars,
(
($('.bar').length - 1) * animation_offset // Moment the last bar starts animating
+ animation_duration // Animation duration
+ reanimate_delay // Your chosen delay
)
);
}
function reAnimateBars() {
// Reset the bars
$('.bar .count').text('');
$('.bar').css('width', '0%');
// This will take some time (as per CSS transition property) to reset.
// So we have to wait for that too.
// Start the animation (again)
// after CSS transition time for resetting is over
setTimeout(animateBars, animation_duration);
}
setTimeout(function() {
// Put non-repeating things here:
$('.bar').append('<span class="count"></span>');
// Start animation (first time)
animateBars();
}, 500);
I am animating these dotted lines (SVG) for a project using velocity.js.
However, after a few loops, the animation starts to lag a lot.
I have pasted the link to my animation in the codepen below.
http://codepen.io/aofaoin/pen/pbLvAb?editors=0110
for (i = 1; i <= 69; i++) {
$("#gold2 .cls-" + i)
.velocity("fadeOut", {
delay: g2,
duration: 800,
})
.velocity("fadeIn", {
delay: 15,
duration: 800,
})
g2 += 80;
}
I can't use loop:true as i want to orchestrate/choreography the animation.
It would be great if anyone can tell me how can I stop the animation from lagging after a few loops. Thank you!
Looking at your code, I suggest wrapping your velocity manipulation inside of setTimeout(function() { ... }, 0). This will prevent browser from freezes caused by a big number of sync operations you try to do.
for (i = 1; i <= 69; i++) {
setTimeout(function() {
$("#gold2 .cls-" + i)
.velocity("fadeOut", {
delay: g2,
duration: 800,
})
.velocity("fadeIn", {
delay: 15,
duration: 800,
});
g2 += 80;
}, 0);
}
If you need to do your animation with delay, add dedicated delay in setTimeout.
I have multiple images and want to rotate images in 3d and 2d one by one display.
HTML is like
<div><img src="1.jpg"></div>
<div><img src="2.jpg"></div>
<div><img src="3.jpg"></div>
etc
So I want to display image by previous image flip out and next flip in.
I have tried below code
To hide:
$hide.animate({
transform: 'rotate(180deg)',
opacity: 0.1
},
1500,
'easeInOutBack',
function () {
$(this).hide();
});
To Show:
$show.show().animate({ transform: 'rotate(180deg)', opacity: 1.0 },1500,'easeInOutBack');
But it is not working. I am using jquery and jquery ui only.
you don't animate rotation with jQuery, let CSS do that for you.
try this:
js:
$hide.addClass('hide').removeClass('show');
$show.removeClass('hide').addClass('show');
css:
.show, .hide{transition:all 0.3s ease;}
.hide{opacity:0.1;transform:rotate(0deg);}
.show{opacity:1;transform:rotate(1800deg);}
hope that helps.
EDIT:
if you still wish to use jQuery and not CSS, i'd suggest a plugin such as http://nnattawat.github.io/flip/
EDIT2:
if you still don't want the CSS approach, and not a jQuery plugin, i suggest you take a look here:
CSS rotation cross browser with jquery.animate()
"CSS-Transforms are not possible to animate with jQuery, yet. You can
do something like this [code sample]"
i also created a fiddle to demonstrate this approach: http://jsfiddle.net/jhcvb2ty/
Basic animates can't animate non-numeric CSS properties.
so use step function in animate then it works.
See example: http://jsfiddle.net/kevalbhatt18/epp06LL3/2/
$('#box').animate({ transformValue: -180 }, {
step: function(now,fx) {
$(this).css('transform','rotatex('+now+'deg)');
},
duration:'slow'
},'linear');
EDIT:
See example: http://jsfiddle.net/kevalbhatt18/u2ptr4jp/4/
Now simply add div inside parent span it will work for all.
Note: only first class you should know i.e in this example we have
box class so if we are at last box then it will flip to first box
$("div").click(function() {
var that = this;
$(this).animate({
transformValue: -180
}, {
step: function(now, fx) {
$(this).css('transform', 'rotatey(' + now + 'deg)');
},
complete: function() {
$(that).hide();
//$('#box').removeAttr( 'style' );
var nextObject = $(that).next()
var nextClass = nextObject.attr('class')
console.log($('#parent').children().hasClass(nextClass));
if ($('#parent').children().hasClass(nextClass)) {
var flipNext = nextClass;
console.log("true")
} else {
console.log("false")
var flipNext = "box";
console.log(flipNext);
}
secondFlip(flipNext, that);
},
duration: 'slow'
}, 'linear');
});
function secondFlip(nextID, that) {
$('.' + nextID).show();
$('.' + nextID).animate({
transformValue: 180
}, {
step: function(now, fx) {
$(this).css('transform', 'rotatex(' + now + 'deg)');
},
complete: function() {
},
duration: 'slow'
}, 'linear');
}
Edit: rotation issue solved
see this example: http://jsfiddle.net/kevalbhatt18/u2ptr4jp/6/
Final Output:
After so many tray I found solution.
see this example:http://jsfiddle.net/kevalbhatt18/oh07zuh0/
hear i find transformation degree.
(function ($) {
$.fn.rotationDegrees = function () {
var matrix = this.css("-webkit-transform") || this.css("-moz-transform") || this.css("-ms-transform") || this.css("-o-transform") || this.css("transform");
if (typeof matrix === 'string' && matrix !== 'none') {
var values = matrix.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
} else {
var angle = 0;
}
return angle;
};
}(jQuery));
I am making a game, where a few products are flying one after another from right to left. The whole time they should also be draggable and be dropped to a certain position. But while dragged, they should not be animated, of course.
The code I have so far, animates the element, while dragging:
var animateElement = function(currentIndex) {
var endpoint = 20000;
$('.product-' + currentIndex.toString()).draggable();
$('.product-' + currentIndex.toString()).transition({
x: -600,
y: 100,
}, endpoint, "linear",
function() {
stopAnimation(currentIndex);
}
); //END ANIMATION
$('#dropProducthere').droppable({
accept: '.product-' + currentIndex.toString()
}); //END droppable
}
var stopAnimation = function(currentIndex) {
$('.product-' + currentIndex.toString()).stop().transition();
}
Is there a better solution than my one above?
I'm developing an accordion plugin, and it's mostly done except for one bug where for the first few steps of the slideUp/slideDown, the accordion is 1px taller than it's meant to be, causing a visual bug. I've narrowed it down to the fact that the first step in the slideUp animation doesn't do anything, and I can't figure out why. Here's an example:
console.log('Start');
var diff = 0;
var upNow = 100;
var downNow = 0;
$.fx.interval = 1000;
var duration = $.fx.interval * 100;
$("#div1").slideUp({
easing: 'linear',
duration: duration,
step: function(now) {
if (now != 0 && now > 90) {
console.log("Slide Up: " + now);
upNow = now;
}
}
});
$("#div2").slideDown({
easing: 'linear',
duration: duration,
step: function(now) {
if (now != 0 && now < 10) {
downNow = now;
diff = 100 - (upNow + downNow);
console.log("Slide Down: " + now);
console.log("Slide Difference:" + diff);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style='height: 100px; background-color: red;' id='div1'>
</div>
<div style='height: 100px; background-color: blue; display: none;' id='div2'>
</div>
http://jsfiddle.net/hbh6U/
The problem is that I need these to be in sync, and I can't figure out why they're not, or how to get them in sync. One idea I've had is to skip the first step of the slideDown animation, but I'm not sure how to do that either. Has anyone got any ideas, or faced this bug before?
The problem comes down to this line in jQuery's internal defaultPrefilter method:
tween.start = prop === "width" || prop === "height" ? 1 : 0;
This causes the animation for the second div (from 1px to 100px) to be shorter than that of the first div (from 0 to 100px).
To solve this modify your step function like this:
function linearStep(now, animation){
var animationStart = animation.start;
if (animationStart === 1){
animationStart = 0;
}
animation.now = (animation.end - animationStart ) * animation.pos + animationStart;
}
It overwrites the calculated now value by doing the same calculation with a fixed animationStart, which is 0 instead of 1.
This will break if the animation actually starts at 1, but there'd be other ways to handle it then.
Side-by-side Fiddle: http://jsfiddle.net/Nd3w2/3/
i don't exactly know where is this issue coming from... Sunday morning... not too much time to investigate... But i found two possible solution based on your fiddle...
First one was to wrap these two DIVs in another DIV with overflow:hidden.
Second one... probably more appropriate is to call "slide" function only on one of the divs and then update the size of second one in callback, something like that:
console.log('Start');
var diff = 0;
var upNow = 100;
var downNow = 0;
$.fx.interval = 1000;
var duration = $.fx.interval * 100;
$("#div1").slideUp({ easing: 'linear', duration: duration, step: function(now)
{
if(now != 0 && now > 90)
{
console.log("Slide Up: " + now);
upNow = now;
}
$("#div2").height(100- $("#div1").height());
}});
Also remove "disply:none" form div2 styles...
It fixes the issue and is a bit more elegant solution in my opinion... Calling two separate animation functions can lead to possible sync problems... Hope that helps...