I'm attempting to create a page that displays and refreshes an image from a webcam (camimg.jpg), but displays a static image (notlive.jpg) if the image hasn't been updated recently. I've found the AJAXCam script, which serves the purpose of reloading the "live" image at a set interval (15 secs), yet with no Javascript experience I can't figure out how to determine when the image was last updated in order to decide whether or not camimg.jpg or notlive.jpg should be displayed.
My limited experience with programming has me thinking it should be something along the lines of:
pageLoaded = time page loaded in browser
imageUpdated = time the image was uploaded to server
if imageUpdated is not within 20 seconds of pageLoaded:
display notlive.jpg
else:
run AJAXCam
The AJAXCam code (initially called by <body onLoad="holdUp()">) is as follows:
<script type="text/javascript">
<!--
//
//AJAXCam v0.8b (c) 2005 Douglas Turecek http://www.ajaxcam.com
//
function holdUp()
{
//
// This function is first called either by an onLoad event in the <body> tag
// or some other event, like onClick.
//
// Set the value of refreshFreq to how often (in seconds)
// you want the picture to refresh
//
refreshFreq=15;
//
//after the refresh time elapses, go and update the picture
//
setTimeout("freshPic()", refreshFreq*1000);
}
function freshPic()
{
//
// Get the source value for the picture
// e.g. http://www.mysite.com/doug.jpg and
//
var currentPath=document.campic.src;
//
// Declare a new array to put the trimmed part of the source
// value in
//
var trimmedPath=new Array();
//
// Take everything before a question mark in the source value
// and put it in the array we created e.g. doug.jpg?0.32234 becomes
// doug.jpg (with the 0.32234 going into the second array spot
//
trimmedPath=currentPath.split("?");
//
// Take the source value and tack a qustion mark followed by a random number
// This makes the browser treat it as a new image and not use the cached copy
//
document.campic.src = trimmedPath[0] + "?" + Math.random();
//
// Go back and wait again.
holdUp();
}
// -->
</script>
Is what I'm trying to accomplish even possible? And if so, how would I go about implementing it? Thanks in advance for the help!
There is no way to do it in javascript.
Your only option is, in case you have access to server side languages like PHP you can send a simple HEAD request and check Last Modified header of the image then report it back to the browser via Ajax.
Related
I want to create snake game, everything works well, but I wish to pass score to another html file and I am unable. Is there any good way to transfer javascript variable into file from which i can then read? Or directly to another html would be best if possible. Thanks for every answer! I also wish to wait a little so person can see where he died but command "wait(function, miliseconds)" did not work.
I´ve already tryed this piece of code which resulted into nothing.
set fso = CreateObject("Scripting.FileSystemObject");
set s = fso.CreateTextFile("../pages/score.txt", True);
s.writeline(score);
s.Close();
My engame function right now:
function endGame()
{
clearInterval(game);
clearInterval(spawnEnemy);
clearInterval(spawnBonus);
dead.play();
window.location.href = "../pages/score.html";
}
As wrote above I need to solve issue with file or displaying score in different html and also to wait before going into another page via window.location.href command.
You can store variables in sessionStorage (is stored until the user closes the browser tab) or in localStorage (is stored without expiration date) and can access them from different sites then.
This is how you can store a value:
// store the score for future use
localStorage.setItem("score", 7);
This is how you can retrieve it:
// display the stored score
console.log("The stored score is: " + localStorage.getItem("score"));
You can trigger a function after a wait period like so:
//change this to the number of seconds you want to wait
var nrOfSeconds = 5;
//use the function you want to trigger after the wait period here
function theFunctionYouWantToTrigger(){
console.log("Function was triggered after " + nrOfSeconds + " seconds");
}
//since the timeout needs the time in milliseconds we need to mulitply the seconds with 1000
window.setTimeout(theFunctionYouWantToTrigger, nrOfSeconds*1000);
I'm currently modifying a open source project (link) to fit my need.
my English is bad, maybe it will be clearer if you can click on the link page, it will take half of minute to load, browser may seems to be freeze for a moment.
this page uses slickgrid , when hovering mouse over table rows , it will render details of that row on a fixed-position layer on page(the bottom left). there is only one such detail layer on the page, when you move your mouse to another row, this layer will change to show details of that row. following code is how it achieve this :
this.grid.onMouseEnter.subscribe( function (e) {}) // use slickgrid to set event listeners
// inside the handler function
from event e, get the row number row.rc
// then calls the staticOverlayDetails function do the actual work. it will renders the presentation layer.
window.setTimeout(function(){staticOverlayDetails(rc.row);}, 30);
so this staticOverlayDetails function will render the layer ( a div element ) to show the detail of row number rc.row, which is where mouse cursor is at.
I want to collect all the rendered result layer html code so I can combine them into a single page for easy read. that means, I want to hover my mouse on row one, wait for layer to be rendered, copy and save the div element, then move mouse to the next row , wait for the layer to be rendered with this new row , ...repeat until all row are done.
function staticOverlayDetails pseudo code:
function staticOverlayDetails (rown) {
//step 1:generate html text structure for the row, but leaves an element blank, this element is a text description for the row. the text will be loaded from a txt file
...
...
// html_text contains an `div` for description text which is currently empty, the text need to be fetched from a text file url, the text file name is based on the content of row. for the purpose of when the text is fetched, the callingback function need to know where to insert and avoid insert wrongly ( if the mouse has already moved to another row, the layer is showing details of another row, so the description text mismatch), so here it set a random string as the unique id of the description `div`, so later the `insert` function can use the id string as selector to insert text.
description_selector = random_id
html_text= html_code_generated
//step 2:
// this function fetches a , setting a callback function `insert` to insert the content.
url=generate text file url from row content
load_description( url, description_selector )
//step 3: present html
$(fixed-layer).html(txt)
//at this time , the description div is blank. the callback function will insert content into div when fetched.
}
function load_description (url, description_selector) {
function insert ( descrp_text ) {
$(description_selector).html(descrp_text).hide.slide_down()
}
$.get(url, insert, 'text')
}
my plan is to loop through rown to change the fixed layer, then dumps out the fixed layer :
for ( i=0; i < row_counts ; i++ ){
staticOverlayDetails(i)
console.log($(fixed_layer_selector).html())
but the async $.get() call makes this attempt impossible. because only when insert function finished , the content in layer is stable and ready to be dumped, if I use this loop, when $.get returns, the presentation layer is already showing later layers, I don't know how to wait for it.
how can I make my code waiting for the calling back function of $.get() to finish, so I can save the full details for the row, then continue to loop with the next row ?
according to link , I tried to modify the $.get request in the function load_content_for_an_element sync :
function load_description (url, description_selector) {
function insert ( descrp_text ) {
$(description_selector).html(descrp_text).hide.slide_down()
}
$.get({url:url, success:insert, sync:false});
}
but the browser make request to https://host.address/[object%20Object] and it returns with 404 error. seems it convert the passed object to string, then treat it as url to fetch.
some additional info:
1, because this project has several tables each with different rendering logic, I want to make the changes as small as possible, that's why I want to dump the generated presentation layer instead of changing the generating code itself. all different tables render the same layer, that's the easiest way to do it.
2, I want to dump the code to generate an page to read, only need to dump once , so there is no worries about performance. actually I can use a mouse macro to do it , but I think that's too dumb, I want to learn the javascript way to do it :)
I'm so sorry my English is bad and I want to express such a complex situation, so please ask for more infos if my words are not clear, I'm so sorry to see other people waste time because of my mistake words...
Promises are your friend. Here's an example of how you would structure your code to use them:
// Set up a staging area
var staticOverlays = [];
loadStaticOverlayDetails(index) {
return $.get(url, insert, data....).then(function (data) {
staticOverlays[index] = data;
});
}
// Request your data
var promises = [];
for ( var i=0; i < 100; i++ ) {
promises.push(loadStaticOverlayDetails(i));
}
// Wait for the data to complete loading
$.when(promises).then(function insert() {
for ( i=0; i < staticOverlays.length; i++ ) {
var overlay = staticOverlays[i];
// step 1:generate html text structure for the row, but leaves an element blank
var txt = html_code_generated
// insert data into element in fixed layer;
$(fixed-layer).html(txt);
}
});
As an aside, if you're really making 100+ http requests you should consider moving some of this logic to the server because that many http requests will hurt your user experience...
I'm trying to start a loader to show that I have a process going on. Converting a kml file to geojson. The converting part works fine. Larger kml files take longer to convert and I want to show that my web page is doing something while it's converting the file. I have this:
function convertFunction() {
loader.style.display = "block";
if(format.value = "kml"){
out.value = JSON.stringify(toGeoJSON["kml"]((new DOMParser()).parseFromString(input.value, 'text/xml')), null, 4);
}
};
I'm used to working with Android and when I order my processes like that, it usually starts the first one first.
Why does my loader not start until after my file is converted and placed into my out text view? How can I get it to work the way I want it to?
I'm not uploading the file to a server first. I'm reading the text from the file, placing the text in a text view(input), getting the text from the input, convert and put new text in the output text view. Then last button to create the geojson file and download it.
The reason that your loader isn't showing is that your conversion process is blocking code. This means that it will hold up the main thread (the UI thread) until the conversion process is done. The loader will never be shown because the conversion will already be done before the browser has a chance to show it.
A possible solution:
Use a Web Worker to carry out the conversion process on a separate thread. This will keep your UI thread free so that your loader can display and animate.
Another possible (simpler) workaround:
Display something on the page to indicate that the conversion process is going on, and use setTimeout to delay the conversion process just enough to allow the page to update. Note that you wouldn't be able to show any sort of animation during the conversion in this case because the blocked UI thread would prevent it from animating.
function convertFunction() {
if(format.value === "kml"){
loadingMessage.style.display = "block";
setTimeout(function () {
out.value = JSON.stringify(toGeoJSON["kml"]((new DOMParser()).parseFromString(input.value, 'text/xml')), null, 4);
loadingMessage.style.display = 'none';
// run any code that would use out.value
}, 100);
}
};
I need to do a simple pdf with some 3D objects for an oral presentation. I made several views, each one with a camera viewpoint, an object and a display mode.
To avoid the need to manually switch between the different viewpoints with the context menu, I would like the viewpoints to switch automatically with a Timer (each viewpoint staying for a few seconds). And I would like to not have to touch the mouse at all (nor the keyboard), so I would like to have the playback started as soon as the page appears.
I found the javascript command runtime.setView(N,x) to switch to the x'th view among N, but I don't know where to put it (I don't want to define a function which will be called when I press a button, since I want everything to be automated). Also, I don't know how to pause for a few seconds.
Any help ? Thanks !
I believe you're looking for setInterval(fn, time) which will call a function periodically at a time interval that you set. I'm not familiar with the setView() method you mentioned, but here's some pseudo code that you would put in tags at the end of the document body.
function startSwitcher()
var viewNum = 0;
var maxViews = 5; // you set this to how many views there are
setInterval(function() {
++viewNum;
if (viewNum >= maxViews) {
viewNum = 0;
}
runtime.setView(N, viewNum); // you will have to figure out this line
}, 2000);
}
startSwitcher();
The 2000 is 2000 milliseconds and is the time interval between executing the function. You can put any number of milliseconds there.
The runtime.setView(N, viewNum) line is something you will have to figure out as I am not familiar with whatever library you're trying to use there. The operative part of this code is the viewNum variable which configures which view in rotation should be next.
I think the runtime.SetView(..) Methods works with the name of the view as a string instead of the viewnumber. I have this function in a Dokument-level script and it works for me:
// view is the name of the view for example "TopView"
function setView(view){
console.println("Navigating to view: "+view);
var pageIndex = this.pageNum;
var annotIndex = 0;
var c3d = this.getAnnots3D( pageIndex )[ annotIndex ].context3D;
c3d.runtime.setView(view, true);
}
Combine this with the setInterval(..) from jfriend00´s answer und you should get what you need.
Best regards
I have a html page with 2 buttons on it and a big javascript function that is executed every 10 ms. Each click on each button executes a javascript function that changes some variables used by the big javascript function and change its behaviour. In time the code got very complex and time consuming and I would like to move the entire calculation of variables over to the server side. Or, better yet I would like to generate the entire function on the server.
How can I dynamically change the big javascript function when any of the 2 buttons is being pressed?
What you could do is once the button is pressed you make an Ajax request to the server side. There you generate the javascript code based on the button pressed and send it back. You can then eval the response and execute the appropriate function.
Grabbing a large script and executing it every 10 ms is bound to be slow.
Modifying a large script isn't that bad and then you only care about the execution plan of the script. (It doesn't matter how fast the server can generate the script the client will execute if you're sending it every 10 ms and it's super complicated. Client execution is going to cause the client to creep if not properly made.)
However have you considered just "fixing" your script so that it's a bit more compartmentalized. Surely the entirety of the function does not change every 10 ms? (On your site does it change from being a game of Pong to a looping weather radar graphic every 10 ms?)
compartimentalized javascript example (using jquery): Assumes you have two tags one with the class buttonA and one with the class buttonB. Clicking buttonA or buttonB changes internal values and then the script is executed.
var complicatedFunction = function(){
//private variables and methods
var a = 2, b = 3;
//public variables and methods
return {
exec: function(el){
//which button was pushed?
if($(el).is('.buttonA')){
a = 4;
b = 8;
} else {
a = 10;
b = 2;
}
alert('The result of a*b is ' +(a*b));
}
}
}();
$('.buttonA, .buttonB').click(function(){complicatedFunction.exec(this)});
Wish I could help more, if you post a code example maybe we can!