So, I'm trying to make an animation in JavaScript (I want a navigation bar to pull down when I click it). The problem is that every time I click this navigation bar, it only moves down one pixel. How do I make it to where I can make the "Move" function repeat over and over so that it realizes the navigation bar is below "0", and move it up? Here's the code I have atm:
var i = -43 //original position of div
function Move(x)
{
if (i < 0)
{
i++;
x.style.top = i + "px";
}
}
function setPosition(x)
{
setInterval(Move(x), 500);
}
P.S. I have the "div onclick" equal to "setInterval(this)"
I would use a setTimeout() (so you don't have to worry about canceling the setInterval()), and note the use of an anonymous function (function(){}) for the first argument of the setTimeout() call:
#slider {
position: absolute;
top: -43px;
left: 200px;
width: 200px;
height: 50px;
border: 1px solid blue;
background: #dff;
}
<div id='slider'>This is a slidout</div>
<div id="clicker">Click me!</div>
var slider = document.getElementById('slider'),
clicker = document.getElementById('clicker');
clicker.onclick = function(){
Move(slider, -43);
};
function Move(x, i)
{
if (i < 0)
{
i++;
x.style.top = i + "px";
setTimeout(function(){
Move(x, i);
}, 50);
}
}
http://jsfiddle.net/h2C3A/
Related
I have a variable count that triggers a function positiveBar if the value of count is > 0. If the value of count is < 0, it triggers a function negativeBar.
positiveBar changes a div's position using
progressBar.style.left = '50%';
negativeBar changes that same div's position using
progressBar.style.right = '50%';
This gives me the result I want; however, if at any point count becomes greater than 0, the positioning on negativeBar stops working, and it uses the positioning of the positiveBar function instead.
Video to explain:
var count = 0;
// Show count on the page
document.getElementById("countDisplay").innerHTML = count;
// Update count
function updateDisplay() {
countDisplay.innerHTML = count;
};
// Change negative count to an absolute
function absCount() {
return Math.abs(count);
};
function positiveBar() {
progressBar.style.backgroundColor = "#77eb90";
progressBar.style.width = (count * 10) + 'px';
progressBar.style.left = '50%';
};
function negativeBar() {
progressBar.style.backgroundColor = "#ef5c3f";
progressBar.style.width = (absCount() * 10) + 'px';
progressBar.style.right = '50%';
};
// Count up and down when + and - buttons are clicked and edit bar
add1.addEventListener("click", () => {
count++;
updateDisplay();
if (count > 0) {
positiveBar();
} else {
negativeBar();
}
});
subtract1.addEventListener("click", () => {
count--;
updateDisplay();
if (count > 0) {
positiveBar();
} else {
negativeBar();
}
});
.progressBar__Container {
height: 10px;
margin: 20px auto;
border: 1px solid black;
position: relative;
}
#progressBar {
height: 10px;
width: 0;
position: absolute;
}
<div id="countDisplay"></div>
<button id="add1">+</button>
<button id="subtract1">-</button>
<div class="progressBar__Container">
<div id="progressBar"> </div>
</div>
I tried reordering statements. I also tried creating a condition for if count = 0, but that didn't change the result. I'm very confused because it initially works how I intend, but if count becomes greater than 0 at any point, progressBar.style.right = '50%'; stops being applied.
You aren't clearing any previously set left or right styles when you switch from negative to positive and vice versa.
I would use CSS classes to control the position and colour as it's easier to toggle them based on the state of count.
let count = 0;
const countDisplay = document.getElementById("countDisplay");
const progressBar = document.getElementById("progressBar");
// Update count
function updateDisplay() {
countDisplay.textContent = count;
progressBar.style.width = `${absCount() * 10}px`;
progressBar.classList.toggle("positive", count > 0);
progressBar.classList.toggle("negative", count < 0);
};
// Change negative count to an absolute
function absCount() {
return Math.abs(count);
};
// Count up and down when + and - buttons are clicked and edit bar
add1.addEventListener("click", () => {
count++;
updateDisplay();
});
subtract1.addEventListener("click", () => {
count--;
updateDisplay();
});
.progressBar__Container {
height: 10px;
margin: 20px auto;
border: 1px solid black;
position: relative;
}
#progressBar {
height: 10px;
width: 0;
position: absolute;
}
#progressBar.positive {
background-color: #77eb90;
left: 50%;
}
#progressBar.negative {
background-color: #ef5c3f;
right: 50%;
}
<div id="countDisplay">0</div>
<button id="add1">+</button>
<button id="subtract1">-</button>
<div class="progressBar__Container">
<div id="progressBar"> </div>
</div>
See MDN:
When both left and right are defined, if not prevented from doing so by other properties, the element will stretch to satisfy both. If the element cannot stretch to satisfy both — for example, if a width is declared — the position of the element is over-constrained. When this is the case, the left value has precedence when the container is left-to-right; the right value has precedence when the container is right-to-left.
Because you are setting style.left when you then come to set style.right the above applies - i.e. the style.right setting will get overridden.
I am trying to make me character moving left and up and I think jump() and slideLeft()
functions are working properly and the problem is in the controller(e) function (else if (e.KeyCode===37)) . The first function is avaible but it isn't able to acces the second conditon function. Also, I would want to make the grid solid after I will make an slideRight() similar function ,so if my character is jumping on it, the platform would sustain the square . Has anyone any ideea for either of my questions ?
Code snippet:
var square = document.querySelector('.square');
var grid = document.querySelector('.grid');
var bottom = 0;
let isJumping = false;
let isGoingLeft = false;
var newBottom;
let left = 0;
let leftTimerId;
function jump() {
if (isJumping) return
let timerUpId = setInterval(function() {
if (bottom > 250) {
clearInterval(timerUpId);
let timerDownId = setInterval(function() {
if (bottom < 0) {
clearInterval(timerDownId);
isJumping = false;
}
bottom -= 5;
square.style.bottom = bottom + 'px';
}, 20)
}
isJumping = true;
bottom += 30;
square.style.bottom = bottom + 'px';
}, 20)
}
function slideLeft() {
console.log('da');
isGoingLeft = true;
leftTimerId = setInterval(function() {
left -= 5;
square.style.left = left + 'px';
}, 20)
}
function controller(e) {
if (e.keyCode === 32)
jump();
else if (e.KeyCode === 37)
slideLeft();
}
document.addEventListener('keydown', controller);
.grid {
position: absolute;
background-color: chartreuse;
height: 20px;
width: 500px;
bottom: 100px;
left: 100px;
}
.square {
position: absolute;
background-color: darkblue;
height: 100px;
width: 100px;
bottom: 0px;
left: 150px;
}
`
<div class="grid"></div>
<div class="square"></div>
EDIT:
There is a typo:
The second time you've written KeyCode
function controller(e) {
if(e.keyCode===32) {
jump();
}
else if(e.keyCode===37) {
slideLeft();
}
}
I don't really understand what you mean by the second part of your question. If you want a character to have the ability to jump on a square, you'll have to implement a collision detection. Something like this:
if ( isNotOnGround() ) {
fall()
}
I am new to using javascript and jquery so I'm having some problems figuring this one out.
I am trying to use the animate function in jquery to move a box from one corner to the next.
The box begins on the top-left corner of the screen and upon clicking the 'go' button, it will move to the next corner (top-right).
Clicking the same 'go' button then moves the box to the next corner (bottom-right).
Clicking the 'go' button once more will move it to the next corner (bottom-left).
Clicking the 'go' button once more will move it to the next corner (top-left, which is the start).
I've included a picture to show exactly what I mean by this:
What the program should do!
So, this is what I've got so far:
$(document).ready(function () {
$('#go').click(function(){
var dest = parseInt($('#block').css('margin-left').replace('px', '')) + 100;
if (dest > 0) {
$('#block').animate({
marginLeft: '1800px'
}, 0 );
}
else {
$('#block').animate({
marginLeft: dest + 'px'
}, 0 );
}
});
});
#block {
width: 100px;
height: 100px;
background: red;
margin: 0px;
top: 0px;
left: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="block"></div>
<button id="go">» Run</button>
I've got the box to move to the top-right corner but cannot figure out how to make it now move down using the same button.
I've tried something with a toggle but it did not work. That looked something like this:
$(document).ready(function () {
$('#go').click(function(){
var toggle = 1
if (toggle == 1){
$("#block").animate({left: "80px"});
toggle = 0;
} else{
$("#block").animate({right: "80px"});
toggle = 1;
}
});
I was thinking of maybe using cases to switch between which coordinates the button will move the box to. However, I have no knowledge of how this works with jquery and the animate function.
If anyone has any other ideas or knows how to use the case switches in this scenario, I would really appreciate it and thank you in advance!
P.S. I've tried searching this answer on here for a couple of hours now and have not found much that will help me. I am hoping this question will serve to help others who are having a similar problem to mine!
Please try this example:
$(document).ready(function () {
var leftValue = window.innerWidth - 115; // 115 is a temp value
var topValue = window.innerHeight - 115;
var actionNum = 0;
var movingBlock = $('#block');
$('#go').click(function () {
if (actionNum < 4) {
actionNum++;
} else {
actionNum = 1;
}
switch (actionNum) {
case 1:
// move to the top right
movingBlock.animate({
left: leftValue + 'px',
top: 0
}, 1000);
break;
case 2:
// move to the bottom right
movingBlock.animate({
left: leftValue + 'px',
top: topValue + 'px'
}, 1000);
break;
case 3:
// move to the left bottom
movingBlock.animate({
top: topValue + 'px',
left: 0
}, 1000);
break;
case 4:
// move to the top left
movingBlock.animate({
left: 0,
top: 0
}, 1000);
break;
default:
break;
}
});
});
#block {
width: 100px;
height: 100px;
background: red;
margin: 0px;
top: 0px;
left: 0px;
position: relative;
z-index: 1;
}
#go {
z-index: 2;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="block"></div>
<button id="go">» Run</button>
There is a multi solution for your problem ,
So I suggest some simple solution , is that you pput position absolute to your div ,
then change (annimate) the left or top of this last after checking conditions ,
you can get top left position in Jquery using .position() funcion ,
See belwon Snippet (added , 1000 milisseconde in order to show annimation transition )
var widh_annimation = "400px";
var hieght_annimation = "100px";
$(document).ready(function () {
$('#go').click(function(){
var position = $("#block").position();
var annimation = {};
if(position.left == 0 && position.top == 0) {
annimation = { left:widh_annimation};
}else if(position.left > 0 && position.top == 0) {
annimation = { top:hieght_annimation};
}else if(position.left > 0 && position.top > 0) {
annimation = { left:"0"};
}else if(position.left == 0 && position.top > 0) {
annimation = { top:"0"};
}
$('#block').animate(annimation, 1000 );
});
});
#block {
width: 100px;
height: 100px;
background: red;
margin: 0px;
top: 0px;
left: 0px;
position:absolute;
}
#go {
position:absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="block"></div>
<button id="go">» Run</button>
I am rotating an element when I click on a button using setInterval along with clearInterval to stop rotation when a certain value is reached by clearing the interval time t.It works well but when I click on the same button over and over again before the current animation completes , the animation no longer stop rotating.clearInterval does not work in this case.
The code below illustrates it :
var t; // interval
var x = 0 ; // counter
var cal ; // element to be rotate
function prepareRotatesX(){
x=x+5;
cal =document.getElementById("myCalendar");
cal.style.transform="rotateX("+x+"deg)";
if(x>360){ clearInterval(t); x=0;}
}
function rotate(){
t = setInterval(function(){
prepareRotatesX();
}, 10);
}
#myCalendar{
position: absolute;
top:45px;
left:20px;
border: 2px solid blue;
width: 210px;
height:170px;
background-color:blue;
}
<div id="myCalendar">
<!---HERE COME CALENDAR -->
</div>
<!-- make rotation-->
<button id='bnext' onclick='rotate();'>Rotation</button>
So how to stop rotation in this case ?
The option you are probably after is if it is still running than do not run it again. So see if t is defined, if it is exit. And when the loop is done, than you can reset the interval.
var t; // interval
var x = 0; // counter
var cal; // element to be rotate
function prepareRotatesX() {
x = x + 5;
cal = document.getElementById("myCalendar");
cal.style.transform = "rotateX(" + x + "deg)";
if (x > 360) {
clearInterval(t);
x = 0;
t = null
}
}
function rotate() {
if (t) return; // if t is defined, than it is running so exit
t = setInterval(function() {
prepareRotatesX();
}, 10);
}
#myCalendar {
position: absolute;
top: 45px;
left: 20px;
border: 2px solid blue;
width: 210px;
height: 170px;
background-color: blue;
}
<div id="myCalendar">
<!---HERE COME CALENDAR -->
</div>
<!-- make rotation-->
<button id='bnext' onclick='rotate();'>Rotation</button>
other option is to just clear the interval and restart it
function rotate() {
if (t) clearInterval(t)
t = setInterval(function() {
prepareRotatesX();
}, 10);
}
Variable t declared globally is creating problem, if you move t to local scope in your code. It should fix your problem (Assuming that previous clicks rotation should continue)
In case if you want to abort the previous click, you can follow solution given by #epascarello
var x = 0 ; // counter
var cal ; // element to be rotate
function prepareRotatesX(t){
x=x+5;
cal =document.getElementById("myCalendar");
cal.style.transform="rotateX("+x+"deg)";
if(x>360){ clearInterval(t); x=0;}
}
function rotate(){
var t; // interval
t = setInterval(function(){
prepareRotatesX(t);
}, 10);
}
#myCalendar{
position: absolute;
top:45px;
left:20px;
border: 2px solid blue;
width: 210px;
height:170px;
background-color:blue;
}
<div id="myCalendar">
<!---HERE COME CALENDAR -->
</div>
<!-- make rotation-->
<button id='bnext' onclick='rotate();'>Rotation</button>
In your rotate method, which is called on click you need to make a change to see if the interval is defined and clear it if it is. See below code update.
var t; // interval
var x = 0 ; // counter
var cal ; // element to be rotate
function prepareRotatesX(){
x=x+5;
cal =document.getElementById("myCalendar");
cal.style.transform="rotateX("+x+"deg)";
if(x>360){ clearInterval(t); x=0;}
}
function rotate(){
if(t !== undefined) {
clearInterval(t);
}
t = setInterval(function(){
prepareRotatesX();
}, 10);
}
#myCalendar{
position: absolute;
top:45px;
left:20px;
border: 2px solid blue;
width: 210px;
height:170px;
background-color:blue;
}
<div id="myCalendar">
<!---HERE COME CALENDAR -->
</div>
<!-- make rotation-->
<button id='bnext' onclick='rotate();'>Rotation</button>
I have a JQuery function that makes a nav bar slide up or down as you scroll vertically. The idea is to always keep the navbar 20 pixels from the top of the client window. When the user scrolls up or down, the nav bar slides till it is back to 20 pixels from the top of the client window.
My Problem: It just wont bloody move lol. What have I done wrong?
Here is my JSFiddle with JQuery code: http://jsfiddle.net/wLga8/
Here is my code:
function moveDistanceEaseIn( /*HTML Element*/ ele, /*int|float*/ dist, /*Function*/ funct )
{
ele = $(ele);
var min = dist*0.01;
// kill an already running animation
if (ele.data("animInterval"))
clearInterval(ele.data("animInterval"));
var step = function()
{
if (dist <= min)
{
ele.data("animInterval", false);
clearInterval(interval);
return;
}
var stepMove = dist*0.1;
dist -= stepMove;
funct(ele, dist, stepMove);
};
var interval = setInterval(step, 30);
ele.data("animInterval", interval);
}
function moveToPointEaseIn( /*HTML Element*/ ele, /*int|float*/ curPoint, /*int|float*/ point, /*Function*/ funct, /*bool*/ signed )
{
ele = $(ele);
var dist = (signed == true) ? curPoint - point:Math.abs(curPoint - point);
moveDistanceEaseIn(ele, dist, funct);
}
$(document).ready(function()
{
$(window).scroll(function ()
{
var nav = $("#aa");
moveToPointEaseIn(nav, nav.position().top, $(window).scrollTop()+20, function(ele, dist, stepMove)
{
ele.css("top", ele.position().top+stepMove);
}, true);
});
});
And some example HTML:
<body style="height: 3000px;">
<div id="aa" style="position: absolute; left: 0px; top: 20px; width: 200px; height: 500px; background-color: red;"></div>
</body>
I'm not certain why your function isn't working. The fiddle wasn't set to use jquery, but even setting that has no effect.
However, this seems to do what you're after....
<body style="height: 3000px;">
<div id="aa" style="position: absolute; left: 0px; top: 20px; width: 200px; height: 500px; background-color: red;">
</div>
var $scrollingDiv = $("#aa");
$(window).scroll(function(){
$scrollingDiv.stop().animate({"marginTop": ($(window).scrollTop() + 0) + "px"}, 20 );
});
DEMO
Not sure if it will solve all of your problem, but these should at least get you up and running so you can debug your code further:
Add the jQuery library to your fiddle (missing in the one you posted)
The first time your step function runs, the values are negative: -100 and -1. This means your <= test will kill your animation on the first iteration
I hacked around this by changing this line:
if (dist <= min)
To this:
if (Math.abs(dist) <= Math.abs(min))
The animation still looks wrong, but at least it is animating :)
Here's the modified fiddle: http://jsfiddle.net/wLga8/4/