Height not increasing using setInterval (creating border around screen) - javascript

I'm trying to create a border that slowly wraps around the screen. As part of this process, I'm playing around with only increasing the height of the border right now by using the setInterval method. However, I can't get the border height to increase slowly. Below is what I'm doing:
var i = 1;
setBorder = setInterval(borderAnimation(), 200);
function borderAnimation() {
var border = document.getElementById("border-animation");
border.style.height = i + "vh";
i = i + 1;
document.write(i);
if(i = 100){
clearInterval(setBorder);
}
}
document.write(2);
If I change the variable i inside the function to say 5, then the height changes to that number so I know the function is being called at least once.
Similarly, document.write(i) prints only once. So if i is 1, then in the screen I see only 1; it also does not print 2 at any time even though I have document.write(2). Why is this?
After this, I intend to make it so that another div is called that goes around the top (this one is left), then another on the right then another around bottom, thus completing a border that goes around the screen. If someone has a better idea or way of achieving this, please let me know as well.

There are a couple mistakes:
1: pass the function reference (don't call the function) to setInterval
2: if(i = 100) should be if(i == 100)
var i = 1;
setBorder = setInterval(borderAnimation, 200);
function borderAnimation() {
var border = document.getElementById("border-animation");
border.style.height = i + "vh";
i = i + 1;
console.log(i);
if(i == 20){
clearInterval(setBorder);
}
}
#border-animation{
position: absolute;
width: 200px;
border: 1px solid #333;
}
<div id="border-animation"><div>

Related

Why isn't this document.getElementById() function working?

I want to get a div ball to move left using javascript and
document.getElementById("ball").style.left = i + "px";
This is the code that i'm using (below). I was thinking to use the while(true) {} loop, but it just crashed on me...
Does anyone know how to do/fix this??
JSFiddle
<script>
//while(true) {
var ballLeft = 250;
document.getElementById("ball").style.left = ballLeft;
ballLeft =-2;
// }
</script>
EDIT
The <script> tag is placed inside the <body>
EDIT 2
My issue is that the ball is not moving.
JavaScript is single-threaded (with some very specific exceptions that do not apply here). That single thread executes tasks one at a time, exclusively. Executing a script is one task. Repainting the browser is another; answering a click is yet another. If you run an infinite task (like a while (true) { ... }), the browser will never again have time to interact with you.
Make sure any infinite loop is broken up by frequent timeouts, or - even better, for an animation job - use window.requestAnimationFrame().
const ball = document.getElementById('ball');
let position = 250;
function tick(ts) {
ball.style.left = `${position}px`;
position -= 2;
if (position > 0) window.requestAnimationFrame(tick);
}
window.requestAnimationFrame(tick);
#ball {
position: absolute;
left: 250px;
top: 0;
}
<div id="ball">
🏀
</div>

Create a wiggle effect for a text

