displaying images with different intervals - javascript

I am trying to display an array of images that will replace each other but will have 0.5 sec of black screen between them.
For example array_img = ["im1","im2","im3"]
show im1 for 3 seconds, show a black screen for 0.5 sec, show im2 for 3 sec, black screen for 0.5 sec...
my code is
images_array is a global variable.
time_between_images = 3000 and is a global var
time_for_black_screen = 500 and is a global var
function displayImages(){
for (i = 0; i < images_array.length; i++) {
console.log(images_array[i]);
setTimeout(function () {
console.log("1");
$('#exprBody').css('background-color', 'white');
$('#picture_frame').append(images_array[i]);
}, time_between_images)
setTimeout(function () {
console.log("2");
$("#picture_frame img:last-child").remove()
$('#exprBody').css('background-color', 'black');
}, time_for_black_screen)
}
console.log(images_array);
}
My html is simple
<body>
<div id="experiment_frame">
<div id="header">
<div id="left_cat"></div><div id="right_cat"></div>
</div>
<div id="picture_frame" class="centered">
<div id="exp_instruct"></div>
</div>
</div>
</body>
I thought I should use setTimeout because I want to switch between the two tasks for each image in the array. IMG + black screen, IMG + black screen
but nothing is showing on my page.
The array
["<img src='/images/cute/1223.jpg'>", "<img src='/images/cute/1235.jpg'>", "<img src='/images/disgusted/8878.jpg'>", "<img src='/images/disgusted/8898.jpg'>", "<img src='/images/neutral/3321.png'>", "<img src='/images/neutral/3445.png'>"]
EDIT:
function displayImageIter(number) {
$("body").toggleClass("whiteBody");
$("#picture_frame").empty().append(images_array[number]);
setTimeout(function () {
$("#picture_frame").empty();
$("body").toggleClass("blackBody");
setTimeout(function () {
displayImageIter((number + 1) % images_array.length);
}, time_for_black_screen)
}, time_between_images)
}
For some reason what I have with this code is
IMG white background
blank screen white for 0.5 sec
IMG black background
blank screen white for 0.5 sec

Take a look at the following simplified code:
function displayImage(number) {
$("#picture_frame").empty().append(images_array[number]).css('background-color', 'white');
setTimeout(function () {
$("#picture_frame").empty().css('background-color', 'black');
setTimeout(function () {
displayImage((number + 1) % images_array.length);
}, time_for_black_screen)
}, time_between_images)
}
const images_array = ["FIRST IMAGE", "SECOND IMAGE", "THIRD IMAGE"];
const time_between_images = 3000;
const time_for_black_screen = 500;
displayImage(0);
#picture_frame {width: 200px; height: 100px; background-color: white}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="picture_frame"></div>
Answering your comment:
a) To change the parent div background just use:
$("#picture_frame").empty().append(images_array[number]);
$("#parent_div").css('background-color', 'white');
b) To stop this loop you could use some flag and set it to false after 15 minutes:
function displayImage(number) {
$("#picture_frame").empty().append(images_array[number]).css('background-color', 'white');
setTimeout(function () {
$("#picture_frame").empty().css('background-color', 'black');
setTimeout(function () {
//continue only if flag is true
if (flag) displayImage((number + 1) % images_array.length);
}, time_for_black_screen)
}, time_between_images)
}
const images_array = ["FIRST IMAGE", "SECOND IMAGE", "THIRD IMAGE"];
const time_between_images = 3000;
const time_for_black_screen = 500;
let flag = true;
displayImage(0);
//used 15 seconds here for simplicity
setTimeout(() => flag = false, 15000);

<a class="img0"></a>
<a class="img1"></a>
<a class="img2"></a>
<script>
var elArr = [];
// here get the els that you wanna to display img
elArr.push(document.querySelector('.img0'));
elArr.push(document.querySelector('.img1'));
elArr.push(document.querySelector('.img2'));
// here is the img src and it's interval
var imgArr = [
{ src: 'a', interval: 3000 },
{ src: 'b', interval: 2000 },
{ src: 'c', interval: 1000 },
];
// if you wanna auto display unknown number imgs, set a variable to count the whole interval
var sumInterval = 0;
for (var i = 0; i < imgArr.length; i++) {
// the first interval is 3000, second is 5000, third is 6000
sumInterval += imgArr[i].interval;
setTimeout(function () {
elArr[i].innerHTML = imgArr[i].src;
// if is the last img, set an interval and then do the callback
if (i == imgArr.length - 1) {
setTimeout(function () {
alert('now screen shall be black');
}, 500)
}
}, sumInterval);
}
</script>

