Im trying to make '.pierre' .moveDown once the image has a left position of 20% but its not working. Whats supposed to happen is once the image has a left position of 20% it needs to fall down the page by itself. The html and css code is located in the fiddle.
Heres a link to a fiddle
https://jsfiddle.net/Pallonej/0vhc7pqq/
this is my script thats not working
if ($('.pierre').css('left') == '20%') {
$(this).moveDown();
}
Your check for the position should be inside of the keydown handler and then parse the value from $.css(..) to an integer to have your comparison work.
The code could look like in the updated fiddle here.
I've also added stop to you animation to avoid animation queuing. Maybe it's better to do this with-out animation.
With $(document).width() * 0.2 you can calculate the relative position for the falling position.
If you want to hide or remove the box once it is fallen you can add a done callback to the animation to do what you're looking for. In the demo I've hidden the box.
//move person
$(document).keydown(function (e) {
if (e.keyCode == 37) { // left
$(".pierre").stop(true,true).animate({
left: "-=30"
});
} else if (e.keyCode == 37) { // right
$(".pierre").stop(true,true).animate({
left: "-=30"
});
}
//console.log($('.pierre').css('left'));
if (parseInt($('.pierre').css('left')) <= $(document).width() * 0.2 ) {
//$(this).slideDown();
$('.pierre').animate({
top: "+=" + $(document).height()
}, function() {
$(this).hide();
});
}
});
//fall
/*if ($('.pierre').css('left') === '+5px') {
//$(this).slideDown();
$(this).animate({
left: "-=30"
});
}*/
.pierre {
height:15%;
width:15%;
background: black;
position: absolute;
left: 90%;
top: -.7%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='pierre'></div>
You need to work with the offset property and not position
Here's an example for your question with extra feature to illustrate the concept :
var position = $(".pierre").offset();
$(document).keydown(function(e) {
var y= $(".pierre").offset().top;
var x = $(".pierre").offset().left;
if (e.keyCode == 37) { // left
$("#position").html("X: "+x+" , Y:"+y);
$(".pierre").animate({
left: "-=30"
});
} else if (e.keyCode == 37) { // right
$(".pierre").animate({
left: "+=30"
});
}
if (x<=200) {
$(".pierre").animate({
top: "+=30"
});
}
});
and here is the JSFiddle
As Alundra alreay mentioned, you should use .offset().
You can add a callback to the .animate function, which will be executed after the animation has finished. If the location is right, you can call stop, in order to stop all current (and future) animation, so it won't move left again for the times you button-bashed left. Then you can again animate it to let it fall.
The new js code (I removed the second right-left button part for readability):
//move person
$(document).keydown(function(e) {
if (e.keyCode == 37) { // left
$(".pierre").animate({
left: "-=30"
}, function(){
if($('.pierre').position().left < window.innerWidth/5){
$('.pierre').stop(true);
$('.pierre').animate({
top: "+=1000"
});
}
});
}
});
Related
I have an animation triggered by a scroll event, which makes a menu slide out of view. There is also a button that when clicked brings the menu back into view.
Because the menu can be closed by scrolling, when the user clicks the button to bring the menu in, if they scroll during this period of the animation, the menu disappears again without the animation completing.
I have put together a simplified version of the animation here http://codepen.io/emilychews/pen/evbzMQ
I need to temporarily prevent the scroll function working after the button is clicked, which I'm assuming would be best done with the setTimeout() method on the click function? I've tried a number of things but can't seem to solve it/ get it to work.
Any help would be awesome. For quick reference as well the code is below
JQUERY
jQuery(document).ready(function($){
// slide menu to left on scroll
function hideOnScroll() {
$(window).scroll(function() {
if ( $(document).scrollTop() > 1) {
$('.menubox').css('left', '-25%');
}
});
}
hideOnScroll(); // call hideOnScroll function
// click handler to bring menu back in
$('.mybutton').on('click', function() {
$('.menubox').css('left', '0%');
var scrollPause = setTimeout(hideOnScroll, 2000) // temporarily pause hideOnScroll function
});
}); //end of jQuery
CSS
body {
margin: 0;
padding: 0;
height: 200vh;}
.menubox {
top: 100;
position: fixed;
width: 20%;
height: 100%;
background: red;
padding: 10px;
color: white;
transition: all 2s;
}
.mybutton {
position: fixed;
left: 40%;
top: 50px;
padding: 5px 10px;
}
HTML
<div class="menubox">Menu Box</div>
<button class="mybutton">Click to bring back menu</button>
** Also please note I've simplified the animation for the sake of the forum, the actual animation function contains Greensock code, but I didn't want to include this in case it confused the issue. I can't therefore just use the .addClass() and .removeClass() or have a workaround that changes the given CSS or scrollTop() values. I need to disable the hideOnScroll() function when the button is clicked for the duration of the click invoked animation - which in the examples is 2s. Thus I think the only way to achieve this is with the setTimeOut() method (i may be wrong on this). But I can't get it to work.
Many thanks
Emily
you can simply check the offset is complete.
function hideOnScroll() {
$(window).scroll(function() {
if ( $(document).scrollTop() > 1) {
if( $('.menubox').offset().left == 0 ){
$('.menubox').css('left', '-25%');
}
});
}
http://codepen.io/anon/pen/aJXGbr
I have made a few changes in your javascript. Have a look
var animating = false;
$(document).ready(function(){
function hideOnScroll() {
$(window).scroll(function() {
event.preventDefault();
if ( $(document).scrollTop() > 1 && !animating){
console.log("Hiding")
animating = true;
$('.menubox').animate({'left': '-25%'},2000,function(){
animating = false;
});
}
});
}
hideOnScroll();
$('.mybutton').click(function() {
var pos = $(window).scrollTop();
animating = true;
$('.menubox').animate({'left':'0%'},2000,function(){
console.log("Finished Opening");
animating = false;
});
console.log("Animating Open");
var siId = setInterval(function(){
if(animating){
console.log("Preventing Window Scrolling.");
$(window).scrollTop(pos);
}
else{
console.log("Stopping setInterval");
animating = false;
clearInterval(siId);
}
},0);
});
});
This will stop your browser window from scrolling until your Menu Open Animation is finished.
Also I have removed the transitionproperty from style.
Tested in Google Chrome.
Kindly inform me if i have misinterpreted your question.
I have 2 div with height and width of 100%. one is top:0px and the other is top 100%;
I want to go from one to the other one with an animation which start when I use the mousewheel. it worked fine with my code.
$(window).bind('mousewheel DOMMouseScroll', function(event){
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
TweenLite.to(window, 2, {scrollTo:{y:$( "#one").offset().top}});
} else {
TweenLite.to(window, 2, {scrollTo:{y:$("#two").offset().top}});
}
}
But I want to stop that script when I enter in the second div and then use the wheel as usual for the rest of the page. ( other full pages div)
So I can do
....
else {
TweenLite.to(window, 2, {scrollTo:{y:$("#two").offset().top}});
$(window).unbind(); (but i dodn't know if it's really ok )
}
That works fine. But now I would like to make the wheel script work again when we reach the top of the div "two". I tried with conditions but i couldn't make it work.
This is my code (you can also see it on this codepen where it works):
$(window).bind('mousewheel DOMMouseScroll', function(event){
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
TweenLite.to(window, 2, {scrollTo:{y:$( "#one").offset().top}, ease:Expo.easeOut});
}
else {
TweenLite.to(window, 2, {scrollTo:{y:$( "#two").offset().top}, ease:Expo.easeOut});
}
});
body{overflow:hidden}
#one {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 1;
background:#733;
}
#two {
position: absolute;
width: 100%;
height: 90%;
left: 0;
top: 100%;
z-index: 1;
background:#439;
}
#three {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 190%;
z-index: 1;
background:#896;
}
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
This solution is not pretty, but it works. You could use it as a workaround while somebody (or yourself or myself) look for a better solution.
var animation = false;
var scrollby = 20;
$(window).bind('mousewheel DOMMouseScroll', function(event){
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
if ($( "#two").offset().top == $(window).scrollTop()) {
TweenLite.to(window, 2, {scrollTo:{y:$( "#one").offset().top}, ease:Expo.easeOut, onComplete:function() { animation=false; }, onStart: function(){ animation=true; } });
} else {
if (!animation){
if ($(window).scrollTop() - scrollby < $( "#two").offset().top) {
$(window).scrollTop($( "#two").offset().top);
} else {
window.scrollBy(0,-scrollby);
}
}
}
}
else {
if ($(window).scrollTop() == 0) {
TweenLite.to(window, 2, {scrollTo:{y:$( "#two").offset().top}, ease:Expo.easeOut, onComplete:function() { animation=false; }, onStart: function(){ animation=true; }});
} else {
if (!animation) {window.scrollBy(0,scrollby);}
}
}
});
You can see it working on this codepen.
Your initial code did this:
If the mousewheel goes down, scroll down to #two.
If the mousewheel goes up, scroll up to #one.
The modified code above changes a bit:
If the mousewheel goes down:
If you are at the top of the page (#one), scroll down to #two.
Or else (you are in #two or below), scroll down a given amount.
If the mousewheel goes up:
If you are at #two, then scroll up to #one.
If you are not at #two (you are below that point), scroll up a given amount.
I also added a couple of checks to avoid issues:
Check if there is an animation (TweenLite.to) going on before scrolling. This is achiveved by setting the animation variable on the onStart and onComplete events of TweenLite.
If scrolling up you go above #two, autocorrect and go to #two. This issue only happens when you scroll to the bottom of the page and then scroll up.
So I am trying to make a nav bar which is hidden when you first load the page and displays when you scroll down to the second section, I have got it working but when you scroll up and down within the home section, the nav bar keeps appearing and disappearing again when it should stay out of sight.
Live Demo: http://zimxtrial.ukbigbuy.com/
JS:
<script type="text/javascript">
jQuery(document).ready(function() {
var startY= jQuery('#home').position().top + jQuery('#home').outerHeight();
jQuery('#nav-container').html( jQuery('#nav').html());
jQuery(window).scroll(function () {
if(jQuery(this).scrollTop() > startY ){
jQuery('#nav-container').slideDown();
}else{
$('#nav-container').css({display: 'block'});
jQuery('#nav-container').slideUp();
}
});
});
</script>
CSS:
#nav-container {
position: fixed;
height: 50px;
width: 100%;
min-width: 600px;
display: none;
}
Any help would be greatly appreciated, thanks guys.
Also, this is my first time messing around with JQuery and JS so be kind.
Final version after fix:
<script type="text/javascript">
$(document).ready(function() {
var startY= $('#home').position().top + $('#home').outerHeight();
var navc = $('#nav-container')
navc.html( $('#nav').html());
$(window).scroll(function () {
if($(this).scrollTop() > startY ){
navc.slideDown();
}else{
navc.slideUp();
}
});
});
</script>
Because you are inside the .scroll() function which gets fired everytime the page is scrolled, it will be going to your else condition and displaying the navbar each time because of this line:
$('#nav-container').css({display: 'block'});
Remove this line and it should work as expected.
You would need to check if the navBar is show or not and depending on that run the scroll() function only if the state is the correct one. Something like this:
if(jQuery(this).scrollTop() > startY && $("#nav-container").css('display') == "none" ){
jQuery('#nav-container').slideDown();
}else if( && $("#nav-container").css('display') == "block"){
$('#nav-container').css({display: 'block'});
jQuery('#nav-container').slideUp();
}
I have a menu that slides out on clicking the nav-toggle class.
Now I also want the nav-toggle class (the menu icon) to move along 226px from the right, so it moves at the same time as the #navigation menu. Then if clicked again it will collapse the menu (as it currently does) and go back to right:0 position.
See my commenting out in the third last line
jQuery('.nav-toggle').click(function () {
var $marginLefty = jQuery('#navigation');
$marginLefty.animate({
right: parseInt($marginLefty.css('right'), 10) == 0 ? -$marginLefty.outerWidth() : 0
});
jQuery('.nav-toggle').animate({
right: "226px"
// How do I make it so if it is at 226px when clicked
// it should then go to "right: 0", that toggle effect as above
});
});
Probably just like you did the #navigation one:
jQuery('.nav-toggle').animate({
right: parseInt(jQuery('.nav_toggle').css('right'), 10) == 0 ? "226px" : 0;
});
Just add a class to check if the nav is expanded/moved or not.
var navbar = $('.nav-toggle');
if (navbar.hasClass('expanded'))
{
$(navbar).animate({'right':'226px'}).removeClass('expanded');
} else {
$(navbar).animate({'right':'0px'}).addClass('expanded');
}
Note these numbers may need flipping.
I think you need to do something like this:
jQuery('.nav-toggle').click(function () {
var $marginLefty = jQuery('#navigation');
$marginLefty.animate({
right: parseInt($marginLefty.css('right'), 10) == 0 ? -$marginLefty.outerWidth() : 0
});
if ($('.nav-toggle').css('right') == '0px') {
$(".nav-toggle").stop().animate({right: '226px'}, 1000);
} else {
$(".nav-toggle").stop().animate({right: '0px'}, 1000);
};
});
i have this script that with li list, if you click on one of the list items, a box slides to the right, and if you click again, its slides back to its orginal place(toggle)
the demo is here:
http://www.kornar.co.uk/home2.php
the problem that i have is on slideout, i want the width of the panel to be 700px
$(".panel").css("width","700px");
on slide back in, i want the width to be 350px, so it hides behind the list again.
$(".panel").css("width","350px");
but the problem im having is on when it slides back, it deosnt hide behind the list, it still shows the panel on the right? thanks
Hey dude, I made a couple of assumptions about what you were trying achieve on the whole, but maybe this is what you were trying to do... The following is all I changed:
<script type="text/javascript">
$(document).ready(function() {
$('.block').click(function(){
var id= $(this).attr('id');
var data_id= $(".data").html();
var panelPositionLeft=$('.panel').css('left');
if(panelPositionLeft=='0px') {
//the .panel is hidden, so slide it out and populate .data with the new id
$('.panel').animate({left: 350, width:700});
$('.data').html(id);
} else if (data_id!=id){
//something other than the previous .block was clicked and the .panel is obviously open, so don't collapse, just add the new id into .data
$('.data').html(id);
} else {
//neither of the previous situations are true, so it must be that the previously clicked block is being clicked again. Just slide it closed and don't change the value of .data
$('.panel').animate({left: 0, width: 350});
}
});
$('.close').click(function(){
// just slide it closed.
$('.panel').animate({left: 0, width: 350});
});
});
</script>
There are still a few things you could clean up, but I thought this would be a little easier to read and understand. Try this out, let me know if I misunderstood the problem.
Thanks!
Try surrounding the "+" with quotes (i.e. "+" + panel.outerWidth()). I think this should work.
Richard
For getaways reference: this is what I would have posted had masondesu not got there first. As you can see it is very similar, but has if statements where none are actually required (as in masondesu's solution.
$(document).ready(function () {
$('.block').click(function () {
var id = $(this).attr('id');
var data_id = $(".data").html();
var panel = $('.panel');
var panel_width = $('.panel').css('left');
var currLeft = panel.css('left');
var blockWidth = $(".left").outerWidth();
if (data_id == id) {
if (currLeft == "0px") {
panel.animate({ left: blockWidth, width: "700px" });
} else {
panel.animate({ left: "0px", width: "350px" });
}
}
else {
if (currLeft == "0px") {
panel.animate({ left: blockWidth, width: "700px" });
} else {
panel.animate({ left: "0px", width: "350px" });
}
}
$('.data').html(id);
return false;
});
$('.close').click(function () {
var panel = $('.panel');
var currLeft = panel.css('left');
if (currLeft == "0px") {
panel.animate({ left: blockWidth, width: "700px" });
} else {
panel.animate({ left: "0px", width: "350px" });
}
return false;
});
});
Regards,
Richard
You don't resize the panel on "li"-click, it resizes only on ".close"-click. so it won't resize ;)