I have a PSD file with a bunch of layers that are frames for an animation. How can I create an animation from this using JQuery/JavaScript?
Will I have to save each layer as a separate image, is there a way to have the one image with multiple layers animated? To clarify, I don't want the actual image to move, I just want different layers to be displayed as if they were frames of an animation. What's the standard way this is done with JavaScript?
Thanks!
Here is a fiddle that demonstrates the javascript timer + individual images approach.
Fiddle: http://jsfiddle.net/ZVFu8/2/
The basic idea is to create an array with the names of your images.
var img_name_arr = [];
var img_name_root = "anim-";
var img_name_ext = ".gif";
var num_images = 12;
// init arr of img names assuming frames are named [root]+i+[extension]
for (i = 0; i<=num_images; i++) {
img_name_arr.push(img_name_root + i + img_name_ext);
}
For the animation, use setInterval(). In javascript, an interval executes periodically. You specify the code to execute and the interval at which the code should be run (in milliseconds).
Every time your interval is called, you can display a new image by setting the "src" attribute of the image tag to the next index in the image_name array.
// Create an interval, and save a handle to the interval so it can be stopped later
anim_interval = setInterval(function() {
$("#player").attr("src", s + img_name_arr[(anim_frame++ % num_images)+1] );
}, frame_interval);
Depending on how long your animation is and how large each image file is, it might be necessary to optimize this by pre-loading these images. Before the animation starts, you could create an img tag for each image and hide it. Then, instead of altering the "src" attribute to change the image, you would actually hide the current image and un-hide the next image in the previous image's place.
Here is the full code if you wish to run this locally:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<a id="anim_control" href="">Start</a>
<img id="player" src="" />
<script>
var s = "http://" + atob("YmVucmlkb3V0LmNvbQ==") + "/";
var img_name_arr = [];
var img_name_root = "anim-";
var img_name_ext = ".gif";
var num_images = 12;
var framerate = 1; // Desired frames per second
var frame_interval = 1000/framerate;
$(function(){
// Document is ready
// init arr of img names
for (i = 0; i <= num_images; i++) {
img_name_arr.push(img_name_root + i + img_name_ext);
}
var anim_interval = null;
var playing = false;
var anim_frame = 0;
// Define an interval that will execute every [frame_interval] milliseconds
$("#anim_control").on("click", function(e) {
e.preventDefault();
if (playing == true) {
playing = false;
$(this).html("Start");
clearInterval(anim_interval);
} else {
playing = true;
$(this).html("Stop");
anim_interval = setInterval(function() {
//console.log(s + img_name_arr[(anim_frame++ % num_images)+1]);
$("#player").attr("src", s + img_name_arr[(anim_frame++ % num_images)+1] );
}, frame_interval);
}
});
});
</script>
<style>
#player {
width: 320px;
height: 240px;
border: 1px solid #000;
}
</style>
Related
I have a simple image rotator on a website consisting of 4 images that have to appear for a few seconds before showing the next one. It seems to work on its first cycle but then when it gets back to the first image it doesn't show that one but works again from the second image and so on always missing that image on every cycle.
The function is called using onLoad EH in the body. In the body there is an img with my first image inside it. I'm a noob so please be gentle if I've missed anything out.
Here's what I have...
<body onLoad="sunSlideShow()">
<img src="IMAGES/slider1.gif" alt="slide-show" id="mySlider" width="900">
<body>
var quotes = new Array ("slider2.gif", "slider3.gif" ,"slider4.gif", "slider1.gif");
var i = 0
function sunSlideShow()
{
document.getElementById("mySlider").src = ( "IMAGES/" + quotes[i] );
if (i<4)
{
i++;
}
else
i = 1;
setTimeout("sunSlideShow()", 3000);
}
sunSlideShow()
Change it to this:
else
i = 0;
setTimeout("sunSlideShow()", 3000);
Further to my other answer (which was wrong!)... Try this:
http://jsfiddle.net/pq6Gm/13/
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
setInterval(sunSlideShow,3000);
});
var quotes = [
"http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2007/07/11/sun128.jpg",
"http://icons.iconarchive.com/icons/robinweatherall/seasonal/128/sun-icon.png",
"http://www.astronomytoday.com/images/sun3.gif",
"http://mariusbancila.ro/blog/wp-content/uploads/2011/08/sun.png"
];
var i = 0;
function sunSlideShow() {
document.getElementById("mySlider").src = quotes[i];
if (i < (quotes.length-1))
{
i++;
}
else
{
i = 0;
}
}
</script>
<body>
<img src="http://mariusbancila.ro/blog/wp-content/uploads/2011/08/sun.png" id="mySlider"/>
</body>
==================================================================
EDIT: This is wrong... please find my other answer on this page.
==================================================================
To start with, I wouldn't use ... you're better off starting the script with jquery once the page is loaded.
Add this to your head section:
<script type="text/javascript">
$(function () {
sunSlideShow();
}
</script>
That will fire the sunSlideShow function once the page is loaded.
Then, you're starting your slideshow with var i = 0... but when you've got to the fourth image, you're setting it to 1?
I would be tempted to use a while loop to achieve what you want.
Something like this:
<script type="text/javascript">
$(function () {
sunSlideShow();
}
var quotes = new Array ("slider2.gif", "slider3.gif" ,"slider4.gif", "slider1.gif");
var i = 0;
function sunSlideShow(){
while (i<4)
{
document.getElementById("mySlider").src = ( "IMAGES/" + quotes[i] );
if (i<4)
{
i++;
}
else
{
i = 0;
}
sleep(3000);
}
}
function sleep(miliseconds){
var currentTime = new Date().getTime();
while (currentTime + miliseconds >= new Date().getTime()){}
}
</script>
This script hasn't been tested... but it should start the sunSlideShow function once the page has loaded and then change the image every 3 seconds.
I too searched the web trying to find a general solution to the problem of rotating an image about its center. I came up with my own solution which works perfectly. The basic concept is simple: rotate the entire context by the desired angle (here called 'tilt'); calculate the image's coordinates in the NEW coordinate system; draw the image; lastly, rotate the context back to its original position. Here's the code:
var xp = rocketX * Math.cos(tilt) - rocketY * Math.sin(tilt);
var yp = rocketX * Math.sin(tilt) + rocketY * Math.cos(tilt);
var a = rocketX - xp;
var c = Math.sqrt(a*a + (rocketY-yp)*(rocketY-yp));
var beta = Math.acos(a/c);
var ap = c * Math.cos(tilt + beta);
var bp = c * Math.sin(tilt + beta);
var newX = rocketX + ap;
var newY = rocketY - bp;
context.rotate(tilt);
context.drawImage(littleRocketImage, newX-9, newY-40);
context.rotate(-tilt);
In the penultimate line, the constants '9' and '40' are half the size of the image; this insures that the rotated image is placed such that its center coincides with the center of the original image.
One warning: I use this only for first quadrant rotations; you'll have to put in the standard tests for the other quadrants that change the signs of the components.
Update: 2021
You can use the light-weight library Ad-rotator.js to setup simple Ad-rotation like this -
<script src="https://cdn.jsdelivr.net/npm/ad-rotator"></script>
<script>
const instance = rotator(
document.getElementById('myelement'), // a DOM element
[ // array of ads
{ url: 'https://site1.com', img: 'https://example/picture1.jpg' },
{ url: 'https://site2.com', img: 'https://example/picture1/picture2.jpg'},
// ...
]
);
</script>
<body onLoad="instance.start()">
<div id="myelement"></div>
<body>
Reference Tutorial
I'm having trouble finding any good information on how to make a javascript(or jquery) progress bar WITH text that tells you the percentage.
I don't want a plug in, I just want to know how it works so that I can adapt it to what I need. How do you preload images and get a variable for the number of images that are preloaded. Also, how do you change html/css and-or call a function, based on the number of images that are loaded already?
<img> elements have an onload event that fires once the image has fully loaded. Therefore, in js you can keep track of the number of images that have loaded vs the number remaining using this event.
Images also have corresponding onerror and onabort events that fire when the image fails to load or the download have been aborted (by the user pressing the 'x' button). You also need to keep track of them along with the onload event to keep track of image loading properly.
Additional answer:
A simple example in pure js:
var img_to_load = [ '/img/1.jpg', '/img/2.jpg' ];
var loaded_images = 0;
for (var i=0; i<img_to_load.length; i++) {
var img = document.createElement('img');
img.src = img_to_load[i];
img.style.display = 'hidden'; // don't display preloaded images
img.onload = function () {
loaded_images ++;
if (loaded_images == img_to_load.length) {
alert('done loading images');
}
else {
alert((100*loaded_images/img_to_load.length) + '% loaded');
}
}
document.body.appendChild(img);
}
The example above doesn't handle onerror or onabort for clarity but real world code should take care of them as well.
What about using something below:
$('#btnUpload').click(function() {
var bar = document.getElementById('progBar'),
fallback = document.getElementById('downloadProgress'),
loaded = 0;
var load = function() {
loaded += 1;
bar.value = loaded;
/* The below will be visible if the progress tag is not supported */
$(fallback).empty().append("HTML5 progress tag not supported: ");
$('#progUpdate').empty().append(loaded + "% loaded");
if (loaded == 100) {
clearInterval(beginLoad);
$('#progUpdate').empty().append("Upload Complete");
console.log('Load was performed.');
}
};
var beginLoad = setInterval(function() {
load();
}, 50);
});
JSFIDDLE
You might also want to try HTML5 progress element:
<section>
<p>Progress: <progress id="p" max=100><span>0</span>%</progress></p>
<script>
var progressBar = document.getElementById('p');
function updateProgress(newValue) {
progressBar.value = newValue;
progressBar.getElementsByTagName('span')[0].textContent = newValue;
} </script>
</section>
http://www.html5tutorial.info/html5-progress.php
I'm working on making a JS script that will go in the header div and display a few pictures. I looked into JQuery Cycle, but it was out of my league. The code I wrote below freezes the browser, should I be using the for loop with the timer var?
<script type="text/JavaScript" language="JavaScript">
var timer;
for (timer = 0; timer < 11; timer++) {
if (timer = 0) {
document.write('<img src="images/one.png">');
}
if (timer = 5) {
document.write('<img src="images/two.png">');
}
if (timer = 10) {
document.write('<img src="images/three.png">');
}
}
</script>
Thanks!
Assuming you want a script to rotate images and not just write them to the page as your code will do, you can use something like this:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="target"></div>
<script>
var ary = ["images/one.png","images/two.png","images/three.png"];
var target = document.getElementById("target");
setInterval(function(){
target.innerHTML = "<img src=\""+ary[0]+"\" />";
ary.push(ary.shift());
},2000);
</script>
</body>
</html>
Of course the above code has no effects (like fading) which jQuery will give yous, but it also doesn't require loading the entire jQuery library for something so basic.
How about just running the script after the page loads?
<script>
// in <head> //
function load() {
var headDiv = document.getElementById("head");
var images = ["images/one.png", "images/two.png"];
for(var i = 0; i<images.length; i++) {
image = document.createElement("img");
image.src = images[i];
headDiv.appendChild(image);
}
}
</script>
Then use <body onload="load();"> to run the script.
Edit
To add in a delay loading images, I rewrote the code:
<script>
// in <head> //
var displayOnLoad = true; // Set to true to load the first image when the script runs, otherwise set to false to delay before loading the first image
var delay = 2.5; // seconds to delay between loading images
function loadImage(url) {
image = document.createElement("img");
image.src = images[i];
headDiv.appendChild(image);
}
function load() {
var headDiv = document.getElementById("head");
var images = ["images/one.png", "images/two.png"];
for(var i = 0; i<images.length; i++) {
setTimeout(loadImage(images[i]), (i+displayOnLoad)*(delay*1000));
}
}
</script>
Set displayOnLoad = false; if you want to wait the specified delay before loading the first image. The delay is set in seconds. I recommend waiting over a single second between images, as they may take some time to download (depending on the user's internet speed).
As with the first snippet, I haven't tested the code, so please tell me if an error occurs, and I will take a look.
Since you used the jquery tag on your question, I assume you are OK with using jQuery. In which case, you can do something like this:
In your static HTML, include the img tag and set its id to something (in my example, it's set to myImg) and set its src attribute to the first image, e.g.:
<img id="myImg" src="images/one.png">
Next, use jQuery to delay execution of your script until the page has finished loading, then use setTimeout to create a further delay so that the user can actually spend a few seconds looking at the image before it changes:
<script>
var imgTimeoutMsecs = 5000; // Five seconds between image cycles
$(function() {
// Document is ready
setTimeout(function() {
// We will get here after the first timer expires.
// Change the image src property of the existing img element.
$("#myImg").prop("src", "images/two.png");
setTimeout(function() {
// We will get here after the second, nested, timer expires.
// Again, change the image src property of the existing img element.
$("#myImg").prop("src", "images/three.png");
}, imgTimeoutMsecs);
}, imgTimeoutMsecs);
});
</script>
Of course, that approach doesn't scale very well, so if you are using more than three images total, you want to modify the approach to something like this:
var imgTimeoutMsecs = 5000; // Five seconds between image cycles
// Array of img src attributes.
var images = [
"images/one.png",
"images/two.png",
"images/three.png",
"images/four.png",
"images/five.png",
];
// Index into images array.
var iCurrentImage = 0;
function cycleImage() {
// Increment to the next image, or wrap around.
if (iCurrentImage >= images.length) {
iCurrentImage = 0;
}
else {
iCurrentImage += 1;
}
$("#myImg").prop("src", images[iCurrentImage]);
// Reset the timer.
setTimeout(cycleImages, imgTimeoutMsecs);
}
$(function() {
// Document is ready.
// Cycle images for as long as the page is loaded.
setTimeout(cycleImages, imgTimeoutMsecs);
});
There are many improvements that can be made to that example. For instance, you could slightly simplify this code by using setInterval instead of setTimer.
The code you've provided simply iterates through the for loop, writing the images to the browser as it does so. I suggest you take a look at JavaScript setTimeout function.
JS Timing
Because of this background image's fadeInOut transitions produces weird effect in white all the texts i decided to program my own custom image rotator with fadeinout effect
var intervalo;
var i= 0;
var photos = [
"http://toniweb.us/gm/img/galeria/fondo1.jpg",
"http://toniweb.us/gm/img/galeria/fondo2.jpg",
"http://toniweb.us/gm/img/galeria/fondo3.jpg",
"http://toniweb.us/gm/img/galeria/fondo4.jpg"
];
function rotarFondo(){
var container = $('#headerimgs');
var current = container.children('div:visible:first');
var imgSrc = photos[i];
i++;
if(i == photos.length)
i = 0;
console.log(imgSrc);
var next = (current.next().length > 1) ? current.next() : container.children('div:visible');
current.css('background',imgSrc);
next.css('background',imgSrc);
current.fadeOut(300);
next.fadeIn(300);
}
function congelarFondo(){
}
$(document).ready(function(){
if (intervalo )
clearInterval(intervalo );
intervalo = setInterval('rotarFondo()',1000);
});
the interval thing and the image calculation seems to work fine, but i don't know why the bgImgaes are actually not being applied,
Testing here for now http://jsfiddle.net/bE9Dq/27/
any idea??
Well for starters it might save you some time and a few headaches to use one of these plugins:
http://buildinternet.com/project/supersized/
http://bavotasan.com/2011/full-sizebackground-image-jquery-plugin/
(I've used them both)
First thing I've noticed with your code is you may need to set the background image as follows:
.css('background-image','url(' + imgSrc + ')');
Also notice on the second line ( the next.) you are still using imgSrc I think you mean to use imgSrc1 instead?
i am writing a animation with javascript and want to print to user loading time until all images loaded.
images set in html as: <img src="" />
are there javascript code to know when all page loaded?
i.e time until onLoad() event called
You might be able to do something like this at the bottom of the page
<span id="imgsMsg"></span>
<script type="text/javascript">
var imgs = document.images;
var len = imgs.length;
var percent = 100;
var count=0;
var messagecontainer = document.getElementById("imgsMsg");
for (var i=0;i<len;i++) {
imgs[i].onload=function() {
count++;
messagecontainer = (percent - Math.floor((100/len)*count))+"% loaded"; // hope my math is correct ;)
}
}
</script>
</body>
The best you can probably do is to track the number of images that have been loaded, and divide that into the total number of images remaining. Something like this:
var total_loaded = 0;
$('img').load(function()
{
total_loaded += 1;
var load_progress = total_loaded / $('img').length;
// you can now use load_progress to show the user a rough progress animation
} );
If you want a "time remaining" display, you'll need to fake it. You could track the total time elapsed and compare that to the load_progress variable to get the remaining time, for example.
This isn't hard to do, with $(window).load:
var readytime = new Date().getTime();
$(window).load(function() {
var loadingtime = (new Date().getTime() - readytime) / 1000; // in seconds
$('#yourTimingField').text(loadingtime + ' seconds');
});
This measures the amount of time between the this part of the script and the loading of all subelements.