Im changing the page background of a from white to black following a sequence of 1 and 0. At the moment I manage to make it work were the black and white background changes with the same delay:
var syncinterval = setInterval(function(){
bytes = "10101010101010101010101010101010101010101010101010101010101010101";
bit = bytes[i];
output_bit(bit);
i += 1;
if (i > bytes.length) {
clearInterval(syncinterval);
i = 0;
for (i=0; i < input.length; i++) {
tbits = input[i].charCodeAt(0).toString(2);
while (tbits.length < 8) tbits = '0' + tbits;
bytes += tbits;
}
console.log(bytes);
}
}, sync_speed);
Complete working demo: http://jsfiddle.net/kn48Z/
How can I modify the function to make the white background last for sync_speed seconds and the black background for other any value?
If I'm understanding what you're trying to do, try placing your code into a separate function and use setTimeout. This will give you more control over what you're trying to accomplish.
I modified your code a bit. I check to see if bit is 1 (which I'm assuming is white), if it is, it will run backgroundOrSomething within sync_speed seconds. If it's not, it will run backgroundOrSomething within otherTime. I set otherTime to 1 second, just for giggles.
function backgroundOrSomething (){
bytes = "10101010101010101010101010101010101010101010101010101010101010101";
bit = bytes[i];
output_bit(bit);
i += 1;
if(i > bytes.length) {
i = 0;
for (i=0; i < input.length; i++) {
tbits = input[i].charCodeAt(0).toString(2);
while (tbits.length < 8) tbits = '0' + tbits;
bytes += tbits;
}
console.log(bytes);
}
otherTime = 1000;
if (bit == 1)
setTimeout(backgroundOrSomething, sync_speed);
else
setTimeout(backgroundOrSomething, otherTime);
}
setTimeout(backgroundOrSomething, sync_speed);
The last setTimeout at the bottom of the code will be the first to execute backgroundOrSomething.
As above you'll need to use a set interval as follows:
var bit = 0;
var syncInterval = setInterval(function() {
document.body.style.backgroundColor = bit == 0 ? 'black' : 'white';
bit = 1;
}, 3000);
var stopInterval = setTimeout(function() {
clearInterval(syncInterval);
}, 50000);
Fiddle here http://jsfiddle.net/kn48Z/4/. Note slowed down background switch so it should give a fit.
Related
Okay, so I have created this javascript text-animation that has a delay when writing text to
my p element "output". The animation works just fine...but I decided that I wanted to add text color to specific words in my "message" parameter. I made that happen by using this code:
function write(message,clear,delay) {
if(clear == true) clearMessage();
if(typeof delay != "number") delay = game.message.delay;
let q = undefined;
let output = document.getElementById("output");
let applyingColor = false;
let dest = output;
for(var i = 0 ; i < message.length ; i++) {
let cur = i;
let letter = message.charAt(i);
let wait = delay*i;
q = setTimeout(() => {
if(letter == "<") {
letter = "";
applyingColor = true;
let color = undefined;
let a = message.substring(cur+1,message.length);
let colorSig = a.substring(0,a.indexOf("/"));
color = colorSig;
let span = document.createElement("span");
span.style.color = color;
output.appendChild(span);
dest = span;
} else if(letter == ">") {
letter = "";
dest = output;
} else if(letter == "|") {
letter = "<br>";
}
if(applyingColor) {
if(letter != "/") {
return;
} else {
applyingColor = false;
return;
}
}
dest.innerHTML += letter;
},wait);
writingQueue.push(q);
}
}
the code above delays each character while also checking for very specific text such as
<rgb(255,0,0)/ this is red>. the "<" and the ">" are starting and ending signifiers for the colored text, while the "/" is used to mark where the end of the color goes. The text you want to be colored would go before ">" and after "/". and that makes it red! or any color you want. But I noticed a small detail. Whenever you use this, it creates an additional delay. For example if you did something like...
write("Hello, foo! My name is <red/ bar>!");
it would delay the "b" in "bar" longer than it would delay the "f" in "foo".
I think the problem is being caused by
if(applyingColor) {
if(letter != "/") {
return
} else {
applyingColor = false
return
}
}
at around the bottom body of the q = setTimeout(...).
What this code above does is skip over any letters that are not "/" while applyingColor is true, then turns it to false when it eventually reaches that wonderful little marker ("/") and returns one last time.
Honestly I dont know how to fix this. I've been working on this for hours now and my head hurts a lot. I could really use some help!
Oh! I forgot to mention. You can just ignore the "clear" and "delay" parameters. I do not believe they are relevant to my issue. The delay parameter is just the delay between each character. I have it to where it has a default value right now. And clear is just to clear previous text and clear out the writingQueue variable.
The problem in your current code is that as i increases over every iteration, so wait is being recalculated every check.. The first time it's 0 * delay, the second 1 * delay, the third 2 * delay. The solution while implementing only the current code would be to just define wait outside of the for loop.
buggy
let delay = 3;
for(var i = 0 ; i < 93 ; i++) {
let wait = delay * i;
}
let delay = 3;
let wait = 3 * 3;
for(var i = 0 ; i < 93 ; i++) {
}
good
However, there is an even better way to do javascript animations like the one you made, assuming you want them all to take the same amount of time (given your problem, as I understand it, is that the later letters are taking longer <?>) & you're making a webpage
window.requestAnimationFrame(function)
which will wait until the next frame to execute the code, making it always happen with the illusion of no delay to the user
suboptimal
q = setTimeout(() => if(letter == "<") {
/*...*/
faster, very rarely skips frames
q = window.requestAnimationFrame(() => if(letter == "<") {
/*...*/
if you want the letters to change all at once, you can just put the entire
for loop in a function and then call it using window.requestAnimationFrame(function).
window.requestAnimationFrame(colorIn);
function colorIn() {
for(var i = 0 ; i < message.length ; i++) {
let letter = message.charAt(i);
if(letter == "<") {
/*...*/
which will either make the letters changed all at once. if it can't, they'll change after dropping a few frames- though that should only happen if your computer has a virus or you change the color of an absolutely massive string
How do I change my code to start Blinking at the same time, and still be infinite?
function blink() {
if (!toggleSwitch) {
for (let i = 0; i < elements.length; i++) {
shapes.push(elements[i].className);
}
// Start off at the first element.
let i = 0;
let len = shapes.length;
// Do the next link
function doNext() {
let element = shapes[i];
i++;
eval(element).fillColor = eval(element).setColor;
document.getElementById(element).style.backgroundColor = (eval(element).fillColor === document.getElementById(element).style.backgroundColor) ? 'white' : eval(element).setColor;
if (i < len) {
// Don't do anything special
} else {
// Reset the counter
i = 0;
}
, myVar = setTimeout(doNext, 1000);
}
// And the code needs kicked off somewhere
doNext();
}
}
Also I can't toggle Classes because with a drag and drop I can change the background color any time during a running time so I have an object for each shape where I keep what color is the background. –
To have your page call your blink function after a certain pause first how about doing something like this?
<BODY onLoad="setTimeout('blink()', 5000);">
I have a circle, consisting of 12 arc segments and I want to allow the user to see the transition from the start pattern to the end pattern. (there will be many start and end patterns).
Here is my code so far:
http://codepen.io/blazerix/pen/jrwNAG
function playAnimations(){
var totalLength = document.getElementsByClassName("container")[0].children.length
for(var i = 0; i < totalLength; i++){
var current_pattern = document.getElementsByClassName("container")[0].children[i]
console.log(current_pattern)
for(var j = 0; j < 12; j++){
$('#LED' + (j+1) ).css('transition-duration', '0s');
$('#LED' + (j+1) ).css({fill: current_pattern.children[1].children[j].style.backgroundColor});
}
setTimeout(function () {
for(var k = 0; k < 12; k++){
$('#LED' + (k+1) ).css('transition-duration', "" + current_pattern.children[3].children[0].value + "ms");
$('#LED' + (k+1) ).css({fill: current_pattern.children[2].children[k].style.backgroundColor});
}
}, 150);
}
}
The outer for loop goes through all of the patterns, and the two inner for loops will go through the start and end pattern respectively. For some reason, my program only displays the animation of the very last pattern. I suspect this is because the code is executing really quickly - however I am unsure of how to fix this.
Does anyone know a good workaround or what I could possibly do to rectify this issue? Any feedback or help is appreciated.
Ok, not entirely understanding all the parts of your code, I've whipped this up. It doesn't work just yet, but you may get the idea of what I'm trying to do: wait 250 milliseconds before you fire off the next animation, once you run out of siblings, bounce to the other animation. I can't spend any more time on this, but I hope this gets you where you want to be:
function playAnimations() {
var $patternHolder = $(".container");
playAnimation($('#LED1'), 0, $patternHolder, 1, 1);
}
function playAnimation($target, index, $patternHolder, childPatternIndex, animationNumber) {
//just set both fill color and transition in the object you pass in:
//.eq() chooses a child, returns jQuery object of that child by index
//Use jQuery to get background-color style
$target.css({ fill: $patternHolder.children(childPatternIndex).children().eq(index).css("background-color"), transition: "0s" });
setTimeout(function () {
if ($target.parent().next().length > 0) {
playAnimation($target.parent().next(), index++);
} else if (animationNumber == 1) {
playAnimation($("#LED1"), 0, patternHolder, 3, 2);
}
}, 250);
}
My code is:
function slide(x)
{
if (x==undefined)
var x = 1;
if (x >= 4096)
return;
document.getElementById("slide").style.backgroundPosition = x + "px 0px";
x++;
setTimeout(function() {
slide(x);
}, 1);
}
JSFIDDLE
It makes a spin (?) by changing backgroundPosition, and it works. But it's too slow, I'd want to make it faster, and then gradually slow down. How can I do that?
You should pick a higher delay than 1ms. In most browsers 10 to 50 ms would be a lot more reliable. To speed up your animation though, increase x increments. For example:
function slide(x)
{
if(x==undefined) var x = 1;
if(x >= 4096) return;
document.getElementById("slide").style.backgroundPosition = x+"px 0px";
x += 10; // or some other value
setTimeout(function() {
slide(x);
}, 50); // or some other value
}
Also, you probably want to check x like this:
if (typeof x === 'undefined') { x = 1; }, no need for var.
2018 UPDATE:
Check out the https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame API. Using this over a fixed update interval is usually preferable.
I have rewrite all the function:
function slide() {
var x = 1;
var y = 30;
var clr = setInterval(function(){
if(x >= 4096) x = 1;
document.getElementById("slide").style.backgroundPosition = x+"px 0px";
x+=y;
y-=0.1;
if (y<=0) { clearInterval(clr); }
},10);
}
https://jsfiddle.net/tatrwkmh/4/
Currently the position is being changed by 1 pixel every time slide is called, via the line x++;. You can make it faster by changing this from x++ to x += 2 or x += 3 etc.
Your animation may look clunky without some sort of easing function, though. You should look into using some sort of animation library instead.
I got it nicely starting fast and then going slower by adding to your code the following:
if(x < 1000)
x+=2
else if(x < 1500)
x+=1.5
else
x++;
okay so i want if my counter reaches the maximum count, it starts over, with the default counter number which is 0 here is my code:
var picCount = 0; // global
var maxCount = 4;
//Pictures, to add more then 4 pics, add var picFive = "link to image here", var picSix ="bla", you get it.. add in picArray ,picFive and ,picSix
//To change the time delay, change it at the body onload and on the setTimeout
var picOne = "http://screenshots.nl.sftcdn.net/nl/scrn/3342000/3342167/modloader-for-minecraft-02-700x406.jpg"
var picTwo = "http://media.moddb.com/images/downloads/1/31/30912/minecraft_blox.png"
var picThree = "http://www.mupload.nl/img/rl6zeofbb.png"
var picFour = "http://www.mupload.nl/img/rl6zeofbb.png"
var picArray = [picOne, picTwo, picThree, picFour]
//
// gets next picture in array
function nextPic() { // check if adding 1 exceeds number of pics in array
if (picCount.length < maxCount.length) {
picCount = (picCount + 1 < picArray.length) ? picCount + 1 : 5000;
// build the image to write to page using the new pic reference
var build = '<img border="0" src="' + picArray[picCount] + '" width="649">\n';
document.getElementById("imgHolder").innerHTML = build;
// repeat this every 10 seconds.
setTimeout('nextPic()', 10 * 1000) //setTimeout is here
} else {
picCount = (picCount - maxCount < picArray.length) ? picCount + 1 : 5000;
// build the image to write to page using the new pic reference
var build = '<img border="0" src="' + picArray[picCount] + '" width="649">\n';
document.getElementById("imgHolder").innerHTML = build;
// repeat this every 10 seconds.
setTimeout('nextPic()', 10 * 1000) //setTimeout is here
}
}
okay so i hope you guys can help me with this..
That's a lot of messy code.
My fix for an implementation would probably look something like this:
var currentPic = 0;
var picOne = "http://screenshots.nl.sftcdn.net/nl/scrn/3342000/3342167/modloader-for-minecraft-02-700x406.jpg"
var picTwo = "http://media.moddb.com/images/downloads/1/31/30912/minecraft_blox.png"
var picThree = "http://www.mupload.nl/img/rl6zeofbb.png"
var picFour = "http://www.mupload.nl/img/rl6zeofbb.png"
var picArray= [picOne,picTwo,picThree,picFour]
function nextPic() {
if (currentPic < picArray.length) {currentPic++;}
else {currentPic = 0;}
var build='<img border="0" src="'+picArray[currentPic]+'" width="649">';
document.getElementById("imgHolder").innerHTML=build;
// repeat this every 10 seconds.
setTimeout('nextPic()',10 * 1000)//setTimeout is here
}
Despite many other issues which I am sure are present in your code, I believe this line is the cause of your particular problem addressed in the question:
if (picCount.length < maxCount.length) {
maxCount and picCount are just numbers. They do not have a length property. Change it to this:
if (picCount < maxCount) {
var currentPic = 0;
var picArray= ["http://screenshots.nl.sftcdn.net/nl/scrn/3342000/3342167/modloader-for-minecraft-02-700x406.jpg",
"http://media.moddb.com/images/downloads/1/31/30912/minecraft_blox.png",
"http://www.mupload.nl/img/rl6zeofbb.png",
"http://www.mupload.nl/img/rl6zeofbb.png"];
function nextPic() {
(currentPic < picArray.length) ? currentPic++ : currentPic = 0;
var build='<img border="0" src="'+picArray[currentPic]+'" width="649">';
document.getElementById("imgHolder").innerHTML=build;
}
setTimeout('nextPic()',10 * 1000);
I made a few changes that make your code cleaner.
Some tips:
No need to store your image URLs in vars before putting them in the array. Just initialize your array with them.
Don't repeat yourself. Whenever you find yourself using the exact same code in multiple places, you probably need to rethink how you are approaching the problem.
Look up the "ternary operator". In my opinion it makes simple conditional statements easier to read.
No need to use maxCount - the max count will be the length of your picArray.
Although not usually required, try to end all statements with a semicolon.
Don't mind the elitist attitude some people have, but at the same time, try to research as much as you can before asking a question.