How can I toggle animate a div? - javascript

I tried installing Jquery UI so that I could easily add animation to the toggleClass funciton, but it only animates when adding the class, and not when removing the class (or moving back left to it's original position).
jQuery('#menu').click(function() {
jQuery('#wrap').toggleClass('move-right', 1000);
});
CSS
#wrap {
position: relative;
bottom: 22px;
max-width: 1150px;
margin: 0 auto;
padding: 20px;
}
.move-right {
left: 9%;
}
So How can I get this to animate both ways?
It's just a simple slide to the right, then back left. I thought jQuery UI would be easiest, but if I don't need it even better

add a left position to #wrap
then change your .move-right selector to be more specific
#wrap {
position: relative;
bottom: 22px;
max-width: 1150px;
margin: 0 auto;
padding: 20px;
left:0;
}
#wrap.move-right {
left: 9%;
}
http://jsfiddle.net/TrcLy/

You could try it by using a boolean and if the boolean is true try moving it the other way.
Then your code should be something like this:
JS:
var right = false;
jQuery('#menu').click(function() {
if(!right) {
jQuery('#wrap').toggleClass('move-right', 1000);
right = true;
} else if(right) {
jQuery('#wrap').toggleClass('move-left', 1000);
right = false;
}
});
CSS:
#wrap {
position: relative;
bottom: 22px;
max-width: 1150px;
margin: 0 auto;
padding: 20px;
}
.move-right {
left: 9%;
}
.move-left {
right: 9%;
}
This basically checks whether 'wrap' has moved right on clicking the button. If not, it moves it to the right, otherwise, it moves to the left.

You can use CSS3 transition to define a transition property (left) and time (1s), see: http://jsfiddle.net/m3sEn/1/ This doesn't require jQuery UI.
CSS:
#wrap {
left: 0;
transition: left 1s;
}
#wrap.move-right {
left: 9%;
}

Related

How to make button move to new position on hover

I want a button to move to a new position when you hover over it and it stays there. Sort of like the button is scared of the mouse. Preferably with vanilla JS and CSS
button{
position: absolute;
top: 10px;
left: 10px;
}
button:hover{
left: 200px;
top: 200x;
}
<button>button</button>
const button = document.getElementById('btn');
button.addEventListener('mouseover', function () {
button.style.left = `${Math.ceil(Math.random() * 90)}%`;
button.style.top = `${Math.ceil(Math.random() * 90)}%`;
});
button.addEventListener('click', function () {
alert('you clicked me')
})
#btn {
position: absolute;
transition: .5s;
background-color: dodgerblue;
padding: 10px;
height: 40px;
width: 150px;
}
<button id="btn">Click me if you can</button>
you could give a hudge transition delay, it will look like freezed and las almost an eternity on a webpage. but used only once, to make the button move around, javascript will be needed.
CSS example
button{
position: absolute;
top: 10px;
left: 10px;
transition:0s 20000s ;
}
button:hover{
left: 200px;
top: 200x;
transition:0s 0s;
}
<button>button</button>

Timing and speed of multiple sliding divs

