Why is cancelAnimationFrame not working? - javascript

Refer to this fiddle - http://jsfiddle.net/rnqLfz14/28/
[ This code is not mine - http://www.isaacsukin.com/news/2015/01/detailed-explanation-javascript-game-loops-and-timing ]
//....
function stop() {
running = false;
started = false;
cancelAnimationFrame(frameID);
}
//...
function mainLoop(timestamp) {
// Throttle the frame rate.
if (timestamp < lastFrameTimeMs + (1000 / maxFPS)) {
frameID = requestAnimationFrame(mainLoop);
return;
}
delta += timestamp - lastFrameTimeMs;
lastFrameTimeMs = timestamp;
begin(timestamp, delta);
if (timestamp > lastFpsUpdate + 1000) {
fps = 0.25 * framesThisSecond + 0.75 * fps;
lastFpsUpdate = timestamp;
framesThisSecond = 0;
}
framesThisSecond++;
var numUpdateSteps = 0;
while (delta >= timestep) {
update(timestep);
delta -= timestep;
if (++numUpdateSteps >= 240) {
panic();
break;
}
}
draw(delta / timestep);
T.textContent = timestamp;
if (timestamp >= 6000.0) {
T.textContent = "Stopped!";
stop();
}
end(fps);
frameID = requestAnimationFrame(mainLoop);
}
//...
The cancelAnimationFrame function is not stopping the animating loop. Got any suggestions? I have scratched my head over it for a long time now please any suggestions would be appreciated.

When the condition for stop() is fulfilled, stop() is called but the code continues so a new rAF will be requested.
Just add a return after the stop call to prevent this from happening (or use an else):
...
if (timestamp >= 6000.0) {
T.textContent = "Stopped!";
stop(); // stop() is just a sub-routine here and will continue after being called
return; // <--- here
}
...
Modified fiddle

Related

Button for smooth scrolling

I am doing a button for smooth scrolling to the bottom of the page. The button is working, but without the smooth animation. Does someone have an idea, what I am doing wrong? The same kind of code for button to top is working fine. I need to do this without CSS "smooth".
document.getElementById("buttondown").onclick = function() {
scrollTo(5555550, 2000);
}
// Element or Position to move + Time in ms (milliseconds)
function scrollTo(element, duration) {
var rootelement = document.documentElement;
if (rootelement.scrollTop === 0) {
var up = rootelement.scrollTop;
++rootelement.scrollTop;
rootelement = up + 1 === rootelement.scrollTop-- ? rootelement : document.body;
}
scrollToC(rootelement, rootelement.scrollTop, element, duration);
}
// Element to move, element or px from, element or px to, time in ms to animate
function scrollToC(element, from, to, duration) {
if (duration <= 0) return;
if (typeof from === "object") from = from.offsetTop;
if (typeof to === "object") to = to.offsetTop;
scrollToX(element, from, to, 0, 1 / duration, 20, easeOutCuaic);
}
function scrollToX(element, xFrom, xTo, t01, speed, step, motion) {
if (t01 < 0 || t01 > 1 || speed <= 0) {
element.scrollTop = xTo;
return;
}
element.scrollTop = xFrom - (xFrom - xTo) * motion(t01);
t01 += speed * step;
debugger;
setTimeout(function() {
scrollToX(element, xFrom, xTo, t01, speed, step, motion);
}, step);
}
function easeOutCuaic(t) {
t--;
return t * t * t + 1;
}
You can add smooth behaviour to the function:
document.getElementById("buttondown").onclick = function() {
window.scrollTo({
top: 100,
left: 100,
behavior: 'smooth'
});
}

By using HTML5 canvas, how to create infinite loop with time interval

I want to keep updating my image position with HTML5 canvas. I tried the following javascript code to do the work
window.onload = function start() {
update();
}
function update() {
document.getElementById('scoreband').innerHTML = score;
var style = document.getElementById('bug').style;
timmer = window.setInterval(function () {
style.left = ((Math.random() * 100) + 1) + "%";
style.top = ((Math.random() * 100) + 19) + "%";
}, num);
}
But this is not working when it comes to HTML5 canvas. Is there similar way to do the same job in HTML5 canvas?
To change any visual DOM content you should use requestAmimationFrame
Eg
function update(time){
// time is in ms and has a 1/1000000 second accuracy
// code that changes some content, like the canvas
requestAnimationFrame(update); // requests the next frame in 1/60th second
}
And to start it
requestAnimationFrame(update);
As requested
indow.onload = function start() {
requestAnimationFrame(update);
}
function update() {
document.getElementById('scoreband').innerHTML = score;
var style = document.getElementById('bug').style;
style.left = ((Math.random() * 100) + 1) + "%";
style.top = ((Math.random() * 100) + 19) + "%";
requestAnimationFrame(update);
}
Though it’s not as good as requestAnimationFrame, setInterval’s frame rate can be dynamic.
//supposing num is defined lol
var timer = setInterval(update, num);
function update() {
document.getElementById('scoreband').innerHTML = score;
var style = document.getElementById('bug').style;
style.left = ((Math.random() * 100) + 1) + "%";
style.top = ((Math.random() * 100) + 19) + "%";
}

Scroll and run a code when section is visible ( pure Javascript )

function animateValue(id, start, end, duration) {
var range = end - start;
var current = start;
var increment = end > start? 1 : -1;
var stepTime = Math.abs(Math.floor(duration / range));
var obj = document.getElementById(id);
var timer = setInterval(function() {
current += increment;
obj.innerHTML = current;
if (current == end) {
clearInterval(timer);
}
}, stepTime);
}
animateValue("num1", 0, 75, 10000);
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
if(scrollTop > 400){
animateValue("num2", 0, 75, 10000);
}
.box{
height:500px;
}
<h1 id="num1">75</h1>
<div class="box"></div>
<h1 id="num2">75</h1>
I need to run the number from 0 to 75 on id="num2", like id="num1" is working. But I need id="num2" running after page is scrolled down there. And its a challenge because I can't use any library like Jquery, angular JS etc. I need it using pure JavaScript.
I added some events for scrolling and resizing (both can "show" the target element). We don't need the scrolling position when using .getBoundingClientRect(), because it shows us the targets top position depending on the scroll position.
https://jsfiddle.net/q8ww67tj/
function animateValue(id, start, end, duration) {
var range = end - start;
var current = start;
var increment = end > start? 1 : -1;
var stepTime = Math.abs(Math.floor(duration / range));
var obj = document.getElementById(id);
var timer = setInterval(function() {
current += increment;
obj.innerHTML = current;
if (current == end) {
clearInterval(timer);
}
}, stepTime);
}
animateValue("num1", 0, 75, 10000);
triggered = false;
window.addEventListener('load', recalculate);
window.addEventListener('scroll', recalculate);
window.addEventListener('resize', recalculate);
function recalculate() {
var height = document.body.clientHeight,
targetRect = document.getElementById('num2').getBoundingClientRect();
targetY = targetRect['top'],
targetHeight = targetRect['height'];
if (targetY + targetHeight < height) {
if (!triggered) {
triggered = true;
animateValue("num2", 0, 75, 10000);
}
}
}
.box {
height: 1000px;
}
<h1 id="num1">75</h1>
<div class="box"></div>
<h1 id="num2">75</h1>

Code a jump like in the game 'Winterbells'

How would one go about coding a jump like in this game? I've got some working code already (made in Adobe Edge) but the way it's programmed it won't start another jump while mid-air. This is what I've got atm:
var velocityY = 0;
var gravity = 0.5;
var onGround = false;
var fps = 60;
function StartJump()
{
if(onGround)
{
velocityY = -13.0;
onGround = false;
}
}
function EndJump()
{
if(velocityY < -6,0)
velocityY = -6,0;
}
var positionY = sym.$("ball").position().left;
Loop();
function Loop()
{
Update();
setTimeout(Loop, 1000/fps);
}
function Update()
{
velocityY += gravity;
positionY += velocityY;
if(positionY > 730)
{
positionY = 730;
velocityY = 0;
onGround = true;
}
sym.$("ball").css("top", positionY + "px");
console.log(velocityY);
}
The top value 730 is where "ball" starts on the ground. StartJump() is called on the event 'mousedown' and EndJump() on 'mouseup'. I can't figure out how to change the code so I can make it jump while mid-air (as in when it collides with sth, like how in the game the bunny hits the bell).

How do I change my interval within the function itself?

So, this is the code I'm using to set my interval which triggers draw() every 0.1s
var intervalTime = 100;
setInterval(draw, intervalTime);
function draw() {
if( i == 1 ) intervalTime = 50;
}
I want to know how I can change that intervalTime to 50 when i becomes 1. The code above doesn't seem to work like that. It stays at an interval time of 0.1s
var intervalTime = 100;
var interval = setInterval(draw, intervalTime);
function draw() {
if( i == 1 ) {
clearInterval(interval);
interval = setInterval(draw, intervalTime);
}
}

Categories