So what I want to happen is that when viewing the Span the text is normal but as you scroll down it starts moving until it looks like such:
Before the effect:
While the effect occurs:
The header is represented by spans for each letter. In the initial state, the top pixel value for each is 0. But the idea as mentioned is that that changes alongside the scroll value.
I wanted to keep track of the scroll position through JS and jQuery and then change the pixel value as needed. But that's what I have been having trouble with. Also making it smooth has been another issue.
Use the mathematical functions sine and cosine, for characters at even and odd indices respectively, as the graphs of the functions move up and down like waves. This will create a smooth effect:
cos(x) == 1 - sin(x), so in a sense, each character will be the "opposite" of the next one to create that scattered look:
function makeContainerWiggleOnScroll(container, speed = 0.01, distance = 4) {
let wiggle = function() {
// y-axis scroll value
var y = window.pageYOffset || document.body.scrollTop;
// make div pseudo-(position:fixed), because setting the position to fixed makes the letters overlap
container.style.marginTop = y + 'px';
for (var i = 0; i < container.children.length; i++) {
var span = container.children[i];
// margin-top = { amplitude of the sine/cosine function (to make it always positive) } + { the sine/cosine function (to make it move up and down }
// cos(x) = 1 - sin(x)
var trigFunc = i % 2 ? Math.cos : Math.sin;
span.style.marginTop = distance + distance * trigFunc(speed * y)/2 + 'px';
}
};
window.addEventListener('scroll', wiggle);
wiggle(); // init
}
makeContainerWiggleOnScroll(document.querySelector('h2'));
body {
height: 500px;
margin-top: 0;
}
span {
display: inline-block;
vertical-align: top;
}
<h2>
<span>H</span><span>e</span><span>a</span><span>d</span><span>e</span><span>r</span>
</h2>
Important styling note: the spans' display must be set to inline-block, so that margin-top works.
Something like this will be the core of your JS functionality:
window.addEventListener('scroll', function(e) {
var scrl = window.scrollY
// Changing the position of elements that we want to go up
document.querySelectorAll('.up').forEach(function(el){
el.style.top = - scrl/30 +'px';
});
// Changing the position of elements that we want to go down
document.querySelectorAll('.down').forEach(function(el){
el.style.top = scrl/30 +'px';
});
});
We're basically listening in on the scroll event, checking how much has the user scrolled and then act upon it by offsetting our spans (which i've classed as up & down)
JSBin Example
Something you can improve on yourself would be making sure that the letters wont go off the page when the user scrolls a lot.
You can do this with simple math calculation, taking in consideration the window's total height and using the current scrollY as a multiplier.
- As RokoC has pointed out there is room for performance improvements.Implement some debouncing or other kinds of limiters

Elements refuse to move - jQuery .css

Here I have an odd problem. I'm building a simple helicopter game (the old type - click to go up, avoid obstacles). My problem is that the obstacles generate, but don't position correctly, and then they won't move. I'm trying to move them with jQuery's css() - the css method works fine on anything else but when used with top and left doesn't.
The problem functions (generate and move obstacles):
game.background.generateObs = function() {
var top = Math.floor(Math.random()*game.canvas.height);
var left = game.canvas.width-10;
var $obs = $("<div></div>")
$obs.addClass("obs").appendTo("#canvas");
$obs.css({
background: "black",
position: "absolute",
height: game.obstacle.height,
width: game.obstacle.width,
});
$obs.css("top", $("#canvas").offset().top + top )
.css("left",$("#canvas").offset().left + left);
game.obstacle.width = Math.floor(Math.random()*200);
if(game.gameState=="running") {
setTimeout("game.background.generateObs()",obsInterval);
}
else {
return;
}
}
game.background.moveObs = function() {
var currentPos = $("#canvas div.obs").css("left");
var newPos = currentPos - game.obstacle.frameWidth;
$("#canvas div.obs").css("left",newPos);
if(game.gameState=="running") {
setTimeout("game.background.moveObs()",interval);
}
else {
return;
}
}
The other thing is that jsFiddle is now telling me that game is undefined, when I have defined it right at the start.
Can anyone tell me what I'm doing wrong? Here's the fiddle.
$("#canvas div.obs").css("left") is returning auto in your fiddle, not a number.
Try using .offset().left instead.
Additionally, you should change your setTimeout calls like this:
setTimeout(game.background.moveObs,interval);

Datatables fnFilter Delay loader/indicator