Please see this fiddle I have set up.
You are first confronted by three links. Each link triggers divs to slide out.
The link 'john smith' slides out and in at the speed we want. When it slides out the first line slides out then when that is completed the second line slides down as though coming from the first. When it slides back it does the same motion at the same speed but reverse i.e.. the second line slide back up first and then when that is completed the first line slides back to the left.
When you click on the work link and menu slides out in the same manner as the bio. Also there is a sub menu that slides out when on clicks on item 2.
When the user clicks on the contact link one line slides out.
What we need to achieve is this; when any div is open and another link is clicked on, the visible div slides back in reverse to how they slid in. We have almost achieve this, however, the code is not quite right as the divs are not sliding back in at the same speed and in the right order, they simply slide back fast. For example, if one has clicked on 'work' and the 'item 2' link, and then you select 'contact' the opened div slide back very quickly. What I need to achieve is that they slide back in reverse to how they slid out.
To attempt to make it clear, if you click on 'work' and then 'item 2' so with menus are visible and then click on work again, you will see the sub menu slides away first before the first menu. You will also notice that the items that slide up slide back down first before the divs slide back to the left. This is what needs to happen if you click on 'contact' or 'john smith' when the menus are visible.
I know this sounds very complicated and if I can answer any questions to make it clearer I will.
Thanks
$('#bio-line-1').animate({width: 'hide'});
$('#contact-info').animate({right: 'hide'});
$('#bio-line-2').slideUp("fast");
$('#black-div, #black-credits, #igna-1-div, #igna-1-credits, #igna-2- div, #igna-2-credits, #fatal-div, #fatal-credits').fadeOut('100');
});
you can use .setTimeout() to put some delay
setTimeout(function () {
$('#contact-info').animate({right: 'toggle'});
}, 500);
DEMO
DEMO
I finally worked out how to fix it to work how I intended, however my code is very long winded. I realise there must be a way to reduce the repetition of the code by using generic functions. I will now post the working code onto Code Review for further development.
$('#menu').click(function () {
if ( $('#igna-1').css('display') != 'none' ) {
$('#igna-1').slideToggle("fast", function() {
$('#igna-2').animate({ left: 'hide' }, 300, function() {
$('#black, #igna, #igna-1').slideUp("fast", function() {
$('#fatal, #igna-2').animate({ left: 'hide' }, 300);
});
Although I see that you have found your solution but as I had started coding the TweenMax version of it, I went on and finished it. The reason I am suggesting GSAP should be the go-to tool for animations for the web is not just because it is crazy fast, or easy to jump-start or get started with, or makes some of the coolest animation effects possible with few lines of code (I can go on and on) ... but it is as intuitive as it can get.
Coming back to your animation, I have converted your animation solution into using TimelineMax / TweenMax entirely, snippet of which is as follows:
/*global TweenMax,TimelineMax,Power2,Power0*/
var getElementById=document.getElementById.bind(document);
var nameA=getElementById('name-a'),menu=getElementById('menu'),contact=getElementById('contact');
var contactInfo=getElementById('contact-info'),contactInfoAnchor=contactInfo.querySelector('a');
var igna=getElementById('igna'),ignaAnchor=igna.querySelector('a');
var ignaOne=getElementById('igna-1'),ignaOneAnchor=ignaOne.querySelector('a');
var ignaTwo=getElementById('igna-2'),ignaTwoAnchor=ignaTwo.querySelector('a');
var black=getElementById('black'),blackAnchor=black.querySelector('a');
var fatal=getElementById('fatal'),fatalAnchor=fatal.querySelector('a');
var bioLineOne=getElementById('bio-line-1'),bioLineOneParagraph=bioLineOne.querySelector('p');
var bioLineTwo=getElementById('bio-line-2'),bioLineTwoParagraph=bioLineTwo.querySelector('p');
var tlName=getTimeline(),tlContact=getTimeline(),tlWork=getTimeline(),tlIgnaTwo=getTimeline(),tlWorkIgnaTwoCombined=getTimeline();
var isTlNameDirectionForward=false,isTlContactDirectionForward=false,isTlWorkDirectionForward=false,isTlIgnaTwoDirectionForward=false,reverseTimeScale=1;
var duration=.4,easeInOut=Power2.easeInOut,easeOut=Power2.easeOut,easeIn=Power2.easeIn,easeNone=Power0.easeNone;
function init(){
setTlName();
setTlContact();
setTlWork();
setTlIgnaTwo();
setTlWorkIgnaTwoCombined();
assignListeners();
}
function setTlName(){
addParentDIVsToTimeline(tlName,[bioLineOne,bioLineTwo],['rect(10px 633px 50px 0px)','rect(10px 633px 50px 0px)']);
tlName.fromTo(bioLineOneParagraph,duration,{x:-633},{x:0,ease:easeOut,clearProps:'x'},0).fromTo(bioLineTwoParagraph,duration,{y:-40},{y:0,ease:easeOut,clearProps:'y'},duration*.3);
}
function setTlContact(){
addParentDIVsToTimeline(tlContact,[contactInfo],['rect(0px 120px 20px 0px)']);
tlContact.fromTo(contactInfoAnchor,duration,{display:'block',x:150},{display:'block',x:0,ease:easeOut,clearProps:'display, x'},0);
}
function setTlWork(){
var fromProps={display:'block',y:40},toProps={display:'block',y:0,ease:easeOut,clearProps:'display, y'};
addParentDIVsToTimeline(tlWork,[fatal,igna,black],['rect(0px 120px 20px -90px)','rect(0px 120px 26px 0px)','rect(0px 120px 26px 0px)']);
tlWork.fromTo(fatalAnchor,duration,{display:'block',x:-150},{display:'block',x:0,ease:easeOut,clearProps:'display, x'},0).fromTo(ignaAnchor,duration,fromProps,toProps,duration*.3).fromTo(blackAnchor,duration,fromProps,toProps,duration*.6);
}
function setTlIgnaTwo(){
addParentDIVsToTimeline(tlIgnaTwo,[ignaTwo,ignaOne],['rect(0px 120px 20px -90px)','rect(0px 120px 26px 0px)']);
tlIgnaTwo.fromTo(ignaTwoAnchor,duration,{display:'block',x:-150},{display:'block',x:0,ease:easeOut,clearProps:'display, x'},0).fromTo(ignaOneAnchor,duration,{display:'block',y:40},{display:'block',y:0,ease:easeOut,clearProps:'display, y'},duration*.3);
}
function setTlWorkIgnaTwoCombined(){
tlWorkIgnaTwoCombined.to(tlIgnaTwo,duration,{progress:0,ease:easeNone},0).to(tlWork,tlWork.totalDuration(),{progress:0,ease:easeNone},duration*.3);
}
function assignListeners(){
nameA.addEventListener('click',onNameAClicked,false);
menu.addEventListener('click',onMenuClicked,false);
contact.addEventListener('click',onContactClicked,false);
igna.addEventListener('click',onIgnaClicked,false);
ignaOneAnchor.addEventListener('click',playTlWorkIgnaTwoCombined,false);
ignaTwoAnchor.addEventListener('click',playTlWorkIgnaTwoCombined,false);
black.addEventListener('click',onMenuClicked,false);
fatal.addEventListener('click',onMenuClicked,false);
}
function onNameAClicked(){
isTlNameDirectionForward=!isTlNameDirectionForward;
isTlNameDirectionForward?tlName.timeScale(1).play():tlName.timeScale(1).reverse();
reverseTlContact();
if(isTlIgnaTwoDirectionForward){playTlWorkIgnaTwoCombined();}else if(isTlWorkDirectionForward){reverseTlWork();}
}
function onMenuClicked(){
isTlWorkDirectionForward=!isTlWorkDirectionForward;
isTlWorkDirectionForward?tlWork.timeScale(1).play():tlWork.timeScale(1).reverse();
reverseTlContact();
reverseTlName();
if(isTlIgnaTwoDirectionForward){playTlWorkIgnaTwoCombined();}
}
function onContactClicked(){
isTlContactDirectionForward=!isTlContactDirectionForward;
isTlContactDirectionForward?tlContact.timeScale(1).play():tlContact.timeScale(1).reverse();
reverseTlName();
if(isTlIgnaTwoDirectionForward){playTlWorkIgnaTwoCombined();}else if(isTlWorkDirectionForward){reverseTlWork();}
}
function onIgnaClicked(){
isTlIgnaTwoDirectionForward=!isTlIgnaTwoDirectionForward;
isTlIgnaTwoDirectionForward?tlIgnaTwo.timeScale(1).play():tlIgnaTwo.timeScale(1).reverse();
}
function addParentDIVsToTimeline(tl,parents,clipRects){
var length=parents.length;
for(var i=0;i<length;i+=1){tl.fromTo(parents[i],duration,{display:'none',clip:clipRects[i]},{display:'block',clip:clipRects[i],ease:easeOut,clearProps:'clip'},duration*.3*i);}
}
function getTimeline(){return new TimelineMax({paused:true});}
function reverseTlContact(){
if(isTlContactDirectionForward){
isTlContactDirectionForward=false;
tlContact.timeScale(reverseTimeScale).reverse();
}
}
function reverseTlName(){
if(isTlNameDirectionForward){
isTlNameDirectionForward=false;
tlName.timeScale(reverseTimeScale).reverse();
}
}
function reverseTlWork(){
isTlWorkDirectionForward=false;
tlWork.timeScale(reverseTimeScale).reverse();
}
function playTlWorkIgnaTwoCombined(){
isTlIgnaTwoDirectionForward=isTlWorkDirectionForward=false;
tlWork.pause(tlWork.totalTime());
tlIgnaTwo.pause(tlIgnaTwo.totalTime());
tlWorkIgnaTwoCombined.pause(0).play();
}
//
init();
#name-a {
left: 38px;
position: fixed;
top: 38px;
z-index: 1;
}
#bio-line-1 {
left: 150px;
position: fixed;
top: 35px;
width: 633px;
z-index: 1;
}
#bio-line-1 p {
color: #333333;
display: block;
float: right;
font-size: 16px;
line-height: 21px;
width: 552px;
}
#bio-line-2 {
left: 150px;
margin-top: 20px;
position: fixed;
top: 38px;
width: 633px;
z-index: 1;
}
#bio-line-2 p {
color: #333333;
display: block;
float: right;
font-size: 16px;
line-height: 21px;
width: 552px;
}
#menu {
bottom: 34px;
left: 38px;
position: fixed;
z-index: 4;
background-color: #ffffff;
}
#contact {
bottom: 34px;
position: fixed;
right: 38px;
z-index: 1;
background-color: #ffffff;
}
#contact-info {
bottom: 34px;
margin-right: 38px;
position: fixed;
right: 160px;
text-transform: lowercase;
white-space: nowrap;
}
.hidden {
display: none;
}
#fatal {
bottom: 34px;
float: right;
left: 135px;
margin-left: 36px;
position: fixed;
white-space: nowrap;
z-index: 1;
}
#black {
bottom: 61px;
float: right;
left: 171px;
margin-bottom: 18px;
position: fixed;
white-space: nowrap;
z-index: 1;
}
#igna {
bottom: 52px;
float: right;
left: 171px;
margin-bottom: 5px;
position: fixed;
white-space: nowrap;
width: 270px;
z-index: 1;
}
#igna-1 {
bottom: 72px;
left: 404px;
margin-bottom: 7px;
position: fixed;
white-space: nowrap;
width: 162px;
z-index: 1;
}
#igna-2 {
bottom: 57px;
left: 82px;
margin-left: 321px;
position: fixed;
white-space: nowrap;
width: 162px;
z-index: 1;
}
.sub-menu {
white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script>
<div id="name-a">John Smith</div>
<div id="menu">Work</div>
<div id="contact">Contact</div>
<div class="hidden" id="contact-info">conatct#foo.com</div>
<div class="hidden hover" id="black">item 1</div>
<div class="hidden hover" id="igna">item 2</div>
<div class="hidden hover" id="fatal">item 3</div>
<div class="hidden hover" id="igna-1">S/S <span id="ss">15</span></div>
<div class="hidden hover" id="igna-2">A/W 14</div>
<div id="bio-line-1" class="hidden"><p>holds a Master's Degree from the University of the Arts London</p></div>
<div id="bio-line-2" class="hidden"><p>and currently works foo bar.</p></div>
Hope you find it all useful in some way.
Further reading:
Sequence JavaScript Animations Like a Pro with GSAP's
TimelineLite.
Understanding the Position Parameter.
P.S. The example above may not have done justice to the library. There may have been bugs in my code or the approach may seem overly complicated, but these shouldn't take away the credits from this GreenSock Animation Platform. Love this tool.
T

Div Expandsion on Click

I was wondering if anyone can give me some insight on javascript/jquery for div expansion. In the JSFiddle you will find:
Four black divs:
.first_box {
width: 142px;
height: 142px;
margin-left: 0px;
margin-top: 0px;
position: absolute;
display: table;
background-color: black;
}
A unique hover color for each div:
.first_box:hover {
width: 142px;
height: 142px;
margin-left: 0px;
margin-top: 0px;
position: absolute;
display: table;
background-color: green;
}
So my question is:
What can I use so that when a div is clicked, it expands to the size of the four divs (289 X 289)?
The expanded div will then be filled with unique content.
Thank you!
JSFiddle: http://jsfiddle.net/SXfeG/1/
If you use absolute positionning, you can add some CSS like that :
.div-clicked {
width: 289px !important ;
height: 289px !important ;
margin-top: 0 !important ;
margin-left: 0 !important ;
z-index: 400 ;
}
div {
transition: all 1s ; // To add transition effect
}
And then, with jQuery, you can toggle 'clicked' class simply by using :
$('div').on('click', function (e) { $(this).toggleClass('clicked') ; })
JSFiddle : http://jsfiddle.net/85QFN/

Scroll to top script - div won't hide when on top

I'm working on this website called http://martindue.dk/mmd3x9x/ and I have this scroll to top script that just won't coorporate. I've used the script on many other sites, and it works fine, but on this particular website the div#to-top keeps on re-appearing, even though I'm at the very top of the website, why won't it fade out correctly when at the top?
My code looks like this (the #to-top is insertted after the body-tag in my html):
Javascript
jQuery(document).ready(function() {
$toTop = jQuery("#to-top");
$toTop.hide();
jQuery(window).scroll(function() {
if(jQuery(this).scrollTop() != 0) {
$toTop.fadeIn();
} else {
$toTop.fadeOut();
}
});
$toTop.click(function() {
jQuery("body, html").animate({ scrollTop : 0 }, 500);
return false;
});
});
CSS
#to-top {
background: url("img/to-top.png") center top no-repeat;
background-size: 100%;
width: 50px;
height: 50px;
position: fixed;
bottom: 60px;
right: 60px;
cursor: pointer;
/*display:none;*/
/*opacity: 0.0;*/
}
I created this fiddle, and here it works fine: http://jsfiddle.net/2Rubp/
I know it is not js but in this case you are only using fading so css can do the trick:
#to-top {
background: url("img/to-top.png") center top no-repeat;
background-size: 100%;
width: 50px;
height: 50px;
position: fixed;
bottom: 60px;
right: 60px;
cursor: pointer;
**-webkit-transition: all 0.5s linear;**
display: none;
opacity: 0.0;
}
NB: this is for chrome see this for cross browser compatibility
http://www.w3schools.com/css/css3_transitions.asp

