How to make the browser paint? - javascript

suppose I have this client-side code:
var d=document.createElement('div');
d.style.position='absolute';
d.style.width='1em';
d.style.height='1em';
d.style.background='red';
document.body.appendChild(d);
for(var i=1e7;i;--i);
It creates a red square and counts down in a loop. Now I have to wait for the countdown to be ready before I see the red square. What is the best way to show the square before the countdown starts? I thought of executing the countdown after a Timeout:
setTimeout(function(){
for(var i=1e7;i;--i);
},1);
Or is there a better way? I do not want to rebuild my code into WebWorkers. Only a simple way to show a message before I start some time consuming linear code.
My real life situation is that I have a huge calculation that takes some time and I want to display a message before it starts.

If it's a large calculation it may lockup your browser, causing a very poor experience for your users. If that's the case, you may consider looking at doing the calculation in a webworker and posting the completed message back to the user.
http://www.html5rocks.com/en/tutorials/workers/basics/
More simply, you do something using setTimetout or setInterval and just have the message show by default: http://jsfiddle.net/ZHDY4/1/
We wait for the DOM to be ready, show the red box with the corresponding wait message.
$(document).ready(function() {
var n = 99;
$("#counter").html("Please Wait");
// Some long calculation; the red box is showing
var a = 0;
for(var i = 0; i < 99999; ++i) {
for(var j = 0; j < 9999; j++) {
a++;
}
}
var counter = setInterval(function() {
$("#counter").html(n);
n--;
if(n <= 0) {
clearInterval(counter);
}
}, 1000);
});

Related

How to make for loop happen every set amount of time?

