PDA

View Full Version : Webcam pic as background updating every 60 seconds? New Old Guy



Greg_M
04-05-2016, 09:53 PM
I have a weather webpage with a webcam image that uploads every 2 minutes. I want to change the webpage.

I want the webcam image to be the background on the webpage, but I want that image to update itself once a minute.

The reason I want it to be the background image is so I can put weather report stickers on top of it (in the foreground) in the bottom corners or at the bottom of the page centered.

Right now the webcam takes the picture and uploads it to my domain host. Then I download it to my webpage. It's fairly kludged together at this point but it works. You can see it here (http://www.datilcam.com/)

Any help appreciated

Greg

PS
A friend game this rough syntax and I filled in the links.
He said it would do what I wanted and it does to a certain extent but it will not reload itself. Maybe someone can tell me what I did wrong




<html>
<body>
Test
</body>
<script>
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = 'url(http://datilcam.com/cam/HCpic.jpg)';

setInterval(updateBg(),5000);

function updateBg(){
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = 'url(http://datilcam.com/cam/HCpic.jpg)';
}
</script>
</html>

jscheuer1
04-06-2016, 12:54 AM
Hmm, that code looks very ragged to say the least. Even if it worked, the interval is every 5 seconds, much too frequently for an image that you say updates only every two minutes. In my experience, an interval half that of the event one is tracking is sufficient, so in this case, one minute, not 5 seconds would be good, but can only guarantee an update every three minutes with perhaps a one minute lag (most likely it will be more frequent). It depends upon how synced up you want to be. we could probably fine tune it to two minutes if there were a way of knowing when each two minute interval started. But, since we would be talking server versus client time, it might not be worth the attempt. Anyways, there are other problems with the code, the function is defined after the interval is set - might not matter. And there's no attempt to bust the natural caching many browsers will do that will frustrate loading a new image of the same name. IE is particularly bad in this regard. In any case, this is working here for me, give it a shot:


<html>
<body>
Test
</body>
<script>
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = 'url(http://datilcam.com/cam/HCpic.jpg)';
function updateBg(){
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = 'url(http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime() + ')';
}
setInterval(function(){updateBg()}, 1000 * 60);
</script>
</html>

Maybe, for less lag, a half minute:


<html>
<body>
Test
</body>
<script>
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = 'url(http://datilcam.com/cam/HCpic.jpg)';
function updateBg(){
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = 'url(http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime() + ')';
}
setInterval(function(){updateBg()}, 1000 * 30);
</script>
</html>

Regardless, you are not going to sync up perfectly. The displayed time on the image will often be a little behind local time, but not far. The tradeoff is, each time you update, the browser repaints the background, which is kinda ugly. If it's not crucial that you be as up to date as possible, you might even want to increase the interval to - say 5 minutes (1000 * 60 * 5). That way, every 5 minutes it will retrieve the most recent web image. If you eliminate the time stamp from the image, no one will know.

Greg_M
04-06-2016, 01:14 AM
Being in exact sync is not very important (to me) as long as it loads the picture every minute or two.
I really appreciate your advice and I'll try your code.
I've bought some books to try to learn but it has been a while since I did any programming type work.

Many thanks

Greg_M
04-06-2016, 03:09 AM
Is there a way to get around the white screen when the image refreshes?

jscheuer1
04-06-2016, 05:04 PM
I'm not sure. Certain things you can do. That's what I was talking about as far as it being uglier the more often it refreshes. A background color would help it not look so stark. I think CSS 3 allows for multiple backgrounds - that's not my area though. But if there could be a stand-by background behind it, an image of that same general scene, even the previous image, that might be work well. I think the best bet might be preloading the image once it's fetched, before it's displayed. Though some browsers (again IE I think is the worst here, though not so bad if it were an image instead of a background image), will still take awhile to repaint.

What exactly are you using for this? The page you linked to is using an image, that's probably better as I say. But the code you posted calls for a background image. If writing over it is an issue, by using absolute positioning you can make other things appear over an image, just as easily as over a background image.

Using the code I gave you in the last post, a preload would look like so:


<html>
<body>
Test
</body>
<script>
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = 'url(http://datilcam.com/cam/HCpic.jpg)';
function updateBg(){
var body = document.getElementsByTagName('body')[0],
img = new Image();
img.onload = function(){
body.style.backgroundImage = 'url(' + this.src + ')';
};
img.src = 'http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime();
}
setInterval(function(){updateBg()}, 1000 * 60);
</script>
</html>