Related

ReadyStateChange after all DOM Elements are create, else many SVG animation?

I have many SVG animation bodymovin.load, so i need to create preloader with persent, where persent every img in all animation
All work is ok, BUT
document.addEventListener('DOMContentLoaded', () => {
starts before all image svg create at DOM, for example in first animation load svg 60 images, in second 367, and preloader see only 60 images
It's preloader
document.addEventListener('DOMContentLoaded', () => {
const mediaFiles = document.querySelectorAll('image');
console.log(mediaFiles)
let i = 0
Array.from(mediaFiles).forEach((file, index) => {
file.onload = () => {
i++
percents.innerHTML = ((i * 100) / mediaFiles.length).toFixed(1)
if(i === mediaFiles.length) {
preloader.classList.add('preloader-hide')
percents.innerHTML = 100
}
}
})
})
It's animations
const ramaoknaData = {
container: document.getElementById('ramaokna-container'),
renderer: 'svg',
loop: false,
autoplay: false,
path: '/ramaokna.json'
};
const ramaoknaAnim = bodymovin.loadAnimation(ramaoknaData);

How to change color of the background in table cell for two seconds? and go back to default

In the below javaScript code:
function webSocketStart()
{ //onclick() of a button
document.getElementById("button").disabled = true;
var wsock = new WebSocket("ws://127.0.0.1:1234/websock");
wsock.onmessage = function (evt)
{
var map = JSON.parse(evt.data)
var myTable = document.getElementById("myTable");
var rows = myTable.getElementsByTagName("tr")
var existing = false
for (var i = 1; i < rows.length; i++) {
if (rows[i].getElementsByTagName("td").length > 0) {
if (rows[i].cells[0].textContent.trim().localeCompare(map['Key'].trim()) == 0){
rows[i].cells[1].textContent = map['Value'] // cell color should change and unchange for two seconds
existing = true
break
}
}
}
if (!existingApp){
var row = myTable.insertRow(1); // New row at the first position
var keyCell = row.insertCell(0)
keyCell.textContent = map['Key']
keyCell.style.backgroundColor = 'yellow'
setInterval(function(){
keyCell.style.backgroundColor = 'white'
}, 2000);
var valueCell = row.insertCell(1)
valueCell.textContent = map['Value']
valueCell.style.backgroundColor = 'yellow'
setTimeout(function(){
valueCell.style.backgroundColor = 'white'
}, 2000);
}
Line 17, 26 & 27 have comments for color change and unchange
Edit:
Made code changes with setTimeout() but some cells does not change back to white
for (var i = 1; i < rows.length; i++) {
if (rows[i].getElementsByTagName("td").length > 0) {
if (rows[i].cells[0].textContent.trim().localeCompare(map['Key'].trim()) == 0){
rows[i].cells[1].textContent = map['Value']
rows[i].cells[1].style.backgroundColor = 'yellow' // color change
existing = true
setTimeout(function(){
rows[i].cells[1].style.backgroundColor = 'white'
}, 2000);
break
}
}
}
if (!existing){
var row = myTable.insertRow(1);
keyObj = row.insertCell(0)
keyObj.textContent = map['Key']
keyObj.style.backgroundColor = 'yellow' // color change
setInterval(function(){
keyObj.style.backgroundColor = 'white'
}, 2000);
keyObj = row.insertCell(1)
keyObj.textContent = map['Value']
keyObj.style.backgroundColor = 'yellow' // color change
setTimeout(function(){
keyObj.style.backgroundColor = 'white'
}, 2000);
}
Using CSS & JavaScript,
1) How to change and unchange the color of the background in table cell, for 2 seconds? after setting of values in table cell
2)
As table element has style properties, Can we achieve the same without CSS rules? rows[i].cells[1].style.backgroundColor = 'yellow'
You can just use sleep function with the seconds inside like sleep(2) for 2 seconds
Is it what's you want
You're already getting the element so you would add a class in JS like this:
el.classList.add('className'); Then you need to set a timer setInterval(function, milliseconds) that removes the class after a set amount of time. The CSS will then revert back to default. I added a CSS transition to the color so it's not as jarring when it changes.
(click handler is just for the example)
var removeClass = function(targ){
if(targ.classList.contains('highlight')){
targ.classList.remove('highlight');
}
}
document.getElementById('myEl').addEventListener('click', function () {
var myEl = this
myEl.classList.add('highlight');
var myTimer = setInterval(function(){removeClass(myEl)},2000);
});
#myEl {
width: 30px;
height: 30px;
margin: 10px;
background-color: aqua;
transition: background 0.25s ease;
}
#myEl.highlight {
background-color: orange;
}
<div id='myEl'></div>
Click the box to activate the timer

