animate elements in random sequence - javascript

I try to animate some buttons. A random string should be generated that the animated buttons arent always in the same sequence. fiddle
an example:
text = 1423
the first animated button is btn1 then after one second btn4 then after one second btn2 then after one second btn3
the buttons:
<div>
<button name="btn1" type="submit" id="btn1" value="1" style="" class="button"></button>
<button name="btn2" type="submit" id="btn2" value="2" style="" class="button"></button>
</div>
<div>
<button name="btn3" type="submit" id="btn3" value="3" style="" class="button"></button>
<button name="btn4" type="submit" id="btn4" value="4" style="" class="button"></button>
</div>
the javascript:
var textArray = [];
var text = "";
function makeid()
{
var possible = "1234";
for( var i=0; i < 4; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
makeid();
textArray = text.split("");
console.log(textArray);
function animate1() {
$('#btn' + textArray[0]).animate( { backgroundColor: 'red' }, 500);
}
function animate2() {
$('#btn' + textArray[1]).animate( { backgroundColor: 'red' }, 500);
}
function animate3() {
$('#btn' + textArray[2]).animate( { backgroundColor: 'red' }, 500);
}
function animate4() {
$('#btn' + textArray[3]).animate( { backgroundColor: 'red' }, 500);
}
window.setTimeout(animate1, 1000);
window.setTimeout(animate2, 2000);
window.setTimeout(animate3, 3000);
window.setTimeout(animate4, 4000);

Your issue about shuffling the possible text, because in your function there is a possibility that same number repeated. like: 2,2,2,1 or 4,4,4,4 and so on.
you can use this shuffle function instead of your method of shuffling:
function shuffleWord(word) {
var shuffledWord = '';
var charIndex = 0;
word = word.split('');
while (word.length > 0) {
charIndex = word.length * Math.random() << 0;
shuffledWord += word[charIndex];
word.splice(charIndex, 1);
}
return shuffledWord;
}
See JsFiddle of your example after updates.

You can't animate backgroundColor unless the jQuery.Color plugin is used, jQuery animate docs
All animated properties should be animated to a single numeric value,
except as noted below; most properties that are non-numeric cannot be
animated using basic jQuery functionality (For example, width, height,
or left can be animated but background-color cannot be, unless the
jQuery.Color plugin is used).
And you allow duplicate IDs when creating the random order. Also, the code can be simplified.
var textArray = [];
function makeid() {
var num;
var possible = "1234";
while(textArray.length < 4) {
num = possible.charAt(Math.floor(Math.random() * possible.length));
if (textArray.indexOf(num) === -1) {
textArray.push(num)
}
}
}
function animate(id, wait) {
setTimeout(function() {
$('#btn' + id).animate({ width: '200'}, 500);
}, wait);
}
makeid();
for (var i=0; i < textArray.length; i++) {
animate(textArray[i], i * 1000)
}
fiddle

Related

not able to use animation for typing game

I was trying to build a game, but I am not able to setInterval properly. The word is not getting printed on the screen when I click on the start game button, after 5seconds it directly shows GAME OVER.
var btn= document.querySelector('#btn');
btn.addEventListener("click", myMove);
function myMove() {
var word = document.querySelector('#word');
var input=document.querySelector('#written');
var words=['xylophone', 'cat', 'bat', 'chollima'];
var i=0;
var id = setInterval(frame, 5000);
function frame() {
word.innerHTML=words[i];
i = (i < 3) ?( i+1) : 0;
if (input.innerHTML== word.innerHTML) {
clearInterval(id);
} else {
word.innerHTML='GAME OVER';
}
}
}
<div id="heading">TYPING GAME</div>
<label>
<div id="word"></div>
<br>
<input type="text" id="written">
</label>
<button id="btn">START</button>
</body>
Actually, there are some issues with your current solution.
First of all, you are changing the word.innerHTML for the first time after the 5 second interval, so it will instantly get replaced by GAME OVER, so with a difference of some millisecond the innerHTML will be change and you won't be able to see the desired output.
Then you are using input.innerHTML for your condition where innerHTML only uses for HTML elements which are containing some content within them (got opening and closing tags) whilst for taking input value you should use input.value.
Thus, in order to make your code work, you should replace the innerHTML in the very first place before executing the setInterval. Then after calling the interval if the condition met you should increment the i value and then call your interval again recursively.
So your final code should be something like this:
var btn = document.querySelector('#btn');
btn.addEventListener("click", myMove);
function myMove() {
var word = document.querySelector('#word');
var input = document.querySelector('#written');
var words = ['xylophone', 'cat', 'bat', 'chollima'];
var i = 0;
word.innerHTML = words[i];
var id = setInterval(frame, 5000);
function frame() {
if (input.value == word.innerHTML) {
clearInterval(id);
i = (i < 3) ? (i + 1) : 0;
word.innerHTML = words[i];
id = setInterval(frame, 5000)
} else {
word.innerHTML = 'GAME OVER';
}
}
}
<div id="heading">TYPING GAME</div>
<label>
<div id="word"></div>
<br>
<input type="text" id="written">
</label>
<button id="btn">START</button>
Don't use input.innerHTML, use input.value instead:
var btn= document.querySelector('#btn');
btn.addEventListener("click", myMove);
function myMove() {
var word = document.querySelector('#word');
var input=document.querySelector('#written');
var words=['xylophone', 'cat', 'bat', 'chollima'];
var i=0;
var id = setInterval(frame, 5000);
function frame() {
word.innerHTML=words[i];
i = (i < 3) ?( i+1) : 0;
if (input.value == word.innerHTML) {
clearInterval(id);
} else {
word.innerHTML='GAME OVER';
}
}
}
<div id="heading">TYPING GAME</div>
<label>
<div id="word"></div>
<br>
<input type="text" id="written">
</label>
<button id="btn">START</button>
</body>

The image changes automatically - Start button

I wanted to add a button to start the change between images, to avoid the start of the change on its own
You must press the button until the change starts
var imageSources = ["https://www.w3schools.com/css/img_fjords.jpg", "https://www.w3schools.com/howto/img_mountains.jpg"]
var index = 0;
setInterval(function(){
if (index === imageSources.length) {
index = 0;
}
document.getElementById("image").src = imageSources[index];
index++;
}, 2000);
<img id="image" src="https://www.w3schools.com/css/img_fjords.jpg" style="width:300px">
Hi Please have a look I hope it's helpful Thanks
https://jsfiddle.net/sanat/xc5w8ngy/7/
<button id="start">
start
</button>
<button id="stop">
stop
</button>
<br>
<br>
<img id="image" src="https://www.w3schools.com/css/img_fjords.jpg" style="width:300px">
var myVar = '';
$(function(){
$("#start").on('click',function(){
var imageSources = ["https://www.w3schools.com/css/img_fjords.jpg", "https://www.w3schools.com/howto/img_mountains.jpg"]
var index = 0;
myVar = setInterval(function(){
if (index === imageSources.length) {
index = 0;
}
document.getElementById("image").src = imageSources[index];
index++;
}, 2000);
});
$("#stop").on('click',function(){
clearInterval(myVar);
});
});

use location.hash to keep page status in javascript

I am doing a practice that use location.hash to keep page's state, what i have done using the below code is
1.click any button, the button's innerHTML will be written into the div#cont
2.refresh the page, it keeps the changes in the div#cont
<body>
<button id="a">A</button>
<button id="b">B</button>
<button id="c">C</button>
<div id="cont"></div>
<script>
// var hashValue;
function getHash() {
var hashValue = location.hash;
return hashValue;
}
function draw() {
var cont = getHash();
if (cont) {
document.getElementById('cont').innerHTML = cont.slice(1);
}
}
btns = document.getElementsByTagName('button');
for (i = 0; i < btns.length; i++) {
btns[i].index = i;
btns[i].onclick = function() {
location.hash = btns[this.index].innerHTML;
}
}
window.onhashchange = function() {
draw();
}
draw();
</script>
</body>
And what i want to achieve next is add three other buttons(D,E,F) and a new div, when clicking one of the D\E\F, the innerHTMl will written into the new div.
The final goal is
click one of the A\B\C, the value will be written into 'contABC'
click one of the D\E\F, the value will be written into 'contDEF'
keep the changes when the page refresh
because this time it has to record two value, and i have no idea how to use hash to do that, anyone can help? Thanks in advance!
This is HTML:
<button id="a">A</button>
<button id="b">B</button>
<button id="c">C</button>
<button id="d">D</button>
<button id="e">E</button>
<button id="f">F</button>
<div id="contABC"></div>
<div id="contDEF"></div>
Try by structuring the way you store the hash value , like using a separator -
<body>
<button data-attr='ABC' id="a">A</button>
<button data-attr='ABC' id="b">B</button>
<button data-attr='ABC' id="c">C</button>
<button data-attr='DEF' id="d">D</button>
<button data-attr='DEF' id="e">E</button>
<button data-attr='DEF' id="f">F</button>
<div id="contABC"></div>
<div id="contDEF"></div>
<script>
// var hashValue;
function getHash() {
var hashValue = location.hash && location.hash.slice(1);
return hashValue && hashValue.split('-');
}
function draw() {
var cont = getHash();
if (cont && cont.length>0) {
document.getElementById('contABC').innerHTML = cont[0];
document.getElementById('contDEF').innerHTML = cont[1];
}
}
btns = document.getElementsByTagName('button');
var seperator = '-';
for (i = 0; i < btns.length; i++) {
btns[i].index = i;
btns[i].onclick = function() {
var cont = getHash() || [];
if(btns[this.index].dataset.attr=='ABC'){
location.hash = btns[this.index].innerHTML + seperator + cont[1];
}else{
location.hash = cont[0] + seperator + btns[this.index].innerHTML ;
}
}
}
window.onhashchange = function() {
draw();
}
draw();
</script>
</body>

How to beat a JavaScript condition riddle?

I am using a foreach loop in php to load data from a mysql table. I'm using the data ID's loaded from the data base and applying it to the button values.
The buttons come in two colors, green and white. The buttons represent likes for liking comments or posts.
The total existing number of likes starts at 6 (div id="total")
white buttons
If button 1 has color of white and you click it, total likes (6) will increase by 1. If you click button 1 again, total likes (7) will decrease by 1.
If button 1, button 2, and button three are clicked, total likes (6) increases by 3 ( 1 for each button). If button 1, button 2 and button 3 are clicked again, the total likes (9) will decrease by 3.
The Puzzle
Green buttons
How do I make it so, When a green button is clicked, the total (6) decrease by 1, and if the button is clicked again, it should increase by 1. Unlike white buttons.
If Green button 3, 5 and 6 are clicked, the total (6) should decease by 3. if the same buttons are clicked again, total (6) increases by 3.
Here is my code
var colorcode = "rgb(116, 204, 49)";
var buttonid = str;
var elem = document.getElementById(buttonid);
var theCSSprop = window.getComputedStyle(elem, null).getPropertyValue("background-color");
var initialtotal = parseInt(document.getElementById("total").innerHTML, 10);
var likes = new Array();
function showUser(str) {
////// 1st condition /////
if (theCSSprop == colorcode) {
if (likes[value] == 0 || !likes[value]) {
likes[value] = 1;
} else {
likes[value] = 0;
}
var sum = 0;
for (i = 0; i < likes.length; i++) {
if (likes[i] == 1) {
sum--
}
}
}
////// 2nd condition /////
else {
if (likes[str] == 0 || !likes[str]) {
likes[str] = 1;
} else {
likes[str] = 0;
}
var sum = 0;
for (i = 0; i < likes.length; i++) {
if (likes[i] == 1) {
sum++
}
}
}
var tot = initialtotal + sum;
document.getElementById("total").innerHTML = tot;
}
<div id="total" style="width:100px;padding:50px 0px; background-color:whitesmoke;text-align:center;">6 </div>
<!---------------------------------------------------------------------------------------------------------------------->
<button id="5" value="5" onclick="showUser(this.value)">LIKE </button>
<button id="346" value="346" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="128" value="128" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="687" value="687" onclick="showUser(this.value)">LIKE </button>
<button id="183" value="183" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="555" value="555" onclick="showUser(this.value)">LIKE </button>
<!---------------------------------------------------------------------------------------------------------------------->
Instead of passing this.value to showUser(), just pass this. That way, the function can get the value and the style directly, without having to call getElementById() (you're not passing the ID). Then you need to set theCSSprop inside the function, so it's the property of the current button.
To make green buttons alternate direction from increment to decrement, you need a global variable that remembers what it did the last time the function was called.
Also, you don't need to write if(likes[str] == 0 || !likes[str]), since 0 is faley. Just write if(!likes[str]).
var colorcode = "rgb(116, 204, 49)";
var likes = new Array();
var greenIncr = -1;
function showUser(elem) {
var initialtotal = parseInt(document.getElementById("total").innerHTML, 10);
////// 1st condition /////
var str = elem.value;
var theCSSprop = window.getComputedStyle(elem, null).getPropertyValue("background-color");
if (theCSSprop == colorcode) {
if (!likes[str]) {
likes[str] = 1;
} else {
likes[str] = 0;
}
var sum = 0;
for (i = 0; i < likes.length; i++) {
if (likes[i] == 1) {
sum += greenIncr;
}
}
greenIncr = -greenIncr; // revese the direction of green button
}
////// 2nd condition /////
else {
if (!likes[str]) {
likes[str] = 1;
} else {
likes[str] = 0;
}
var sum = 0;
for (i = 0; i < likes.length; i++) {
if (likes[i] == 1) {
sum++
}
}
}
var tot = initialtotal + sum;
document.getElementById("total").innerHTML = tot;
}
<div id="total" style="width:100px;padding:50px 0px; background-color:whitesmoke;text-align:center;">6 </div>
<!---------------------------------------------------------------------------------------------------------------------->
<button id="5" value="5" onclick="showUser(this)">LIKE </button>
<button id="346" value="346" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="128" value="128" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="687" value="687" onclick="showUser(this)">LIKE </button>
<button id="183" value="183" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="555" value="555" onclick="showUser(this)">LIKE </button>
<!---------------------------------------------------------------------------------------------------------------------->
First naive implementation can look like this
class Counter {
constructor(initial) {
this.initial = initial
this.white = [false, false, false]
this.green = [false, false, false]
}
changeGreen(index) {
this.green[index] = !this.green[index]
}
changeWhite(index) {
this.white[index] = !this.white[index]
}
get total() {
return this.initial + this.white.reduce((total, current) => total + current, 0) + this.green.reduce((total, current) => total - current, 0)
}
}
let counter = new Counter(6)
const render = counter => {
document.querySelector('#total').innerHTML = counter.total
}
render(counter)
;['#first', '#second', '#third'].map((selector, index) => {
document.querySelector(selector).addEventListener('click', e => {
e.target.classList.toggle('pressed')
counter.changeWhite(index)
render(counter)
})
})
;['#fourth', '#fifth', '#sixth'].map((selector, index) => {
document.querySelector(selector).addEventListener('click', e => {
e.target.classList.toggle('pressed')
counter.changeGreen(index)
render(counter)
})
})
.green {
background: #00aa00
}
.pressed {
border-style: inset
}
<div id="total">0</div>
<p>
<button id="first">First</button>
<button id="second">Second</button>
<button id="third">Third</button>
<button id="fourth" class="green">Fourth</button>
<button id="fifth" class="green">Fifth</button>
<button id="sixth" class="green">Sixth</button>
</p>
But after all I've finished with something like
class Counter {
constructor(initial, strategy) {
this.initial = initial;
this.elements = [];
this.strategy = typeof strategy === 'function' ? strategy : () => {}
}
addElement(content, type, next) {
const element = {
content: content,
type: type,
state: false
};
this.elements.push(element);
return next(element, this.elements.length - 1);
}
toggleElementState(index) {
this.elements[index].state = !this.elements[index].state
}
get total() {
return this.strategy(this.initial, this.elements)
}
}
const initialize = () => {
Counter.WHITE = Symbol('white');
Counter.GREEN = Symbol('green');
const counter = new Counter(6, (initial, buttons) => {
return initial +
buttons.filter(button => button.type === Counter.WHITE).reduce((total, current) => total + Number(current.state), 0) +
buttons.filter(button => button.type === Counter.GREEN).reduce((total, current) => total - Number(current.state), 0)
});
const render = counter => {
document.querySelector('#total').innerHTML = counter.total
};
const createButton = (element, index) => {
const button = document.createElement('button');
button.setAttribute('data-id', index);
button.classList.add(element.type === Counter.GREEN ? 'green' : 'none');
button.textContent = element.content;
document.querySelector('#buttons').appendChild(button)
};
const addButton = (type, ...selectors) => {
selectors.forEach(selector => counter.addElement(selector, type, createButton));
};
render(counter);
addButton(Counter.WHITE, '#first', '#second', '#third');
addButton(Counter.GREEN, '#fourth', '#fifth', '#sixth');
addButton(Counter.WHITE, '#first', '#second', '#third');
document.querySelector('#buttons').addEventListener('click', function(e) {
e.target.classList.toggle('pressed');
counter.toggleElementState(parseInt(e.target.dataset.id));
render(counter)
})
};
document.addEventListener('DOMContentLoaded', initialize);
.green {
background: #00aa00
}
.pressed {
border-style: inset
}
<div id="total">0</div>
<p id="buttons">
</p>

Rainbow Scrolling Text Using <span>

I would like to turn a small paragraph into rainbow text, in which the colors scroll from right to left in an infinite loop using JavaScript. I currently have this paragraph:
<div id="rainbow">
<p id="rtext">
<span id="s1" style="color: red">H</span>
<span id="s2" style="color: blue">e</span>
<span id="s3" style="color: green">l</span>
<span id="s4" style="color: purple">l</span>
<span id="s5" style="color: orange">o</span>
<span id="s6" style="color: magenta">!</span>
</p>
</div>
<div id="actbtn">
<button onclick="activ()">Click for RAINBOW!</button>
</div>`
I am fairly new to JavaScript so I am not sure how to write the activ() function to infinitely scroll the colors.
EDIT:
I would like to thank Ben for the looping script, but now I also need to know how to use the activ() function to change the color of a <span> element. I have tried the following script:
function activ() {
document.getElementById("s1").style.color = 'magenta';
}
But the color will not change. I am trying to keep the script as simple as possible, but also make it work.
FINAL EDIT:
I used Ivan's "UPD Without JQuery" code and added a few colors, and this is what I end up with:
<script>
function EyeVommit() {
document.getElementById("actbtn").style.display = 'none';
'use strict';
var colors = ['red', 'blue', 'green', 'purple', 'orange', 'magenta', 'chartreuse', 'cyan', 'yellow'],
target = document.getElementById('rtext').children,
i,
len = colors.length,
inter = setInterval(function() {
colors.unshift(colors.pop());
for (i = 0; i < len; i++) {
target[i].style.color = colors[i];
}
}, 200);
}
</script>
<div id="table1">
<p id="rtext"> <span id="s1">H</span><span id="s2">e</span><span id="s3">l</span><span id="s4">l</span><span id="s5">o</span><span id="s6">!</span>
<br />
<div id="actbtn">
<button onclick="EyeVommit()">Pabam!</button>
</div>
</p>
The result.
I'm begging you, never, never, never use it in design
<html>
<head>
<title>Price</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<script>
function EyeVommit() {
'use strict';
var colors = ['red', 'blue', 'green', 'purple', 'orange', 'magenta'],
$target = $('#rtext span'),
counter,
i,
len = colors.length,
inter;
for (i = 0; i < len; i++) {
$target[i] = $($target[i]);
}
inter = setInterval(function () {
colors.unshift(colors.pop());
for (i = 0; i < len; i++) {
$target[i].css('color', colors[i]);
}
}, 200);
}
</script>
<div id="table1">
<p id="rtext">
<span id="s1">H</span>
<span id="s2">e</span>
<span id="s3">l</span>
<span id="s4">l</span>
<span id="s5">o</span>
<span id="s6">!</span>
</p>
</div>
<script>
EyeVommit();
</script>
</body>
</html>
UPD without jQuery
<script>
function EyeVommit() {
'use strict';
var colors = ['red', 'blue', 'green', 'purple', 'orange', 'magenta'],
target = document.getElementById('rtext').children,
i,
len = colors.length,
inter = setInterval(function () {
colors.unshift(colors.pop());
for (i = 0; i < len; i++) {
target[i].style.color = colors[i];
}
}, 200);
}
</script>
<div id="table1">
<p id="rtext">
<span id="s1">H</span><span id="s2">e</span><span id="s3">l</span><span id="s4">l</span><span id="s5">o</span><span id="s6">!</span>
<button onclick="EyeVommit()">Pabam!</button>
</p>
</div>
If by "Infinitely scroll" you mean create an infinite loop, you could do this.
function blaah(blaah){
//This is where you put all of your rainbow-y code
blaah("blaah");
}
Then you can just call the event through your button.
This code works because everytime the function runs, you call it again. (Second-last line of the function.)
Here's one that will work for any text that you put in the rtext block
Here is a codepen: http://codepen.io/anon/pen/GtwxD
Here's the HTML
<div id="rainbow">
<p id="rtext">Hello! This is some rainbow text!</p>
</div>
<div id="actbtn">
<button>Click for RAINBOW!</button>
</div>
This is the Javascript
$(document).ready(function(){
createSpans();
$('#actbtn').click(activ);
});
$rtxt = $('#rtext');
var text = $rtxt.html() , color;
function createSpans(){
$rtxt.html(' ');
window.colorCount = 0;
window.on = false;
colorPicker();
}
function activ(){
if(!window.on){
window.id = setInterval(colorPicker,100);
window.on = true;
}
else{
clearInterval(window.id);
window.on = false;
}
}
function colorPicker(){
$rtxt.html(' ');
window.colorCount++;
for(var letter = 0; letter < text.length; letter++){
switch ((letter + colorCount) % 6){
case 0 :
color = "red";
break;
case 1 :
color = "orange";
break;
case 2:
color = "green";
break;
case 3 :
color = "purple";
break;
case 4 :
color = "blue";
break;
case 5 :
color = "gold";
break;
default :
color = "black";
break;
}
$rtxt.append('<span style=" color:' + color + ';">' + text[letter] + '</span>');
}
}

Categories

Resources