jQuery Help - Appear underneath rather than on top

I have the following jQuery which I need adapting:
$(document).ready(function(){
$(".rss-popup a").hover(function() {
$(this).next("em").stop(true, true).animate({opacity: "show", top: "-60"}, "slow");
}, function() {
$(this).next("em").animate({opacity: "hide", top: "-70"}, "fast");
});
});
CSS:
.rss-popup {
margin: 100px auto;
padding: 0;
width: 100px;
position: relative;
}
div.rss-popup em {
background: url(../images/rssbuttonbubble.png) no-repeat;
width: 100px;
height: 49px;
position: absolute;
top: -70px;
left: -0px;
text-align: center;
text-indent: -9999px;
z-index: 2;
display: none;
}
#rss-icon {
width: 42px;
height: 42px;
background: url(../images/rssbutton.png) no-repeat 0 0;
text-indent: -9999px;
margin: 0 auto;
display: block;
}
The HTML:
<div class="rss-popup">
RSS Feed
<em>Subscribe to our RSS Feed</em>
</div>
I want to make the rssbuttonbubble.png appear underneath rather then from above, can any make any suggestions as to how I can achieve this?
Just adjust your top values in the animation and css to be the distance you want:
$(".rss-popup a").hover(function() {
$(this).next("em").stop(true, true).animate({opacity: "show", top: "60"}, "slow");
}, function() {
$(this).next("em").animate({opacity: "hide", top: "70"}, "fast");
});
And in CSS change top: -70px; to:
top: 70px;
This will make it appear below, then just decrease those values if you want it higher, increase if you want it lower.
Nick's answer is correct. You will want to attempt to do this via CSS but just in case you can't you could also achieve something similiar via Jquery. There is an offset() function that returns the onscreen position of a matched element. Once you have that you can then set the position of another element to this position and add the source elements height to the Y coordinate.
See the jQuery documentation here.

Categories