Showing Progress while Child row loads

Coming again with another question :)
This time I had a requirement to show some progress while Child rows are being loaded. Since there is an Api call which relatively takes little time to return data, I do want to show the some progress unless the user who clicks the parent row is totally unaware whether there is a call done to see its child rows.
What I have done:
I wrote a style sheet class which has a
loader-small.gif
image as this:
tr.loading td.details-control {
background: url('/Images/loader-small.gif') no-repeat center center;
}
and applied like this:
$('#accountManagerEarningsDataTable tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
try {
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
//Calling the loading Class ------>
tr.addClass('loading');
// Open this row
var arrForTable1 = [];
var arrForTable2 = [];
totalBrokerage = 0;
totalRetailBrokerage = 0;
totalSelfServiceBrokerage = 0;
console.log('You selected: ' + row.data().AccountManagerID);
var settings = {
"columnDefs": [
{ targets: 1, align: "right", decimals: 0 },
{ targets: 2, align: "right", decimals: 0 },
{ targets: 3, align: "right", decimals: 0 },
{ targets: 4, align: "right", decimals: 2 },
{ targets: 5, align: "right", decimals: 2 }
]
};
//problems with asynchoronus call back
var response = organization_GetAccountManagerDetailEarningsAccountData(row.data(), purl2, pcontext);
if (response.success === "true") {
for (var i = 0; i < response.value.length; i++) {
for (var j = 0; j < response.value[i].Securities.length; j++) {
var itemRow2 = {};
itemRow2["Security ID"] = response.value[i].Securities[j].SecurityId;
itemRow2["Trades"] = response.value[i].Securities[j].Trades;
itemRow2["Buy Qty"] = response.value[i].Securities[j].BuyQuantity;
itemRow2["Sell Qty"] = response.value[i].Securities[j].SellQuantity;
itemRow2["Total Brkg"] = response.value[i].Securities[j].Effective_Brokerage;
itemRow2["Online Brkg"] = response.value[i].Securities[j].Online_Brokerage;
arrForTable2.push(itemRow2);
totalBrokerage = totalBrokerage + parseFloat(response.value[i].Securities[j].Effective_Brokerage);
totalSelfServiceBrokerage = totalSelfServiceBrokerage + parseFloat(response.value[i].Securities[j].Online_Brokerage);
}
totalBrokerage = Math.round(totalBrokerage * 100) / 100;
totalSelfServiceBrokerage = Math.round(totalSelfServiceBrokerage * 100) / 100;
totalRetailBrokerage = Math.round(totalRetailBrokerage * 100) / 100;
var itemRow1 = {};
itemRow1["Account ID"] = response.value[i].AccountId;
itemRow1["Account Name"] = response.value[i].AccountName;
itemRow1["..."] = '<div class="alert alert-info" role="alert">' + buildHtmlTable(arrForTable2, 'table2x' + j, settings) + '<p>Total Brokerage ' + numberWithCommas(totalBrokerage) + '</p></div>';
arrForTable1.push(itemRow1);
arrForTable2 = [];
totalBrokerage = 0;
totalRetailBrokerage = 0;
totalSelfServiceBrokerage = 0;
}
tr.removeClass('loading');
htmlTable1 = buildHtmlTable(arrForTable1, 'table1x' + i);
row.child(htmlTable1).show();
tr.addClass('shown');
}
else {
row.child('<table><tr><td>' + response.value[0].AccountId + '</td></tr></table>').show();
tr.addClass('shown');
};
}
} catch (e) {
console.log(e.message);
}
});
The Problem:
Firefox nicely shows the Progress image after the user clicks it, but Edge and Chrome does not show. Both browsers crossed this piece of code when I was debugging from developer tools of the respective browser.
Its browser compatible problem? Is there a solution for it? Help me please.
In case of chrome there is such an issue while showing the loading bar while making a server call. Please make the following changes where you are making the service call. First add the class loading to the table
tr.addClass('loading');
After that make the service call by giving a timeout function
setTimeout(function(){
var response = organization_GetAccountManagerDetailEarningsAccountData(row.data(), purl2, pcontext);
......
//Your service calls and response call backs
},1);
On providing a timeout (say 1ms), Chrome will get the time to bind the loading bar to DOM, In other case the DOM Object is not available to show the spinner.

Replace random image on website