Again, not so sure about IE. I'll play around and see. In any case, the browser may need to be refreshed and/or the cache emptied in order to see changes.

Greg_M
04-06-2016, 05:39 PM
What exactly are you using for this?


It's just my webcam/weather page.
You can see the current version HERE (http://www.datilcam.com/).
I just wanted to change it a bit for when we move to New Mexico.
I had dreams of learning this language and writing my own stickers that I could place in the forground of the webcam picture, sort of like the Weather Underground sticker on my current page.

jscheuer1
04-06-2016, 06:01 PM
I did see the page you're linking to already. I was wondering which you would be using, that, or the newer code we've been posting about. But now it really doesn't matter so much, as the CSS 3 idea I had, combined with the preload, seems almost seamless, even in IE 11. Here's the latest:


<html>
<body>
Test
</body>
<script>
function updateBackground(){
var body = document.getElementsByTagName('body')[0], prevImg = 'http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime();
body.style.backgroundImage = 'url(' + prevImg + '), url(' + prevImg + ')';
function updateBg(){
var img = new Image();
img.onload = function(){
body.style.backgroundImage = 'url(' + this.src + '), url(' + prevImg + ')';
setTimeout(function(){
prevImg = img.src;
body.style.backgroundImage = 'url(' + prevImg + '), url(' + prevImg + ')';
}, 1000 * 20);
};
img.src = 'http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime();
}
setInterval(function(){updateBg()}, 1000 * 60);
}
updateBackground();
</script>
</html>

You should notice that there are now two background images listed separated by commas. That's the new CSS 3 specification. Without any position, size, etc. differences, they both are full screen. The one to the left of the comma takes precedence when available. Otherwise the one to the right of the comma is seen. We start out with them both being the image itself. Then the next time we check, the dominant is updated with the latest version as soon as it loads, Then in about 20 seconds, the currently unseen one also updates, and then the process repeats. Each time a new one is available from the server and our code checks, it will use that one to overlay the previous one. The only way you could get smoother would be to use two elements and fade one out as the new one comes in or some similar type effect. But as it is, it's quite smooth compared to what it was.

Again, the browser may have to be refreshed and/or have its cache emptied to see changes.

Greg_M
04-06-2016, 06:01 PM
That new version is much better but still has a flicker when it updates....very close now

Greg_M
04-06-2016, 06:32 PM
If writing over it is an issue, by using absolute positioning you can make other things appear over an image, just as easily as over a background image.


Maybe that is the approach to work on since the current webpage picture reloads itself very seamlessly.

jscheuer1
04-06-2016, 07:59 PM
I think you missed a version:


<html>
<body>
Test
</body>
<script>
function updateBackground(){
var body = document.getElementsByTagName('body')[0], prevImg = 'http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime();
body.style.backgroundImage = 'url(' + prevImg + '), url(' + prevImg + ')';
function updateBg(){
var img = new Image();
img.onload = function(){
body.style.backgroundImage = 'url(' + this.src + '), url(' + prevImg + ')';
setTimeout(function(){
prevImg = img.src;
body.style.backgroundImage = 'url(' + prevImg + '), url(' + prevImg + ')';
}, 1000 * 20);
};
img.src = 'http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime();
}
setInterval(function(){updateBg()}, 1000 * 60);
}
updateBackground();
</script>
</html>

Remember you may need to refresh the browser and/or clear the cache to see changes.

I did another update that refreshes every half minute (still can't get an update that isn't there, but has less of a lag between when an update is available and when it's shown). But, even though that's better in a way, it's twice as many requests to the server. Unless you are certain to not have too many users, those requests could add up - maybe cause the page and/or the image to be unavailable for short, even long periods of time. I think that syncing to the server clock might be better. Do you have PHP? Even without it, an accurate user clock could be synced. But with it, even an inaccurate user clock could be synced. When exactly is the update available? It looks like every other odd minute to me, but is it right at the start of that odd minute or like 10 or 15 seconds after (looks like a slight delay - might just be network latency, or how long it takes to get the image from the cam to/over the internet), or my PC clock might be a hair fast compared to your server.

Greg_M
04-07-2016, 12:19 AM
WOW
That's seamless !
I think you've got it

Greg_M
04-07-2016, 12:23 AM
Is there a way to state the "size" ?

jscheuer1
04-07-2016, 02:09 AM
Is there a way to state the "size" ?

Yes, though I'm not 100% sure (since you quoted it) what you mean by that. Although not comprehensive, there are many new with CSS 3 size and scale related properties for the background element. I'm pretty sure there's one, or a way at least, to scale the image to the element, in this case that would be the window. The result would be no cropping, but the aspect ratio would be off in many cases (probably not too bad most of the time with an image such as this). Another option would be to center it. Then all cropping would be done evenly around the edges. But one can size it. Only problem there is, you don't know the window size, so it's just about like centering it (though we can get the window size using javascript and base the bg size on that if we decide to go that way). Maybe, mmm well let's think about this some more. Here's a link to what i think is the most relevant information on the specification for this (what can be set in CSS):

http://www.w3schools.com/css/css3_backgrounds.asp

Have a look at that, and consider what I've just said about it, and see if you get a feel for what you think you'd like best. Meanwhile, I'll do the same, or at least see what I think might be most applicable in this case.

This looks pretty good to me:


<html>
<head>
<style type="text/css">
body {
background-repeat: no-repeat;
background-position: center;
background-attachment: fixed;
background-size: cover;
}
</style>
</head>
<body>
Test
</body>
<script>
function updateBackground(){
var freq = 30; //seconds between polling server for new image
var body = document.getElementsByTagName('body')[0], prevImg = 'http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime();
body.style.backgroundImage = 'url(' + prevImg + '), url(' + prevImg + ')';
function updateBg(){
var img = new Image();
img.onload = function(){
body.style.backgroundImage = 'url(' + this.src + '), url(' + prevImg + ')';
setTimeout(function(){
prevImg = img.src;
body.style.backgroundImage = 'url(' + prevImg + '), url(' + prevImg + ')';
}, 1000 * freq / 3);
};
img.src = 'http://datilcam.com/cam/HCpic.jpg?cbust=' + new Date().getTime();
}
setInterval(function(){updateBg();}, 1000 * freq);
updateBg();
}
updateBackground();
</script>
</html>

I added some CSS in the head (highlighted) to control the size scaling, etc. And made the frequency a single configurable option (also highlighted). Set it to every 30 seconds, though you can set it back to 60 (or to whatever) if you like.

Greg_M
04-07-2016, 03:53 PM
Perfect

Now I have to research making/placing a weather sticker so I can put my weather station info on my webcam picture


Again
Thank You

jscheuer1
04-07-2016, 09:21 PM
Great! You're welcome. I was playing around with this a little more and thought, since I made the frequency a single configuration item, I should also make the url to the webcam image a single item as well. It's listed twice in the previous version. I also noticed that at certain width/height combinations the timestamp is cropped or even unseen. If that's important (not having it cropped or unseen), the background-position property in the head should be set to left top. I've done both in this version (changed the style and made the one config option for the url (changes highlighted):


<html>
<head>
<style type="text/css">
body {
background-repeat: no-repeat;
background-position: top left;
background-attachment: fixed;
background-size: cover;
}
</style>
</head>
<body>
Test
</body>
<script>
function updateBackground(){
var freq = 30; // seconds between polling server for new image
var imgurl = 'http://datilcam.com/cam/HCpic.jpg'; // url to the webcam image
var body = document.getElementsByTagName('body')[0], prevImg = imgurl + '?cbust=' + new Date().getTime();
body.style.backgroundImage = 'url(' + prevImg + '), url(' + prevImg + ')';
function updateBg(){
var img = new Image();
img.onload = function(){
body.style.backgroundImage = 'url(' + this.src + '), url(' + prevImg + ')';
setTimeout(function(){
prevImg = img.src;
body.style.backgroundImage = 'url(' + prevImg + '), url(' + prevImg + ')';
}, 1000 * freq / 3);
};
img.src = imgurl + '?cbust=' + new Date().getTime();
}
setInterval(function(){updateBg();}, 1000 * freq);
updateBg();
}
updateBackground();
</script>
</html>

Greg_M
04-08-2016, 10:13 PM
Very Nice!

Thanks

Greg_M
04-01-2017, 02:00 PM
Is there a way to put an active image at the bottom of the page?
Something that would be clickable and take the viewer to my weather page.

I've added what I know (some html) but I can't figure out how to get it to the bottom of the page and not spoil the utility (background image fits itself to all view-screens) of the page.

This is the domain page I have been experimenting on

http://www.oldthomasplace3.com/