I need to add "momentum" to an object on a grid. The player can control the object as long as he hold the key down, however, I want the ability to press the key one time and the object will keep going in the direction of the key until he hits the border. I have create a simple for loop that works, however because it happens so fast the object just kind of "teleports" to the border. I want the for loop to happen for example every second. Here is a short part of my code:
case "ArrowRight":
if (snakex + 1 == 26) {
temp += 1;
}
else {
for (let i = snakex; i < 26; i++) {
snakex += 1;
snake.style.gridArea = snakey + "/" + snakex;
}
}
break;
The game board is a 25x25 grid, if the fact that going to the right will result in going out of the board, the function will not do anything (temp is there for filling out a "fail mechanic" that I didn't add).
Without the for loop, the player needs to hold down the right key. This for loop makes it so the player needs to press it once, however it happens so fast it "teleports" like I said. Is it possible to make this loop happen every second, for example?
Any help would be appreciated. Thanks in advance!
you can control the speed of a loop by wrapping it in an async function, then you can write a custom function for sleep and await the sleep function at the beginning of every loop.
async function test() {
for(let i =0; i < 10; i++ {
await sleep(1000)
//logic goes here
}
}
function sleep(ms: number) {
return new Promise(r => setTimeout(r,ms))
}

HTML random value rapid test

I have this idea to prove a theory of mine.
So what I want to happen is when I run the program it will rapidly test a random chance. So, when I launched it it would rapidly test yes or no and there is a 1/1000000000 chance of "yes" and if it was yes, It would count one number up.
I browsed Stack Overflow and I found this:
<html>
<script>
// Greetings
var words = ['Hello', 'Hey', 'What\'s up!?'];
function randomAlert() {
// Index for picking the greeting you want to show
var alertIndex;
// Generates a number between 0 and 1
var randomValue = Math.random();
// 50% chance of 'Yes'
if (randomValue < 0.5) {
alertIndex = 0;
}
// 50% chance of 'No'
else if(randomValue < 0.5) {
alertIndex = 1;
}
alert(words[alertIndex])
}
</script>
<button onClick="randomAlert()">Click me!</button>
</html>
But what happens is it makes the button and does what I want (does not work in stack overflow and i'm not sure why. It works when I run it as a file on my comp), but it does not count every time it comes out as "yes" and it has to be done manually. (That is why I have to make the chances so large)
I just read what I wrote and it sounds like I'm asking for a favor rather than asking to learn how to code it. Please, do not take this as a "job". I would like what functions to use to make a random value and rapidly test it. THNX
If you want to do more than 1 draw, then you'll need a loop.
A for is the simplest, a while is also possible.
Also you'll need to have counters for each 'low or high' outcome.
I have made those changes, with a slightly different chance setting to keep it from running forever, with this result:
<script type="text/javascript">
function randomCount() {
var countLow = 0;
var countHigh = 0;
var cutOff = 1 / 1000;
var totalTries = 10000;
for (var i = 0; i < totalTries; i++) {
var randomValue = Math.random();
if (randomValue < cutOff)
countLow++;
else
countHigh++;
}
console.log("Result: countLow = " + countLow + ", countHigh = " + countHigh + ".");
}
</script>
<button onClick="randomCount()">Click me!</button>

How to make the alert pop up after the spin results?

I'm making a very each game for school project, it should works like this:
User click spin, 3 cards will display elements
If all 3 cards matches, the balance will add $50, and pop up alert "you won!"
Otherwise, it will subtract $10 for each spin doesn't match.
If the balance fall below $10, pop up alert "you have less than $10.
I'm trying to make the alert pop up after the slots rendered and balance updated, however the alert always pop up ahead. Any idea how to fix it?
let slotsContainer = document.getElementById('slots');
let balanceContainer = document.getElementById("balance-container");
let tries = document.getElementById("tries");
const INITIAL_AMOUNT = 1000;
let values = ['❤', '🌞', '👻'];
let number_of_spinners = 3;
let spinCount = 0;
let slot_els = [];
let balance = INITIAL_AMOUNT;
balanceContainer.innerHTML = balance;
function render(result) {
slotsContainer.innerHTML = '';
for (var i = 0; i < number_of_spinners; i++) {
let spinner = document.createElement('div');
spinner.innerHTML = result[i];
slotsContainer.appendChild(spinner);
slot_els.push(spinner);
}
}
render(['?', '?', '?'])
function getOneRandomNumber() {
return Math.floor(Math.random() * values.length);
}
function spin_func() {
let firstRandomValue = getOneRandomNumber();
let secondRandomValue = getOneRandomNumber();
let thirdRandomValue = getOneRandomNumber();
render([values[firstRandomValue], values[secondRandomValue], values[thirdRandomValue]]);
if ((firstRandomValue === secondRandomValue) && (secondRandomValue === thirdRandomValue)) {
balance += 50;
balanceContainer.innerHTML = balance;
alert("you won!");
} else {
if (balance >= 10) {
balance -= 10;
balanceContainer.innerHTML = balance;
} else {
alert("You have less than $10");
}
}
console.log('spin!!!');
}
let spin_button = document.getElementById('spin');
spin_button.onclick = spin_func
The DOM is rendered asynchronously so you need to trigger the alert asynchronously.
Try replacing alert("xyz"); with setTimeout(alert, 0, "xyz"); where you are using it.
If you want the player to have time to read the result before triggering the alert, just increase the delay expressed in milliseconds from 0 to 2000 (2 seconds).
Ok. This is because the JS code runs so fast it spins but you don't see it.
This code
for (var i = 0; i < number_of_spinners; i++) {
let spinner = document.createElement('div');
spinner.innerHTML = result[i];
slotsContainer.appendChild(spinner);
slot_els.push(spinner);
}
Would need to be slowed down using a delay. The delay would need to be say 1/4 of a second per animation. Then the code would allow you to see it. Afterwhich the alert would fire and it would work as expected.
The problem here now is that you would need to make the code asynchronous.
Otherwise it still will not work.
Here is a Question of SO re a loop with a delay
How do I add a delay in a JavaScript loop?
You need to make this call your alert (finish) code when the loop completes otherwise, it still won't work.
The principle is:
run a loop that fires the animation
delay the next iteration by the animation speed say 600ms
call the alert/end code when the loop completes

Issue with EaselJS

I developing TD game with EaselJS and faced with one problem.
When enemy come to castle he should should to start attack it with uniq delay.(for example witch:3 seconds, elemental:2 seconds e.t.c.)
How to set this delay with enabled ticker?
createjs.Ticker.on("tick", moveTick);
createjs.Ticker.setFPS(20);
console.log(mobs);
function moveTick(event) {
for (var i = 0; i < mobs.length; i++) {
if (mobs[i].y > stage.canvas.height - castle.castleHeight - mobs[i].elemSize) {
setTimeout(console.log("attacking"), 600000);
} else {
mobs[i].y = mobs[i].y + mobs[i].movementSpeed;
}
}
field.update(event);
}
Since you know how many seconds you want to have something wait before performing an action, and you know how many frames per second your program will run at, what you can do is count frames before performing an action.
A good way to count the frames would be to maintain a tick counter, and decrement the counter any time it is a positive number, and then performing an action once the counter hits 0. Here is a code example partially making use of your code of how this might work:
createjs.Ticker.on("tick", moveTick);
createjs.Ticker.setFPS(20);
console.log(mobs);
// note that enemy_ticker would probably be a property of your enemy object:
var enemy_ticker = -1;
function moveTick(event) {
if (event that causes enemy to attack soon) {
enemy_ticker = 60; // this gives us 3 seconds
}
if (enemy_ticker > 0) {
enemy_ticker--;
} else if (enemy_ticker = 0) {
enemy_ticker--;
// put your code to start your enemy's attack here
}
field.update(event);
}

Javascript pause in WinRT for animation

I want to pause execution in javascript so that I can animate the appearance of text on the screen. My code is currently this:
function AnimateWord(word) {
for (var i = 0; i <= word.length; i++) {
myTest.textContent += word.charAt(i);
// need to pause here and then continue
}
}
I've done some research and the preferred method to do this in javascript seems to be setTimeout, although I can't really see how that would work in this case without creating a recursive loop (which just doesn't seem like the right solution to me).
Is there a way around this, or am I stuck with setTimeout and a recursive loop?
EDIT:
Based on some additional tests, I've tried using the Promise.timeout:
for (var i = 0; i <= word.length; i++) {
WinJS.Promise.timeout(1000).then(TypeLetter(word.charAt(i)));
}
function TypeLetter(letter) {
myTest.textContent += letter;
}
But this doesn't seem to actually pause. In fact, it seems to completely ignore the timeout. I've also tried:
setTimeout(TypeLetter(word.charAt(i)), 1000);
With basically the same results. this page seems to imply that it should wait and then execute the task. I'm quite new to WinJS, but am equating a promise to an await keyword in C#.
setTimeout/setIngerval/requestAnimationFrame are pretty much your only choices. I wouldn't call them recursive perse - while you do call your same function over & over. The calls tack is completely independent.
What kind of animation are you really trying to create? It may be better to create a span for each character, have them hidden, and then fade/translate the, in using CSS animations.
var i = 0;
var str = "plz send teh codez";
var intervalId = setInterval(function(){
myTest.textContent += str.charAt(i);
if (++i >= str.length)
clearInterval(intervalId);
}, 1000);
demo http://jsfiddle.net/qxfVu/1/
Does this do what you are looking for:
var array1 = [];
function AnimateWord(word) {
var test = $('#test');
for (var i = 0; i <= word.length; i++) {
array1.push(word.charAt(i));
test.delay(100).queue(function() {
this.innerHTML += array1[0];
array1.splice(0, 1);
$(this).dequeue();
});
}
}
please see fiddle link as well: http://jsfiddle.net/7Ea9u/

Categories

Resources