I am using datatables with a custom plugin I got from here fnSetFilteringDelay but wanted to add an indicator or loader of some sort to tell the user when the search will happen on the typed text in the filter textbox. I have done this but it is a bit buggy, maybe someone can help me to get this fluent and beautiful.
But if you type more and more, the indicator bar starts to look like it is shattering.
I would like to get rid of the shattering part if possible.
Here is my code after initialising the datatables to variable oTable
oTable.fnSetFilteringDelay(550); //After the last character is entered, will take 550 milliseconds to search
$('#gvProjectList_filter input').parent().append($("<div id='lder' style='width: 0px; height: 30px; background-color: #999; float:right;'></div>"));
$('#gvProjectList_filter input').on('keyup', function (a) {
document.getElementById("lder").style.width = "50px"; //Start the indicator at 50px and end at 0px
var count = 550; //Same as the filtering delay set above
var counter = setInterval(timer, 25); //will run it every 25 millisecond
function timer() {
count -= 25; //Minus 25 milliseconds
if (count <= 0) {
clearInterval(counter);
document.getElementById("lder").style.width = "0px";
return;
}
var neww = parseInt((count / 550) * 50); //calculate the new width vs. time left of 550ms
document.getElementById("lder").style.width = neww + "px";
}
});
Basically it must start at 50px width, and go down, when the user types another character, the bar must start at 50px again.
Here is my jsFiddle demo, just type something to search, first one letter and then a whole name, you will see what I mean.
I have found my own solution. I have made use of the jquery animate function
oTable.fnSetFilteringDelay(550);
$('#mytable_filter input').parent().append($("<div id='lder' style='width: 0px; height: 20px; background-color: #999; float:right;'></div>"));
$('#mytable_filter input').on('keyup', function (a) {
$("#lder").width('50px');
$("#lder").stop().animate({width:'0px'},550);
});
works like a charm!
Here is the final Fiddle, check it out!

overflow: hidden; image scrollBy

I had an idea for like a bus window as a fixed frame, about 800px wide, with a parallax city with the content on billboards spaced out so when you scroll between them it allows the parallax to look like bus is moving. The content will be much bigger than the window like a sprite and I'll put forward and back buttons that will scrollBy (x amount, 0). I have a working parallax script and a rough cityscape of 3 layers that all work fine.
I have hit a wall. I am trying to clear a scrollBy animation after it scrolls 1000px. Then you click it again and it goes another 1000px. This is my function.
function scrollForward() {
window.scrollBy(5,0);
scrollLoop = setInterval('scrollForward()',10);
}
So far I can only clear it when it gets to 1000. I tried doing 1000 || 2000 ect but after the first one it goes really fast and won't clear.
Excelsior https://stackoverflow.com/users/66580/majid-fouladpour wrote a great piece of code for someone else with a different question. It wasn't quite right for what the other guy wanted but it is perfect for me.
function scrollForward() {
var scrolledSoFar = 0;
var scrollStep = 75;
var scrollEnd = 1000;
var timerID = setInterval(function() {
window.scrollBy(scrollStep, 0);
scrolledSoFar += scrollStep;
if( scrolledSoFar >= scrollEnd ) clearInterval(timerID);
}, 10);
}
function scrollBack() {
var scrolledSoFar = 0;
var scrollStep = -75;
var scrollEnd = -1000;
var timerID = setInterval(function() {
window.scrollBy(scrollStep, 0);
scrolledSoFar += scrollStep;
if( scrolledSoFar <= scrollEnd ) clearInterval(timerID);
}, 10);
}
Now for step two figuring out how to put this content animation behind a frame.
Not quite sure what your asking here. Perhaps you could provide more relevant code?
I do see a potential issue with your code. You call setInterval('scrollForward()', 10) which will cause scrollForward to be called every 10ms. However, each of those calls to scrollForward will create more intervals to scrollForward creating a sort of explosion of recursion. You probably want to use setTimeout or create your interval outside of this function.
Also, as an aside you can change your code to simply: setInterval(scrollForward, 10). Removing the quotes and the parens makes it a littler easier to read and manager. You can even put complex, lambda functions like:
setInterval(function() {
scrollForward();
// do something else
}, 10);
edit:
So if you know that scrollForward moves the item 10px, and you want it to stop after it moves the item 1000px, then you simply need to stop it has moved that much. I still don't know how your code is actually structured, but it might look something like the following:
(function() {
var moved_by = 0;
var interval = null;
var scrollForward = function() {
// move by 10px
moved_by += 10;
if (moved_by === 1000 && interval !== null) {
clearInterval(interval);
}
};
var interval = setInterval(scrollForward, 10);
})();
If you want to clear it after 1000 or 2000, you simply adjust the if statement accordingly. I hope that helps.

Categories