I have 7 images and each image has 25 frames. What I need to do is that wander around each image by frames and display it as a video which can be controlled by play, pause and stop buttons.
What I can do is that making a video player that I can easily import a video and play, pause, stop in it. I designed it already but do not have any idea how to make a video from a list of images.
You can view the images at these URLs:
-http://storage.googleapis.com/alyo/assignments/images/0.jpg
- http://storage.googleapis.com/alyo/assignments/images/6.jpg
Any help will be appreciated.
You can achieve it using javscript setTimeout() method and div element like that:
var left = 0;
var top = 0;
var minLeft = -512;
var minBottom = -288;
var xDecrement = 128;
var yDecrement = 72;
var myImage = document.getElementById("myImage");
var imgIndex = 0;
let imageList = ['http://storage.googleapis.com/alyo/assignments/images/0.jpg','http://storage.googleapis.com/alyo/assignments/images/6.jpg'];
var playbackStates = {"INIT":0, "RUNNING": 1 , "PAUSE":2};
var activeState = playbackStates.INIT;
myImage.style.backgroundPositionX = "0px";
myImage.style.backgroundPositionY = "0px";
var timerHandler = null;
var play = function(){
if(timerHandler){
clearTimeout(timerHandler);
if(activeState === playbackStates.PAUSE){
return;
}
}
timerHandler = setTimeout(function(){
let pos =parseFloat(myImage.style.backgroundPositionX.replace("px",""));
myImage.style.backgroundPositionX = ( pos - xDecrement) + "px";
if(pos <= -512){
myImage.style.backgroundPositionX ="0px";
pos =parseFloat(myImage.style.backgroundPositionY.replace("px",""));
myImage.style.backgroundPositionY = ( pos - yDecrement) + "px";
if(pos <= -288){
myImage.style.backgroundPositionY = "0px";
imgIndex ++;
if(imageList.length <= imgIndex) return;
myImage.style.backgroundImage = "url("+imageList[imgIndex]+")";
}
}
play();
}, 160)
};
myImage.style.backgroundImage = "url("+imageList[imgIndex]+")";
play();
activeState = playbackStates.RUNNING;
function pause(){
activeState = playbackStates.PAUSE;
}
function resume(){
activeState = playbackStates.RUNNING;
play();
}
<div style="width:128px;height:72px;" id="myImage"></div>
<input type="button" onclick="pause()" value="Pause"/>
<input type="button" onclick="resume()" value="Resume"/>
You can add all your image url's in "imageList" array, also adjust the speed by modify the timeout interval.
Related
The result I want to achieve:keep clicking the mouse and a bunch of little “heart” images will pop up according to the coordinates of each click of the mouse. In other words, one click will pop up one image on the coordinates of your mouse.
Then after 1 second, the image begin to disappear.The earlier appeared image will also disappear early.
My problem is: the image will not disappear appropriately unless I delete the clearInterval code. Here’s the code:
// when click, an image pop up
// use addEventListener to do so
// let timer = 0;
let imgList = [];
document.addEventListener("click",function(event){
let img = document.createElement("img");
img.style.position = "absolute";
img.style.left = (event.clientX - 32) + "px";
img.style.top = (event.clientY - 32) + "px";
img.src = "https://placehold.it/64x64.png";
document.body.appendChild(img);
imgList.push({
img:img,
opacity:1,
scale:1,
frame:0
});
});
var timer = setInterval(draw, 1000);
function draw(){
if (imgList.length < 1) {
clearInterval(timer);
timer = null;
}
else {
imgList[0].img.remove();
imgList.splice(0, 1);
}
}
The problem is you're cancelling your interval timer when there aren't any images, so if the user doesn't create an image within a second (and within a second after that, etc.), the timer will get cancelled and no further images will be removed.
I wouldn't use an interval timer for this, I'd use a single timer (setTimeout) you create specifically for the added image:
document.addEventListener("click",function(event){
let img= document.createElement("img");
img.style.position="absolute";
img.style.left=(event.clientX-32)+"px";
img.style.top=(event.clientY-32)+"px";
img.src="1.png";
document.body.appendChild(img);
// Remove it after one second
setTimeout(() => {
img.remove();
}, 1000);
});
You can add a load event listener to a added image and within the handler remove it with a timeout. Generic snippet, maybe it's useful for your code:
const addImage = (i = 1) => {
let img = document.createElement("img");
img.src = "https://img.icons8.com/metro/2x/like.png";
img.addEventListener("load", () =>
setTimeout(() => document.body.removeChild(img), i*1000));
// ^add load event/timeout here
document.body.appendChild(img);
}
for (let i=0; i < 5; i += 1) {
addImage(i);
}
document.addEventListener("click", () => addImage(1));
<button>Add image</button>
If the intent is to remove the images 1 second after each other you should set the timer inside the "click" callback. This way you can add the interval if it is not yet set.
If the intent is to display each image a maximum of 1 second this is not the answer you're looking for.
let imgList = [];
let timer;
document.addEventListener("click",function(event){
let img = document.createElement("img");
img.style.position = "absolute";
img.style.left = (event.clientX - 32) + "px";
img.style.top = (event.clientY - 32) + "px";
img.src = "https://placehold.it/64x64.png";
document.body.appendChild(img);
imgList.push({
img:img,
opacity:1,
scale:1,
frame:0
});
if (!timer) {
timer = setInterval(draw, 1000);
}
});
function draw(){
if (imgList.length < 1) {
clearInterval(timer);
timer = null;
}
else {
imgList[0].img.remove();
imgList.splice(0, 1);
}
}
I have two arrays : The first with images paths and the second is with different duration and I am trying using the following functions to set dynamically the 'setTimeout' of my 'changeImage()' function as follow:
function changeImage(){
var img = document.getElementById("img");
img.src = images[x];
var ztme = tme[x];
x++;
if(x >= images.length){
x = 0;
}
fadeImg(img, 100, true);
setTimeout("changeImage()",ztme ); //This is the problem!
}
function fadeImg(el, val, fade){
if(fade === true){
val--;
}else{
val ++;
}
if(val > 0 && val < 100){
el.style.opacity = val / 100;
setTimeout(function(){fadeImg(el, val, fade);}, 10);
}
}
var images = [],
x = 0;
images[0] = "daki/eco_pic.jpg";
images[1] = "daki/art_tnt.gif";
images[2] = "daki/mkv_uk.jpg";
images[3] = "daki/bolo_trt.jpg";
images[4] = "daki/folo_fr.jpg";
var tme = [], //values of 'Time' for a picture to stay displayed
tme[0]= 10000;
tme[1]= 50000;
tme[2]= 2000;
tme[3]= 30000;
tme[4]= 5000;
setTimeout("changeImage()", 15000);
If I give a fixed number for the timeout everything is working like a charm. Therefore to set it dynamically generates just errors.
Any idea to let this changeImage() function get dynamically the time?
Am gratefull to any help.
Thank you in advance.
Your tme array is not properly initialized.you should used semi column after its declaration;
var tme = []; //<=
tme[0]= 10000;
tme[1]= 50000;
tme[2]= 2000;
tme[3]= 30000;
tme[4]= 5000;
setTimeout("changeImage()", 15000);
I have a slideshow that I am triggering with a call from a link. The slideshow is working well. I am having problems stopping AND clearing the slideshow. I have a temporary link that I am calling the stopShow function that is stopping the show, but is not clearing it so I can then redisplay other items.
// JavaScript Document
var imagePaths = ["_sites/BBB_homepage.png","_sites/CabezonKidsDental_homepage.png","_sites/djer_homepage.png","_sites/enchanted_homepage.png","_sites/JoeSSausage_homepage.png","_sites/MMCS_homepage.png","_sites/mySRB.png","_sites/PHCP_homepage.png","_sites/smilesforkidsnm_homepage.png","_sites/t2consulting_homepage.png","_sites/Upward_homepage.png","_sites/Webb_based_homepage.png"];
var showCanvas = null;
var showCanvasCtx = null;
var img = document.createElement("img");
var currentImage = 0;
var revealTimer;
var stopShow = 0;
var slideTImer;
function slideShow() {
if (!stopShow){
showCanvas = document.getElementById('Canvas1');
showCanvasCtx = showCanvas.getContext('2d');
//clear canvas
showCanvasCtx.clearRect(0,0,showCanvasCtx.canvas.width,showCanvasCtx.canvas.height);
//set image size and call switch function
img.setAttribute('width','500');
img.setAttribute('height','400');
switchImage();
//start the animation
slideTimer = setInterval(switchImage,3000);
}
}
function switchImage() {
//set img element source property to images in slideshow
img.setAttribute('src',imagePaths[currentImage++]);
//if past the last image, loop
if (currentImage >= imagePaths.length)
currentImage = 0;
//fade into image by 10th of full saturation
showCanvasCtx.globalAlpha = 0.1;
revealTimer = setInterval(revealImage,100);
}
function revealImage() {
showCanvasCtx.save();
showCanvasCtx.drawImage(img,100,0,500,400);
showCanvasCtx.globalAlpha += 0.1;
if (showCanvasCtx.globalAlpha >= 1.0) clearInterval(revealTimer);
showCanvasCtx.restore();
}
function stopSlideShow() {
//alert('stop show');
clearInterval(slideTimer);
clearInterval(revealTimer);
stopShow=1;
showCanvas = document.getElementById('Canvas1');
showCanvasCtx = showCanvas.getContext('2d');
//clear canvas
showCanvasCtx.clearRect(0,0,showCanvasCtx.canvas.width,showCanvasCtx.canvas.height);
}
This is wrong!
showCanvasCtx.canvas.width
The object model of the canvas works this way:
Canvas -> Context
the width and height parameters are not in the Context but in the Canvas itself. So, considering you got them this way in your code:
showCanvas = document.getElementById('Canvas1');
showCanvasCtx = showCanvas.getContext('2d');
you should get the dimensions of the canvas like this:
showCanvas.width
showCanvas.height
By removing if (!stopShow){ call, and clearing the canvas in the stopSlideShow function, the function works as desired. It was necessary to set the globalAlpha to 1 in the stopSlideShow function. The ending code looks like this:
// JavaScript Document
var imagePaths = ["_sites/BBB_homepage.png","_sites/CabezonKidsDental_homepage.png","_sites/djer_homepage.png","_sites/enchanted_homepage.png","_sites/JoeSSausage_homepage.png","_sites/MMCS_homepage.png","_sites/mySRB.png","_sites/PHCP_homepage.png","_sites/smilesforkidsnm_homepage.png","_sites/t2consulting_homepage.png","_sites/Upward_homepage.png","_sites/Webb_based_homepage.png"];
var showCanvas = null;
var showCanvasCtx = null;
var img = document.createElement("img");
var currentImage = 0;
var revealTimer;
var stopShow = 0;
var slideTImer;
function slideShow() {
showCanvas = document.getElementById('Canvas1');
showCanvasCtx = showCanvas.getContext('2d');
//clear canvas
showCanvasCtx.clearRect(0,0,showCanvas.width,showCanvas.height);
//set image size and call switch function
img.setAttribute('width','500');
img.setAttribute('height','400');
switchImage();
//start the animation
slideTimer = setInterval(switchImage,3000);
}
function switchImage() {
//set img element source property to images in slideshow
img.setAttribute('src',imagePaths[currentImage++]);
//if past the last image, loop
if (currentImage >= imagePaths.length)
currentImage = 0;
//fade into image by 10th of full saturation
showCanvasCtx.globalAlpha = 0.1;
revealTimer = setInterval(revealImage,100);
}
function revealImage() {
showCanvasCtx.save();
showCanvasCtx.drawImage(img,100,0,500,400);
showCanvasCtx.globalAlpha += 0.1;
if (showCanvasCtx.globalAlpha >= 1.0) clearInterval(revealTimer);
showCanvasCtx.restore();
}
function stopSlideShow() {
//alert('stop show');
clearInterval(slideTimer);
clearInterval(revealTimer);
stopShow=1;
img.setAttribute('src',100);
showCanvas = document.getElementById('Canvas1');
showCanvasCtx = showCanvas.getContext('2d');
showCanvasCtx.globalAlpha=1;
}
I'm using JavaScript to change CSS values to make a particular div fill the page when a button is clicked. But I would like make the change from small to filling the screen smooth. How do I do this with CSS or Javascript? This is currently how I'm changing the size of that div
function fullscreen(){ // called when button is clicked
var d = document.getElementById('viewer').style;
if(!isFullscreen){ // if not already fullscreen change values to fill screen
d.width = "100%";
d.height="100%";
d.position= "absolute";
d.left="0%";
d.top="0%";
d.margin="0 0 0 0";
isFullscreen = true;
}else{ // minimizie it
d.width="600px";
d.height="400px";
d.margin="0 auto";
d.position="relative";
isFullscreen = false;
}
}
How do I code the change from the full screen values to the minimized values to be a smooth transition instead of instantaneous?
Use jQuery'sanimate() function!
For example:
function fullscreen(){ // called when button is clicked
var o = {} // options
var speed = "fast"; // You can specify another value
if(!isFullscreen){ // if not already fullscreen change values to fill screen
o.width = "100%";
o.height="100%";
o.left="0%";
o.top="0%";
o.margin="0 0 0 0";
$("#viewer").animate(o,speed);
isFullscreen = true;
}else{ // minimize it
o.width="600px";
o.height="400px";
o.margin="0 auto";
$("#viewer").animate(o,speed);
isFullscreen = false;
}
}
You can do this by using Jquery, .animate() API see the reference .animate()
I have created a small demo using .animate() click the Demo to see the example.
What you want to do is rather complicated, first you need to get the absolute position and dimension of your element in the document, also the dimension of the document itself, there is no native cross-platform javascript functions for that but there are known techniques to find out those values, do a search. So assuming you will implement these functions yourself: getAbsoluteLeft(), getAbsoluteTop(), getWidth(), getHeight(), getDocWidth() and getDocHeight() here is the animating code (not tested):
function fullscreen(){ // called when button is clicked
var e = document.getElementById('viewer');
var d = e.style;
if(!isFullscreen){ // if not already fullscreen change values to fill screen
var duration = 1000 //milliseconds
var framesPerSecond = 24;
var beginLeft = getAbsoluteLeft( e );
var beginTop = getAbsoluteTop( e );
var beginRight = beginLeft + getWidth( e );
var beginBottom = beginTop + getHeight( e );
var endLeft = 0;
var endTop = 0;
var endRight = getDocWidth();
var endBottom = getDocHeight();
var totalFrames = duration / (1000/framesPerSecond);
var frameNo = 0;
var leftStep = (beginLeft - endLeft) / totalFrames;
var topStep = (beginTop - endTop) / totalFrames;
var rightStep = (endRight - beginRight) / totalFrames;
var bottomStep = (endBottom - beginBottom) / totalFrames;
var func = function () {
var left = beginLeft - leftStep * frameNo;
var top = beginTop - topStep * frameNo;
d.left = left+'px';
d.top = top+'px';
d.width = (beginRight + rightStep * frameNo - left)+'px';
d.height = (beginBottom + bottomStep * frameNo - top)+'px';
++frameNo;
if( frameNo == totalFrames ) {
clearInterval( timer );
d.width = "100%";
d.height="100%";
d.left="0%";
d.top="0%";
isFullscreen = true;
}
}
d.position= "absolute";
d.margin="0 0 0 0";
timer = setInterval( func, 1000 / framesPerSecond );
} else { // minimizie it
d.width="600px";
d.height="400px";
d.margin="0 auto";
d.position="relative";
isFullscreen = false;
}
}
In this demo http://www.htmldrive.net/items/demo/527/Animated-background-image-with-jQuery
This code is for one background only. I want to add multiple background with different direction and speed.
var scrollSpeed = 70;
var step = 1;
var current = 0;
var imageWidth = 2247;
var headerWidth = 800;
var restartPosition = -(imageWidth - headerWidth);
function scrollBg(){
current -= step;
if (current == restartPosition){
current = 0;
}
$('#header').css("background-position",current+"px 0");
}
var init = setInterval("scrollBg()", scrollSpeed);
Currently it has settings for
$('#header').css("background-position",current+"px 0");
In a website I want to use this effect on #footer or #content background also. but with different speed and direction.
And is there any better and more optimized jquery method to achieve same effect?
And can we get same effect using CSS 3, without javascript?
Just saw the OP's answer, but decided to post anyway:
I've created a jQuery plugin to do this:
(function($) {
$.fn.scrollingBackground = function(options) {
// settings and defaults.
var settings = options || {};
var speed = settings.speed || 1;
var step = settings.step || 1;
var direction = settings.direction || 'rtl';
var animStep;
// build up a string to pass to animate:
if (direction === 'rtl') {
animStep = "-=" + step + "px";
}
else if (direction === 'ltr') {
animStep = '+=' + step + "px";
}
var element = this;
// perform the animation forever:
var animate = function() {
element.animate({
backgroundPosition: animStep + " 0px"
}, speed, animate);
};
animate();
};
})(jQuery);
Usage:
$("#header").scrollingBackground({
speed: 50,
step: 50,
direction: 'ltr'
});
This is pretty basic, and assumes that you're background-repeat is 'repeat-x' on the element you call it on. This way, there's no need to reset the background position every so often.
Working example: http://jsfiddle.net/andrewwhitaker/xmtpr/
I could work out the following solution. Am not sure if it is efficient. Will wait for anyone to comment or provide a better option.
Till then...:
var scrollSpeed = 70;
var step = 1;
var current = 0;
var images =
[
{
imageWidth:2247,
imagePath:"images/image1"
},
{
imageWidth:1200,
imagePath:"images/image2"
}
]
var headerWidth = 800;
var imageRotateCount = 0;
var imagesLength = images.length;
$('#header').css("background-image", images[0].imagePath);
function scrollBg(){
var curIndex = imageRotateCount%imagesLength;
var curImage = images[curIndex];
current -= step;
var restartPosition = -(curImage.imageWidth - headerWidth);
if (current == restartPosition){
current = 0;
imageRotateCount++;
curIndex = imageRotateCount%imagesLength;
curImage = images[curIndex];
$('#header').css("background-image", curImage.imagePath);
}
$('#header').css("background-position",current+"px 0");
}
var init = setInterval("scrollBg()", scrollSpeed);