I'm experimenting with anime.js to move around elements and animate CSS properties. I have found that when animating certain properties, such as left or top, anime.js overwrites or skips over to the last animation of this property.
For example, here is some code that I've been working on where I've seen this happening:
<style>
div {
position: absolute;
width: 50px;
height: 50px;
background-color: black;
}
#square {
left: 100px;
top: 50px;
}
</style>
<div id="square"></div>
<script>
anime({
targets: '#square',
left: 300,
delay: 2000
});
anime({
targets: '#square',
left: 700,
delay: 4000
});
</script>
Instead of moving the square to the 300px position at 2 seconds, and then 700px position at 4 seconds, all I see is the square being moved to 700px after 4 seconds. It seems like the first 300px bit is entirely ignored. Why does this occur, and is there any workaround to this? Or should I structure the animation code differently to make sure this doesn't happen? Any help would be greatly appreciated.
After some experimentation, I found that the solution is somewhere in the anime.js documentation. I needed to use keyframes like so:
anime({
targets: '#square',
left: [
{value: 300, delay: 2000},
{value: 700, delay: 2000}
]
});
This ensures that one animation is not ignored, allowing the shape to be moved first to the 300px position and then to the 700px position, at 2s and 4s respectively.
Related
I'm pretty new to this, but I've been fiddling around trying to get an image to shrink to nothing on a central point, which works fairly well using a combination of the below code and relative positioning in the CSS.
$(function() {
$('#imageID').on('click', function() {
$(this).animate({
width: 0,
height: 0,
top: '185px',
left: '-2px'
}, 200);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
What I'd like to be able to do, however, is to change this so that the image shrinks centred on the point where the click was made. I've had a go at trying out absolute positioning and trying to set the top / left to the values of pageX and pageY (and also with the extra step of assigning them to variables) but no dice.
Does anyone have any idea of how / if this can be done? Thanks.
First of all welcome to Stack Overflow!
How about using CSS animations for this?
Use transform instead of width and height in animations for a better performance.
CODE SNIPPET:
$(function() {
$('#imageID').on('click', function() {
$(this).addClass("shrink");
});
});
.shrink {
animation: shrink 300ms linear forwards;
}
#keyframes shrink {
to {
transform: scale(0);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="imageID" src="http://fillmurray.com/300/300">
Here's more info on CSS transform and animation properties.
$(function() {
$('#imageID').on('click', function() {
$(this).animate({
width: 0,
height: 0,
top: '185px',
left: '-2px'
}, 200);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This is my jfiddle
And this is my actual code
$card.animate({
left: "1000px"
}, 500, function(){
$card.hide(500);
});
(I dont know why 'left' didnt work on jfiddle) Basically ive got a container with 5 $cards there. When user swipes the card (already implemented) the animate() is triggered and the card slides to the rightand then disappears. How can I implement such thing in CSS animations instead of using Jquery? Ive read that CSS animations run faster (and I proved it on my mobile device, the hide() runs really slow)... Any help or advice will be appreciated
First of all, create a class that you can trigger via jQuery that will have the animation.
Then, using you have two options: transition or animation. Transitions are simpler and more direct, but you can do more with animations.
Here is how I would suggest to do it: a transition for the movement, and an animation to recreate the hide() function.
#keyframes hide {
99% { display: auto; }
100%{ display: none; opacity: 0; }
}
.myelement {
transition: all .5s;
position: absolute;
left: 0;
}
.myelement.toLeft {
left: 2000px;
animation: hide .5s 1 forwards;
}
To trigger it, simply do this:
$(".myelement").addClass("toLeft");
Here is a working JSFiddle.
And like #MohitBhardwaj said, it is necessary for you to set position to absolute, relative, or static in order for positioning (i.e., the left property) to work.
It's also important to note that a transition needs an initial value. I added left: 0 to do this. Otherwise, (with a CSS transition) it would simply jump to 2000px because there is no starting point.
Also, because 2000px as a left value is very large, I suggest you change the parent element's scroll to overflow: hidden, so that the extraneous scroll bar doesn't appear.
Your left didn't work, because you need to set position to a value other than static (which is default) for it to work.
As for using CSS, you can add a class instead of animating in jQuery. This class can change the transition which you can set in css as per your requirements.
var my_div = $('.myelement');
my_div.on('click', function() {
var $this = $(this);
$this.addClass("gone");
setTimeout(function(){
$this.hide();
}, 600 );
})
#mywrapper
{
overflow: hidden;
}
.myelement {
height: 200px;
width: 200px;
background-color: red;
opacity: 1;
position: relative;
transition: all 0.5s ease;
opacity: 1;
left: 0px;
}
.myelement.gone
{
left: 500px;
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="mywrapper">
<div class="myelement">
Click me please
</div>
</div>
I am trying to animate a div to the right of the window using Jquery. I am also using Jquery UI to change the color of the div. I am animating the div all over the window as well. I am just experimenting with jquery animations though, nothing critical. Any ways this is the code I have so far:
HTML:
<div id="box1"></div>
<button type="button" id="btn"> Click Me! </button>
CSS:
#box1{
width: 200px;
height: 200px;
background-color: red;
border: 0px solid black;
border-radius: 0px;
position: relative;
}
#btn{
position: fixed;
top: 600px;
display: table-cell;
font-size: 30px;
}
JQuery:
var allow = true;
var animating = false;
$("#btn").click(function(){
if(allow == true){
if(!animating){
animating = true;
$("#btn").hide();
$("#box1").animate({backgroundColor: "yellow", borderWidth: "5px"}, 1000, "linear").animate({left: "500px"}, 1000).animate({top: "500px"}, 1000);
$("#box1").animate({left: "1000px", top: "0px"}, 1000).animate({left: "500px"}, 1000).animate({top: "500px"}, 1000, function(){
allow = false;
animating = false;
$("#btn").show().text("Click Me Aagain!");
});
}
} else {
if(!animating){
$("#btn").hide();
animating = true;
$("#box1").animate({top: 0}, 1000).animate({left: 0}, 1500).animate({backgroundColor: "red", borderRadius: 0, borderWidth: 0, width: "100px", height: "100px"}, 1000, function(){
$("#btn").show().text("Start Over!");
});
animating = false;
allow = true;
}
}
});
The first variable at the top is to toggle between two different animation sequences. The next is to ensure that the animations are not triggered twice by mistake. The element I am trying to move all the way to the right is #box1 and I want it to do so at the end of the first sequence!
Thanks for your help!
There are 2 options you can do to get the box to animate to the right edge of the area.
1) You could set the css "left: auto", and animate the css "right:0". To do this you would need to take some extra steps. You would need to set css "position: absolute" to the box and would need to wrap the box in a div that has the css "position: relative" with a width of 100%. That way, the box knows where the right edge because its most immediate parent that has css "position:relative" is setting the boundary. Doing this option would require a little fine tuning because switching between animating the left position and the right position will cause some jumping.
2) This option you could continue animating the left position, but to get it to animate to the right, you would need jquery to calculate how wide the page is, and subtract the with width of the box. It would look like this:
left: ($(document).outerWidth() - $('#box1').outerWidth())
I am using jquery to slide images left inside a div set to hide overflows, and then remove the first image and append it to the end, so that I always have the same number of images in the list and they keep sliding left each time the function fires:
function xxx(){
var first = $('.ximg:first');
$('.ximg').animate({ left: '-=200'}, 2000, function(){ $('.ximg').css({left: '0'}); first.insertAfter($('.ximg:last'));});
}
setInterval(function(){ xxx () }, 8000);
<div style="position:relative; overflow:hidden; width: 400px; height: 150px;">
<div class="ximg" style="position: relative; width: 200px; min-height:150px; background:red"></div>
<div class="ximg" style="position: relative; width: 200px; min-height:150px; background:orange"></div>
<div class="ximg" style="position: relative; width: 200px; min-height:150px; background:green"></div>
<div class="ximg" style="position: relative; width: 200px; min-height:150px; background:yelow"></div>
</div>
But I only end up with 1 image in the container, the second only gets added when the function fires. I know there are read made plugins to do this kind of thing but I want it simple and prefer to try and write my own even thought I am relatively new with jquery !
http://jsfiddle.net/rgct2/6/
The container is 400 wide and as each div is 200 wide, there should always be 2 divs in view, even during animation when it will show a % of the first and 3rd divs.
A better way is probably to animate the width of the first element, so it doesn't require all elements to be animated.
function xxx() {
var origWidth = $('.ximg:first').width();
$('.ximg:first').animate({
width: 0
}, 2000, function() {$(this).insertAfter($('.ximg:last')).css({width: origWidth})});
}
There are also CSS problems with the elements. The parent element should have white-space: nowrap, so the elements are in the same line, even when they're not visible. The children elements should have display:inline-block, so they can be in a line (i.e. inline), and have configurable widths.
Another thing to be aware of is the space between <div>s. You need to make sure there is no unintentional spaces, which include newlines.
See the updated demo: http://jsfiddle.net/rgct2/7/.
Tested and its working, instead of use remove, use "detach"
function xxx(){
$('.ximg').css({left: '0'});
$('.ximg').animate({ left: '-=200'}, 2000, function(){ });
$('.ximg:first').detach().insertAfter( $('.ximg:last') );
}
Really easy, I'm sure...
I have a div which is the full screen and I want it to slide down from the top to the bottom.
I have this:
$('#full-screen').animate({
"bottom":0,
height: 'toggle'
}, 1000, function() {
// Animation complete.
});
But this is the wrong way round as the bottom moves up; how do I get the bottom to stay where is is and the top to slide down to meet it?
Thanks
Your exact code works fine when you have absolute positioning on the element.
http://jsfiddle.net/hhEJD/
CSS
body {
padding: 0;
margin: 0;
}
#full-screen {
background: orange;
color: white;
width: 100%;
height: 100%;
position: absolute; // position absolute, and your code works
clip:auto;
overflow:hidden;
}
HTML
<div id="full-screen"></div>
Your code
$('#full-screen').animate({
"bottom":0,
height: 'toggle'
}, 1000, function() {
// Animation complete.
});
You're setting the bottom style to 0 in your animate. This has no effect if you don't use absolute positioning on your element.
You need to also animate the 'top' property of the div as well as disabling the animation queue so both animations happen at the same time.
$('#slide2').animate(
{height: '0px'},
{
duration: 1000,
queue: false, //Disable the queue so both events happen at the same time.
complete: function()
{
// animation complete
}
}
).animate( //also animate the top property
{top: '500px'},
{duration: 1000}
);
Try it out over at jsFiddle.
You can use marginTop for it:
var h=$('#full-screen').height();
$('#full-screen')
.animate(
{marginTop: h, height: 'toggle'},
1000,
function() {
// Animation complete.
}
)
see at: http://jsbin.com/esotu3