I'm using JavaScript's .toggle() to have this appear/ disappear:
{
display: none;
position: fixed;
top: 100px;
right: 0;
left: 0;
background: rgba(0,0,0,0.75);
padding: 15px;
}
However, over the duration of the animation it starts from the top-left corner and expands out to the bottom-right corner of the div.
Ideally, I'd like to start it from the both top corners and expand downwards to both bottom corners evenly.
I thought the CSS transition-origin property might have an effect, but it doesn't seem to be the case.
Any ideas? Thanks in advance. :)
I would start a height of 0 and the animate the height property.
function toggle() {
var el = document.getElementsByTagName('div')[0];
if (el.className) {
el.className = '';
} else {
el.className = 'grow';
}
}
div {
background-color: black;
width:200px;
height: 0;
}
.grow {
height: 200px;
transition: height 2s;
}
<button onclick="toggle()">Toggle</button>
<div></div>
I don't know much about jQuery's toggle method, so I looked in the docs, and sure enough it gives some helpful info. (This is a gentle hint that before coming to StackOverflow you should try solving the problem on your own, including looking at any relevant documentation online).
The .toggle() method animates the width, height, and opacity of the
matched elements simultaneously.
The documentation doesn't give any info about customizing how toggle does its animation, so it looks like you're stuck. If I'm understanding you correctly, it seems like you want the element to animate only the height and not the width, so it stays the same width as it toggles and just animates the height. I don't see any way of doing that with jQuery's toggle.
BUT WAIT! It looks like jQuery has another method called slideToggle which does exactly what you want. It's just like toggle except it only animates the height and keeps the width the same. Hooray!
http://api.jquery.com/slidetoggle/
Moral of the story: if you're using a third party Javascript library like jQuery, you really need to get comfortable finding the information you need in the online documentation my friend. :)
Related
I'm making a webpage just for a bit of amusement. I want the background image to endlessly scroll to the left when the page is first loaded. The image is set to repeat-x in CSS and is seamless when laid end-to-end. Is this code I wrote aiming in the right direction?
I'm hoping to keep the JS vanilla just for simplicity but if this is better handled by JQuery, CSS or another library I'll be all ears.
I'll be very grateful for the help!
I've already tried some vanilla JavaScript code in a simple HTML document. My efforts so far haven't made the image move at all.
document.addEventListener("DOMContentLoaded", function() {
var y = 0;
while (true) {
y -= 1;
document.getElementById("bgImg").left = y;
}
})
#bgImg {
background-image: url("img1.jpg");
background-repeat: repeat-x;
width: 100%;
height: 660px;
display: inline;
}
<div id="bgImg">
</div>
This simply freezes my browser and doesn't scroll at all. Likely thanks to the "while(true)".
This is best accomplished with a CSS animation instead of JavaScript. CSS keyframed animations are designed to loop smooth transitions between pre-set property states with minimal memory overhead (and no synchronous while loops :P).
The only added bit of information you need to include is the width of your image. If you use this value as the x-coordinate of background-position in the to state of the animation, as soon as the background travels that many pixels, it will jump back to the from position. This jump will be invisible to the viewer, provided you've set the width correctly.
#bg {
background: url('https://www.gravatar.com/avatar/e47523b278f15afd925a473e2ac0b966?s=120&d=identicon&r=PG&f=1');
background-repeat: repeat-x;
width: 240px;
height: 120px;
animation: bgScrollLeft 5s linear infinite;
}
#keyframes bgScrollLeft {
from {
background-position: 0 0;
}
to {
background-position: -120px 0;
}
}
<div id="bg"></div>
I just implemented this on my own site after seeing your question. cool idea!
function animateBg(px=0){
requestAnimationFrame(()=>{
document.body.style.backgroundPosition = `${px}px 0px`;
animateBg(px+0.5);
});
}
animateBg();
It assumes you have a bg image set in CSS. Change the 0.5 to change the speed.
You are moving the element left, but in fact you should move your background position. Next to that with a while(1) loop it will run infinitly. So 2 task, create an animation frame to not run infinite. And change the background-position property.
var left = 0;
// You might want to add a time delta
function animate() {
requestAnimationFrame( animate );
document.getElementById("bgImg").style.backgroundPosition = '0 ' +left-- + 'px';
}
animate();
Note the code probably wont work, but gives you an idea of an solution.
Look into requestAnimationFrame to know what it does.
edit
Look at IronFlare solution, which is more beautiful with css.
I have a really strange problem: I am using jQuery v11 on the latest Chrome on localhost. While I manage to use jQuery.animate() on my website with any elements and features (including opacity), I have one element that I just can't.
I tried to trigger the animation within and outside the $(document).ready() function and they both resulted in the same thing. I tried with fadeTo, fadeIn/fadeOut, animate opacity, all of them the same thing. The animation starts but after a certain percentage it just doesn't continue and jumps right to the end. I also tried it with e.g. padding and it works perfectly.
I am using the callback too but removing or adding it did not affect performance on either cases. Also, I have browsed through dozens or even more questions already, so I feel I did my research.
Thank you for your help!
JavaScript:
$("#nb_copy").stop().animate({ opacity: 0 }, 300, function()
{
$(this).css("background-position", "-16px").stop().animate({ opacity: 1 }, 300);
});
HTML:
<div id='notes_buttons'>
<a id='nb_copy' data-info=''>C</a>
</div>
CSS:
div#notes_buttons
{
width: 18px;
position: absolute;
top: 180px;
right: -24px;
opacity: 0;
filter: alpha(opacity=0);
}
div#notes_buttons a
{
cursor: pointer;
display: block;
width: 18px;
height: 18px;
margin-bottom: 1px;
background: red url("/db/sprite.png") no-repeat;
background-position: 0px 0px;
}
Note: I would like to use this animation in the following situation: I am animating the opacity (see, here it works...) of the parent div, then when the nb_copy button is pressed, it fades out, changes the bg position and fades back.
If I use really long animations (3000) and add a delay, the first animation interrupts after about 40%, then after the 3000 ms are over, it counts the delay and then the new animation. This way I have no problem with the animation. Also, if I do not use the callback, it is working. But the two interrupt each other somehow...
if I only use the .css in the callback, it applies instantly (the background position) but the animation runs smoothly.
I already spent about 1.5 hours on such a small thing... Well, if I reproduce the code above in JSfiddle, it is working: https://jsfiddle.net/g6z4xx16/. I am also using Zeroclipboard with the same button, may it be the problem?
In case I get it out of the Zeroclipboard nest, and put it into a simple click trigger, the same result.
Why to make simple work complicated, just use fadeToggle() instead.
Simply change your code to this :
$("#nb_copy").fadeToggle(function()
{
$(this).css("background-position", "-16px").fadeToggle();
});
Using fadeToggle() is better because animate() is used to make custom animations.
In your code place your <style> tag before the <script> tag.
I have two containers:
<div class="left">
<div id="myDiv">A Div</div>
<div id="myDiv2">A Div</div>
</div>
<div class="right">
<div id="myDiv3">A Div</div>
</div>
The first contains div elements, which are moved with the following jQuery:
$(".left > div").click(function(){
$(this).appendTo('.right');
});
The above, however, provides no animation. I would like to use a CSS transition to animate each div between the two parent elements (From .left to .right).
By the way, this is my CSS:
.left, .right{
position: absolute;
display: block;
box-sizing: border-box;
width: 50%;
height: 100%;
}
.left{background:red;}
.right{background:green; left: 50%;}
.left > div, .right > div{
display: block;
height: 100px;
width: 100px;
margin: 10px;
float: left;
background: #fff;
color: #000;
}
And a Fiddle: http://jsfiddle.net/x270Lndz/
I figure I need to get coordinates and transition between them, outside both .left and .right.
This has already been answered: https://stackoverflow.com/a/974765/2725684
The problem is 2 parts, moving elements in the DOM, and animating that movement, but the suggested is:
Store the position of the div, in its resting state, in the first column.
Append the div to the second column, store that position.
Turn off the visibility of the div.
Create a clone of the div, positioned where the resting state one was at.
Animate this clone across to the position of the appended div.
Turn off the visibility of this clone.
Turn back on the original div that was appended.
The javascript/jquery will execute this so fast you won't see the turning off/on of the divs and it will just appear as if the div they are seeing is the only one that ever existed.
Try adding transition: 0.5s ease-in to the .left div
Ultimately, this is going to be a lot of work, and I don't think I have the time to write every step out in full. But, if you're committed, here goes:
Call getBoundingClientRect() or similar on the first element to get its absolute document position relative to the document / viewport.
Use the same function, and getComputedStyle()s padding to determine the exact pixel at which content would begin in the second div.
Determine the difference between the two coordinates, in order to fake the transition while the elements are still inside their first parent. (Or, move them first, and fake the transition after)
Apply the correct transform: translate style to the elements, so that they'll appear to move into the other container. (This is assuming you have the transition properties set up correctly in CSS)
On the transitionend event, turn off transitions, remove the transform property, and do the actual child move.
Pat yourself on the back and go home early.
So there you have it. There's likely going to be a lot of math involved and small additions/subtractions I'm not able to predict. Hopefully, that outline helps you get started at least. You might also be lucky enough to find an animation library that does all of this for you. (Also note that I assumed the presence of several functions not supported on all browsers, so check to make sure they're okay by your book)
I wrote a jQuery plugin:
$.fn.transitionTo = function(target){
this.each(function(){
$this = $(this);
marginLeft = parseInt($this.css('marginLeft').replace("px", ""));
marginTop = parseInt($this.css('marginTop').replace("px", ""));
offset = $this.offset();
$new = $this.clone().appendTo(target);
offsetNew = $new.css('opacity',0).offset();
$this.css({
position: 'absolute',
left: offset.left - marginLeft,
top: offset.top - marginTop
}).appendTo("body");
setTimeout(function(a,b){
a.css({
left: offsetNew.left - marginLeft,
top: offsetNew.top - marginTop
});
setTimeout(function(a,b){
b.replaceWith(a.removeAttr('style'));
},2000,a,b); //Anim time
},10,$this,$new);
});
};
It is called similarly to .appendTo:
$(".left > div").click(function(){
$(this).transitionTo('.right');
});
...and only requires transition: top 2s ease, left 2s ease; on the div.
Fiddle: http://jsfiddle.net/d9yxrmvo/1/
The only known issue with this plugin is the lack of support for animating the original element's siblings.
I have a problem with a CSS transition. I need to change the height of the parent div relative to the child divs in the transition.
I am using CSS which has a number of steps which slide from right to left as the user clicks continue (Magento onepage checkout with progress bar).
The problem is that the parent container .opc has a height of 970px but the heights of the additional steps vary so I need to find a way to make the parent DIV .opc change height to accommodate the sizes of the remaining steps.
.opc { position:relative; overflow:hidden; height:970px; padding-top:20px; text-align:center; }
I've tried adding height: auto; or height: 100%; but the remaining pages still don't fill the page and I am not sure how to solve it!
Is there a way to affect the height using jQuery or Javascript, maybe pure CSS?
I'm thinking jQuery to detect which step the user is on the adjust the height of the container to fit the content?
<script>
jQuery(document).ready(function(){
if('#opc-billing'){
jQuery('.opc').height(1200);
}
if('#opc-shipping'){
jQuery('.opc').height(500);
}
})
</script>
Although the above solution doesn't work :(
Any help would be appreciated guys!
Here is a quick demo that might help:
I am simply adding a CSS transition property to the parent as well, and adjusting the height at the same time as the position of the child.
http://jsfiddle.net/qF3u7/
.parent {
background-color: lightyellow;
-webkit-transition: height 2s;
height: 50px;
}
.transit {
position: relative;
top: 0;
width: 50px;
height: 50px;
border: 1px solid red;
-webkit-transition: top 2s;
}
PS: Run this in chrome as I didn't bother with the other browser prefixes for the CSS.
Although it is not a very dynamic function what you have is getting there. Try this:
$(document).ready(function{
var x = $("#opc-billing").height();
var y = $("#opc-shipping").height();
var opc = $(".opc");
if (x === 600){ // - The number values are just examples of course.
opc.height(1200);
}
if (y === 200){
opc.height(400);
} else {opc.height(300);} // - default height, could be left blank if set by CSS(example - else{})
})
DEMO
Keep in mind that when using the height() method results may be unexpected because height() returns the computed value of an element which does not include padding, border or margin and does not take into account something like when a page is zoomed in. Learn more about height() here. To get total height including padding, border and margins use outerHeight().
UPDATE: I added some extra bells and whistles to the JSFiddle. Check it out!
I have a slider, what have an active item which is larger than others. When the controls are clicked, the next/prev item gets the active class. It is working, but I'd like to add a smooth effect for this. Any ideas?
Code:
$('#next').click(function(){
$('#wrap').find('.active').removeClass('active').next().addClass('active');
$('#wrap img:first').remove().appendTo('#wrap');
});
$('#prev').click(function(){
$('#wrap').find('.active').removeClass('active').prev().addClass('active');
$('#wrap img:last').remove().prependTo('#wrap');
});
Example: http://jsfiddle.net/zXjzU/1/
Thanks!
I'm not sure what you define as a "smooth" effect, but a really simple solution given your existing code would be to just add a transition:width 1s to your #wrap img CSS. See JSFiddle:
#wrap img {
width: 100px;
clear: both;
margin: 0 5px 30px 5px;
transition:width 1s;
}
I'm not sure that I'd construct a carousel like this, I'd probably use positions so that my elements scrolled into the center of screen, but it's pretty easy to Google a solution for that too if that's what you're after.