my goal is to replace one random image from open website with some random image from my list of images. I have this code, but It changes all the images on the website, I need just one random not all of them. Can you help me please with it?
//Handles all images on page with an interval of time
handleImages: function (lstImgs, time) {
$.each($('img'), function (i, item) {
//Skip if image is already replaced
if ($.inArray($(item).attr('src'), lstImgs) == -1) {
var h = $(item).height();
var w = $(item).width();
//If image loaded
if (h > 0 && w > 0) {
self.handleImg(item, lstImgs);
}
else {
//Replace when loaded
$(item).load(function () {
//Prevent 'infinite' loop
if ($.inArray($(item).attr('src'), lstImgs) == -1) {
self.handleImg(item, lstImgs);
}
});
}
}
});
//Keep replacing
if (time > 0) {
setTimeout(function () { self.handleImages(lstImgs, time); }, time);
}
},
//Replace one image
handleImg: function (item, lstImgs) {
$(item).error(function () {
//Handle broken imgs
self.handleBrokenImg(item, lstImgs);
});
self.setRandomImg(item, lstImgs);
},
//Set a random image from lstImgs to item
setRandomImg: function (item, lstImgs) {
var h = $(item).height();
var w = $(item).width();
$(item).css('width', w + 'px').css('height', h + 'px');
$(item).attr('src', lstImgs[Math.floor(Math.random() * lstImgs.length)]);
},
//Removed broken image from lstImgs, run handleImg on item
handleBrokenImg: function (item, lstImgs) {
var brokenImg = $(item).attr('src');
var index = lstImgs.indexOf(brokenImg);
if (index > -1) {
lstImgs.splice(index, 1);
}
self.setRandomImg(item, lstImgs);
},
};
//Run on jQuery ready
$(function () {
self.handleImages(self.gitmbImgs, 3000);
});
//Set global variable
$.gitmb = self;
$.each($('img') selects all images, all you need is one.
Update
<img src="https://thereisnocavalry.files.wordpress.com/2012/08/fractals-erucolindo3.jpg" alt="some image">
<img src="http://ionamiller.weebly.com/uploads/4/7/9/5/4795680/5133447.jpg?617" alt="some image">
<img src="http://wallpoper.com/images/00/17/31/50/abstract-fractal_00173150.jpg" alt="some image">
<img src="http://www.wussu.com/fractals/images/wd950112.gif" alt="some image">
<img src="http://naperdesign.com/wp-content/uploads/2010/09/fractals_generative.jpg" alt="some image">
$().ready(function() {
var imagesToReplace = $("img");
var imagesReplaced = [];
var imagesAvailable = [
"http://www.hdwallpapersn.com/wp-content/uploads/2015/04/Fractal-Pictures-3.jpg",
"http://fc02.deviantart.net/fs27/f/2008/073/c/e/Fractals_of_the_Ball_by_Hosse7.jpg",
"https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcTQKqS8FDvMUcbsUTQj8TIbHg7JSIpvcQqWax9Pq5gZX2BcoVIm",
"http://www.sgeier.net/fractals/fractals/01/Fire%20and%20Water.jpg",
"http://www.fractalsciencekit.com/fractals/large/Fractal-Mobius-Dragon-IFS-10.jpg",
"https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQV44vnqHs24LfEEmMPKXojB4whOyBMnQbXghk2kJnkeP90bSR8"
];
var replaceImage = function() {
var repl_ind, with_ind, img;
if ( !imagesAvailable.length ) {
//loop once all images have been replaced
imagesAvailable = imagesReplaced.slice();
imagesReplaced = [];
}
repl_ind = Math.floor( Math.random() * imagesToReplace.length );
with_ind = Math.floor( Math.random() * imagesAvailable.length );
img = $(imagesToReplace.get(repl_ind));
console.log("replacing",img.attr("src"),"with",imagesAvailable[with_ind]);
imagesReplaced.push( img.attr("src") );
img.attr("src", imagesAvailable[with_ind] );
imagesAvailable.splice(with_ind, 1);
//start timer once image is ready, either instantly or after load
if ( img.get(0).complete ) {
setTimeout(replaceImage, 2000 );
console.log("complete");
img.get(0).onload=false;
} else {
console.log("onload");
img.get(0).onload = function() {setTimeout(replaceImage, 1000 );};
}
}
setTimeout(replaceImage, 4000 );
});
img {
width: 6em;
padding: 0.4em;
height: 5em;
}
This is fiddle link.

Loading elements one after another - simple jQuery

I have some JavaScript that loads a stack of separate elements based on their class name. However, I'd like to add a 1second delay on each, so they all appear one after another.
So i1 loads first then a second later i2 loads and so on...
How do I achieve this with my code?
<script>
jQuery(function($){
var i1 = $(".one"),
i2 = $(".two"),
i3 = $(".three");
i4 = $(".four");
i5 = $(".five");
i6 = $(".six");
$('.field').animate( {
marginTop:"0"
},600, function () {
i1.animate({
"opacity": 1
}),
i2.animate({
"opacity": 1
}),
i3.animate({
"opacity": 1
}),
i4.animate({
"opacity": 1
})
i5.animate({
"opacity": 1
}),
i6.animate({
"opacity": 1
}, 500);
});
});
</script>
Many thanks for any help with this :)
You can try this way:-
Html
<div class="one slide">1</div> <!-- give some common class all these-->
<div class="two slide">2</div>
<div class="three slide">3</div>
<div class="four slide">4</div>
<div class="five slide">5</div>
JS
var all = $('.slide').get(); //Get all the element to slide into an array.
function animate() {
var elem = all.shift(); //Remove the top element from the array
//animate it
$(elem).animate({
"opacity": 1
}, function () {
if (all.length > 0)
window.setTimeout(animate, 1000); //set the time out after the delay of 1 sec for next element to animate.
});
}
animate();
Demo
For each element, set animate function inside the callback of animate method of the previous element.
$('.field').animate({
marginTop: "0"
}, 600, function () {
i1.animate({
"opacity": 1
}, function () {
i2.animate({
"opacity": 1
},etc...);
Without leaking variables and having to add a new class, you can loop through the found elements and use setTimeout to delay time until the next. For example:
$(document).ready(function () {
var i1 = $(".one"),
i2 = $(".two"),
i3 = $(".three"),
i4 = $(".four"),
i5 = $(".five"),
i6 = $(".six"),
iterator = function () {
var arr = Array.prototype.slice.call(arguments, 0),
len = arr.length,
iterate = function (index) {
if (index === len) {
return;
}
arr[index].animate({
opacity: 1
}, 600, function () {
setTimeout(function () {
iterate(++index);
}, 1000);
});
};
iterate(0);
};
iterator(i1, i2, i3, i4, i5, i6);
});
DEMO: http://jsfiddle.net/FbGwQ/2/
Try using jQuery .delay(), it allows you to delay the execution of functions that follow it in the queue.
http://api.jquery.com/delay/
UPDATED:
Working jsFiddle Example: http://jsfiddle.net/DylanNunns/su8jp/2/
jQuery(function ($) {
var i1 = $(".one"),
i2 = $(".two"),
i3 = $(".three");
i4 = $(".four");
i5 = $(".five");
i6 = $(".six");
$('.field').animate({
marginTop: "0"
}, 600, function () {
i1.delay(1000).animate({
"opacity": 1
}),
i2.delay(2000).animate({
"opacity": 1
}),
i3.delay(3000).animate({
"opacity": 1
}),
i4.delay(4000).animate({
"opacity": 1
}),
i5.delay(5000).animate({
"opacity": 1
}),
i6.delay(6000).animate({
"opacity": 1
});
});
});
I like to use jQuery's each method along with delay to help out with this because it gives you the index of an element which you can use to set the delay.
jQuery(function () {
var animation_items = [
".one", ".two", ".three", ".four", ".five", ".six"
];
$.each(animation_items, function(index, item) {
$(item).delay(index * 1000).animate({
opacity: 1
}, 500);
});
});
You also get the added bonus of it working with a specific class instead of specifying them all separately. This makes everything more general and easier to maintain. You can simply add another div to your HTML without having to edit the JavaScript.
<div class="fade_in"></div>
<div class="fade_in"></div>
<div class="fade_in"></div>
jQuery(function () {
var delay = 1000;
$('.fade_in').each(function(index, item) {
$(item).delay(index * 1000).animate({
opacity: 1
}, 500);
});
});
Here's a demo
I think I'd rather use a bit of recursion and use the callbacks for a cleaner implementation (in my mind ..)
var oneByOne = function($el) {
$el.fadeIn(600, function() {
if (!$el.next().length == 0)
oneByOne($el.next());
});
};
$first = $('#one-by-one').children().first();
oneByOne($first);
http://jsfiddle.net/mikecmpbll/sbwMx/
Alternatively, still using recursion but working with the array of items instead:
var oneByOne = function(arr) {
$el = $(arr.shift());
$el.fadeIn(600, function() {
if (!$el.next().length == 0)
oneByOne(arr);
});
};
arr = $("#one-by-one").children().get();
oneByOne(arr);
http://jsfiddle.net/mikecmpbll/sbwMx/1/

Categories

Resources