I have following 4 bulbs:
<div id="bulb1" class="lightbulb"><img src=".\images\bulb.png" /></div>
<div id="bulb2" class="lightbulb"><img src=".\images\bulb.png" /></div>
<div id="bulb3" class="lightbulb"><img src=".\images\bulb.png" /></div>
<div id="bulb4" class="lightbulb"><img src=".\images\bulb.png" /></div>
My requirement is somewhat strange, but yes I have to do it...I have to do this in javascript.
I have an array which has 4 elements {1, 2, 3, 4}. Initially all bulbs(images) will be invisible.
First, I have to select on element from this array randomly. Suppose 2 is selected, then 2nd bulb will lighten up.
Then after 500 milliseconds, again my random function generator picks 4, then 4th bulb image is shown and 2nd is again invisible.
This I have to do 4 times in such a way that each time unique bulb gets lighten up. What approach and structure should I follow?
I am fused all the bulbs at beginning by calling this function
function hideBulbImages()
{
document.getElementById('bulb1').style.visibility = "hidden";
document.getElementById('bulb2').style.visibility = "hidden";
document.getElementById('bulb3').style.visibility = "hidden";
document.getElementById('bulb4').style.visibility = "hidden";
}
I am thinking of the function showBulbImage...
I have written showBulbImage to show the bulb sequentially after every second like this
function showBulbImages()
{
var blink_count = 0;
var blink_the_bulbs = setInterval(function() {
blink_count+=1;
hideBulbImages();
var blinking_bulb = "bulb" + blink_count;
document.getElementById(blinking_bulb).style.visibility = "visible";
if (blink_count > 4)
{
clearInterval(blink_the_bulbs);
}
}, 1000);
}
Now I have to randomize the visibility of bulbs.
Use setInterval() and Math.random()
function get_random_bulb() gets a random number, hides visible image first and then shows random image.
js:
$(document).ready(function () {
get_random_bulb();
function get_random_bulb() {
var a = (parseInt(Math.random() * 4));
$(".lightbulb img.block").removeClass("block").addClass("none");
$(".lightbulb:eq(" + a + ") img").removeClass("none").addClass("block");
}
setInterval(function () {
get_random_bulb();
}, 500);
});
<div id="bulb1" class="lightbulb">
<img src=".\images\bulb.png" class="none" />
</div>
<div id="bulb2" class="lightbulb">
<img src=".\images\bulb.png" class="none" />
</div>
<div id="bulb3" class="lightbulb">
<img src=".\images\bulb.png" class="none" />
</div>
<div id="bulb4" class="lightbulb">
<img src=".\images\bulb.png" class="none" />
</div>
Here is the fiddle.
With the help of Hiral and some more googling I implemented my functionality. Below is my final showBulbImage function
function showBulbImages()
{
var blink_count = 0;
var myArray = ['1', '2', '3', '4'];
var randomArray = shuffleArray(myArray)
var blink_the_bulbs = setInterval(function() {
var blinking_bulb = "bulb" + randomArray[blink_count];
document.getElementById(blinking_bulb).style.visibility = "visible";
blink_count+=1;
if (blink_count > 3)
{
clearInterval(blink_the_bulbs);
}
}, 1000);
}
function shuffleArray(array)
{
for (var i = array.length - 1; i > 0; i--)
{
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
Related
I have created a website for a friend which includes a slideshow with his most recent Instagram posts. The slideshow has a right and left arrow cursor.
The right cursor is working how I want it to; it shows each image from the array upon each click, and keeps going regardless of how many times the user clicks the right cursor. When it reaches the last image in the array, it starts at the first image again due to an if statement put in place.
However, I am having trouble with the left cursor and I suspect it is the counter variable? With the current code, what happens is when I click the left cursor (with the page refreshed and without even clicking on the right cursor), it goes to the second image in the array index1, rather than the last. Then I click the left cursor again without any change happening, then when I click it the third time it goes to the last image in the array and works as it should until it reaches the second image in the array again - because after that it does not go to the first image, it skips the first image after another click of nothing happening and then goes to the last image in the array. Repeats itself in that manner (sorry for going so in-detail, but I want people to get an idea of whats happening here if the code doesn't help).
var sliderImages = [];
var counter = 1;
sliderImages[0] = "images/i1.png";
sliderImages[1] = "images/i2.png";
sliderImages[2] = "images/i3.png";
sliderImages[3] = "images/i4.png";
sliderImages[4] = "images/i5.png";
$("#right-arrow").click(function() {
$(".active").attr("src", sliderImages[counter]);
counter++;
$('#count').text(counter);
if (counter >= sliderImages.length) {
counter = 0;
}
});
$("#left-arrow").click(function() {
$(".active").attr("src", sliderImages[counter]);
counter--;
if (counter <= 0) {
counter = sliderImages.length
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="instagram-feed">
<div class="container">
<h2>INSTAGRAM GALLERY</h2>
<div class="insta-gallery">
<img src="images/left-arrow.png" class="arrow" id="left-arrow">
<img src="images/i1.png" class="active">
<img src="images/right-arrow.png" class="arrow" id="right-arrow">
</div>
</div>
<div class="clear"></div>
</section>
When your page loads, you set counter to 1. When you click the left-arrow button, the first thing you do is set the image to the counter value, and so you set the image to 1. (Remember, arrays are 0-indexed, meaning 1 refers to the second item).
You'd be better off if counter was referring to the current image, not trying to assume the upcoming one. See my comments in the modified code below for more information.
var sliderImages = [];
var counter = 0; //Start with first image instead of second
sliderImages[0] = "images/i1.png";
sliderImages[1] = "images/i2.png";
sliderImages[2] = "images/i3.png";
sliderImages[3] = "images/i4.png";
sliderImages[4] = "images/i5.png";
$("#right-arrow").click(function() {
counter++; //Moving forward by one
if (counter > sliderImages.length-1) counter = 0; //Wrap-around if we exceed length-1
$(".active").attr("src", sliderImages[counter]); //Update img src
});
$("#left-arrow").click(function() {
counter--; //Moving backward by one
if (counter < 0) counter = sliderImages.length-1; //Wrap-around if negative
$(".active").attr("src", sliderImages[counter]); //Update img src
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="instagram-feed">
<div class="container">
<h2>INSTAGRAM GALLERY</h2>
<div class="insta-gallery">
<img src="images/left-arrow.png" class="arrow" id="left-arrow">
<img src="http://via.placeholder.com/350x150" class="active">
<img src="images/right-arrow.png" class="arrow" id="right-arrow">
</div>
</div>
<div class="clear"></div>
</section>
Use a counter as if you're handling indexes, so set it initially at 0.
Here's the basic logic:
var sliderImages = [
"//placehold.it/100x100/0bf?text=O",
"//placehold.it/100x100/f0b?text=1",
"//placehold.it/100x100/0fb?text=2",
"//placehold.it/100x100/fb0?text=3",
"//placehold.it/100x100/b0f?text=4"
];
var n = sliderImages.length; // Total slides
var c = 0; // Counter
function anim () {
$("#mainImage").attr("src", sliderImages[c]);
}
$("#prev").on("click", function() {
--c; // Pre-decrement
if ( c < 0 ) { c = n-1; } // If lower than 0 - go to last slide
anim(); // animate
});
$("#next").on("click", function() {
++c; // Pre-increment
if ( c > n-1 ) { c = 0; } // If greater than num of slides - go to first slide
anim(); // animate
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="mainImage" src="//placehold.it/100x100/0bf?text=O">
<br>
<button id="prev">←</button>
<button id="next">→</button>
<span id="count"></span>
Or here's a neater extracted formula of the above:
var sliderImages = [
"//placehold.it/100x100/0bf?text=O",
"//placehold.it/100x100/f0b?text=1",
"//placehold.it/100x100/0fb?text=2",
"//placehold.it/100x100/fb0?text=3",
"//placehold.it/100x100/b0f?text=4"
];
var n = sliderImages.length; // Total slides
var c = 0; // Counter
function anim () {
c = c<0 ? n-1 : c%n; // Fix counter
$("#mainImage").attr("src", sliderImages[c]); // Animate (or whatever)
}
$("#prev, #next").on("click", function() {
c = this.id==="next" ? ++c : --c; // Increement or decrement
anim(); // Animate
});
// If you have bullets than you can simply do like:
$(".bullet").on("click", function() {
c = $(this).index();
anim();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="mainImage" src="//placehold.it/100x100/0bf?text=O">
<br>
<button id="prev">←</button>
<button id="next">→</button>
<span id="count"></span>
Updated your code a bit :
var sliderImages = [];
var counter = 0;
sliderImages[0] = "images/i1.png";
sliderImages[1] = "images/i2.png";
sliderImages[2] = "images/i3.png";
sliderImages[3] = "images/i4.png";
sliderImages[4] = "images/i5.png";
$("#right-arrow").click(function() {
counter++;
$(".active").attr("src", sliderImages[counter]);
$('#count').text(counter);
if (counter >= sliderImages.length) {
counter = 0;
}
});
$("#left-arrow").click(function() {
counter--;
$(".active").attr("src", sliderImages[counter]);
if (counter <= 0) {
counter = sliderImages.length - 1;
}
});
var n=0;
var images=["FullSizeRender (1).jpg","IMG_1875.JPG","IMG_4665.JPG","IMG_5213.JPG"];
$(document).ready(function() {
// Change image
$("#himg").click(function(){
n++;
if(n==images.length){
n=0;
};
document.getElementById("himg").src=images[n];
$("#himg").find('img[src="' + images[n] + '"]').fadeOut();
$("#himg").find('img[src="' + images[n+1] + '"]').hide().fadeIn();
});
<div class="col-xs-2">
<div id="handbags">
<h4>Handbags</h4>
<img id="himg" src="FullSizeRender (1).jpg" />
</div>
</div>
I have made an array where images change on click, but I am trying to make the images fade on click instead of sharply changing. I've tried selecting the images by source using the index from the array, but it's not working.
Try this:
$(document).ready(function() {
var n = 0;
var images = ["FullSizeRender(1).jpg","IMG_1875.JPG","IMG_4665.JPG","IMG_5213.JPG"];
var image = $('#himg');
image.on('click', function() {
var newN = n+1;
if (newN >= images.length) { newN = 0 };
image.attr('src', images[n]);
image.fadeOut(300, function () {
image.attr('src', images[newN]);
image.fadeIn();
n = newN;
});
});
});
I have make a traffic light system using javascript and used the setInterval to make it go by itself, however how can i make the timings different? for example i would like the red light and green light to stay on longer then amber and red amber.
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript</h1>
<h2>Learning to code</h2>
<p>This is my very first JavaScript task</p>
<img id="traffic" src="red.png">
<button type="button" onclick="dosomething()">something magical will happen if you press me</button>
<script>
var list = ["red.png", "redamber.png", "green.png", "amber.png"];
var index = 0;
var timer = setInterval(dosomething, 3000)
function dosomething(){
index = index + 1;
if (index == list.length) index = 0
var image = document.getElementById('traffic');
image.src=list[index];
}
</script>
</body>
</html>
Here is an example using a weighted-time similar to what I was explaining in my comment. I don't have your images so I replaced them with text.
function changeColors(){
if (index >= list.length) index = 0;
let item = list[index];
if (!item.countdown) item.countdown = item.weight - 1;
else item.countdown = item.countdown - 1;
var image = document.getElementById('traffic');
image.innerHTML=list[index].color+'-'+item.countdown;
if (item.countdown == 0) index = index + 1;
}
var list = [
{color:"red.png", weight:1},
{color:"redamber.png", weight:3},
{color:"green.png", weight:2},
{color:"amber.png", weight:1}
];
var index = 0;
let btnChangeColors = document.getElementById('btnChangeColors');
btnChangeColors.onclick = function() {
var timer = setInterval(changeColors, 1000);
};
<h1>JavaScript</h1>
<h2>Learning to code</h2>
<div id="traffic"/>
<button type="button" id="btnChangeColors">Start Traffic Light</button>
Here's what I'm trying to do:
Type initials (e.g. MS,AK,LT) by clicking on "Enter Names". This saves a string, which I then turn into an array (nameArray) in order to get each set of initials. After reordering these randomly, I want to place some of the initials into the textareas, but that's where things go wrong.
Here's what's wrong:
the initials display for a moment, then disappear after the function executes. (ALSO, I'm trying to have a div (with text "randomizing...") that is otherwise hidden, show itself for 4 seconds (4000 ms) while the initials are being reordered to indicate as such. That's what the setTimeout is for...but that doesn't work either. The div disappears along with the text). Why are these only in coordination with the execution of the function?
Here's the JS code:
var nameArray;
window.onload = pageLoad;
function pageLoad() {
$("#randomizingNotification").hide();
$("#prev_arrow").click(prevUser);
$("#next_arrow").click(nextUser);
$("#enter_names").click(orderNames);
}
function orderNames() {
nameArray = getNames();
randomizeNames();
displayNames();
}
function getNames() {
var initialsString = prompt("Please enter initials, separated by a comma (e.g LK,AS,NM)");
nameArray = initialsString.split(",");
return nameArray;
}
function randomizeNames() {
$("#randomizingNotification").show();
var timer = setTimeout(function(){randomize(nameArray);},4000);
$("#randomizingNotification").hide();
clearTimeout(timer);
}
function randomize(array) {
for (var i = 0; i < array.length; i++ ) {
var randNum = Math.floor(array.length*Math.random()) //random number between 0 and length of array (rounded down
var temp = array[i];
array[i] = array[randNum];
array[randNum] = temp;
}
}
function displayNames() {
var curr, up, prev, current, upcoming, previous;
curr = 0;
up = 1;
prev = null
current = nameArray[curr];
upcoming = nameArray[up];
$("#upcoming_pick").val(upcoming);
$("#current_pick").val(current);
}
Here's the relevant HTML code:
<body>
<div id="header">
<div id="randomizeNotContDiv">
<div id="randomizingNotification">randomizing...</div>
</div>
<div id="page_title"><h1>Welcome to Classtech Shift Scheduler!</h1></div>
<div id="helper_functions_div">
<div id="enter_names_div">
Enter Names
</div>
</div>
<div id="main_content">
<div id="name_tracker">
<div><img src="Images/prev_arrow.png"/></div>
<textarea name="upcoming_pick" cols="10" rows="1" class="picker_names" id="upcoming_pick"></textarea>
<textarea name="current_pick" cols="10" rows="1" class="picker_names" id="current_pick"></textarea>
<textarea name="previous_pick" cols="10" rows="1" class="picker_names" id="previous_pick"></textarea>
<div><img src="Images/next_arrow.png"/></div>
</div>
You've got at least few issues, but the main problem is the structure of your setTimeout. A setTimeout is like an AJAX call in that it's non-blocking. Anything inside the function you pass to it will only execute when the timer is done, while code that comes after it will execute immediately.
I've reorganized the hiding of your randomization message and the displayNames function to go inside of the setTimeout function and things work fine.
Here it is in a fiddle: http://jsfiddle.net/nate/LB6dz/
And here's the code:
var nameArray;
window.onload = pageLoad;
function pageLoad() {
$("#randomizingNotification").hide();
$("#enter_names").click(orderNames);
}
function orderNames(event) {
// Prevent the link's default action
event.preventDefault();
nameArray = getNames();
randomizeNames();
}
function getNames() {
var initialsString = prompt("Please enter initials, separated by a comma (e.g LK,AS,NM)");
nameArray = initialsString.split(",");
return nameArray;
}
function randomizeNames() {
$("#randomizingNotification").show();
var timer = setTimeout(function (){
randomize(nameArray);
// These items need to be inside the timeout, so they only run once it's done
$("#randomizingNotification").hide();
displayNames();
}, 4000);
// No need to clearTimeouts after they're done... they only run once
// clearTimeout(timer);
}
function randomize(array) {
for (var i = 0; i < array.length; i++ ) {
var randNum = Math.floor(array.length*Math.random()) //random number between 0 and length of array (rounded down
var temp = array[i];
array[i] = array[randNum];
array[randNum] = temp;
}
}
function displayNames() {
var curr, up, prev, current, upcoming, previous;
curr = 0;
up = 1;
prev = null
current = nameArray[curr];
upcoming = nameArray[up];
$("#upcoming_pick").val(upcoming);
$("#current_pick").val(current);
}
I have the following javascript. It works well when I am cycling between 2 images, but when I add a third it does not work correctly.
Here is my CSS:
img {
-webkit-transition-property: opacity;
-webkit-transition-duration: 2s;
position: absolute;
width: 320px;
height: auto;
}
img.fade-out {
opacity: 0;
}
img.fade-in {
opacity: 1;
}
Here is my javascript, which seems to work but seems laggy and definately not an elegant solution.
</head><body style="color: black">
<img id="one" class="fade-out" src="Wallpaper.png"/>
<img id="two" class="fade-out" src="Wallpaper0.png"/>
<img id="three" class="fade-out" src="Wallpaper1.png"/>
<script>
var images = ['Wallpaper.png', 'Wallpaper0.png', 'Wallpaper1.png'];
var index = 0;
var fade_in = one;
var fade_out = two;
var fade_foo = three;
fade_in.src = images[0];
fade_out.src = images[images.length - 1];
var fade = function () {
fade_in.src = images[index];
index = (index + 1) % images.length;
fade_in.className = 'fade-out';
fade_out.className = 'fade-in';
fade_foo.className = 'fade-out';
var fade_tmp = fade_in;
fade_in = fade_out;
fade_out = fade_foo;
fade_foo = fade_tmp;
setTimeout(fade, 15000);
};
fade();
</body></html>
For one thing, you're not changing fade_out.src. Try something like this:
fade_in.src = images[0];
fade_out.src = images[1]; // let's use image next to current for fade-out
var fade = function () {
fade_in.src = images[index];
index = (index + 1) % images.length;
fade_out.src = images[index]; // put next to current image into fade-out
// Code below does something misterious.
// You first switch classes between two img's, then switch variables themselves
// Why?
//fade_in.className = 'fade-out';
//fade_out.className = 'fade-in';
//var fade_tmp = fade_in;
//fade_in = fade_out;
//fade_out = fade_tmp;
setTimeout(fade, 15000);
};
Can't tell more since I don't know what exactly you're doing.
It seems you're only displaying one image at a time, so you don't need two variables, one will do. You just need to fade out the current image and bring in a new image:
var index = -1, count = /* total number of images */;
var image = null;
function fade() {
if (image != null)
image.className = 'fade-out';
index = (index + 1) % count;
image = document.getElementById('image-' + index);
image.className = 'fade-in';
setTimeout(fade, 15000);
}
fade();
This assumes that you have set up all the images in HTML as follows:
<img id="image-0" class="fade-out" src="..." />
<img id="image-1" class="fade-out" src="..." />
<img id="image-2" class="fade-out" src="..." />
...
Note that you can achieve cross-fading only if you have several images preloaded, as in the above example. If you use only one image and change the source, the previous image will be lost when you try to fade in the new one.
you're not waiting for you transitions to finish before you swap the source. we just need to rearrange the order of things.
var fade = function() {
fade_in.className = 'fade-out';
fade_out.className = 'fade-in';
setTimeout(function() {
index = (index + 1) % images.length;
fade_in.src = images[index]; // should be completely invisible at this time
var fade_tmp = fade_in;
fade_in = fade_out;
fade_out = fade_tmp;
}, 2000); // 2 seconds, same as your transition time
setTimeout(fade, 15000);
};
setTimeout(fade, 15000);
here the only work that the fade method does is to change the classes, which initiates the transitions. we set a delay that matches your transition time to update the index and swap the image source.
edits: i guess i'm not making it clear what's going on and the assumptions i'm making. here's my complete html except for the provided css which is the same. i also fixed an issue with image order since the last example.
<body>
<img id="one" class="fade-out" /><img id="two" class="fade-out" />
<script>
var images = ['16jog8h.jpg', '20_11_2007_0044537001195507712_joe_baran.jpg', '400davesrig.jpg'];
var index = 0;
var fade_in = document.getElementById('one');
var fade_out = document.getElementById('two');
// fade_in.src = images[0];
fade_out.src = images[0];
var fade = function() {
fade_in.className = 'fade-out';
fade_out.className = 'fade-in';
setTimeout(function() {
index = (index + 1) % images.length;
fade_in.src = images[index];
var fade_tmp = fade_in;
fade_in = fade_out;
fade_out = fade_tmp;
}, 2000);
setTimeout(fade, 5000);
};
fade();
</script>
</body>