Goal
Create a responsive slide for low ram devices.(immagine a set of many images at high resolution.. mobile device would crash).i want to show only one image and preload N images.
Scenario
Let's say i have 77 images (nI=77,variable).
Obiovsly i want to load the first image, but also want to preload 2 images per side (nP=2,variable).
That is a total of 5 boxes ( center, 2left, 2right ).nB=nP*2+1.
On init i want to disply the boxes/images as follows(the number is the image index)
[75][76][0][1][2]
0, the first image is atm the only visible image.
Now comes the tricky part.
If i press < (next) the static visualizzation is:
[76][0][1][2][3]
but every box moves! so if we start with a default position set:
[75][76][0][1][2]//image index
[ 0][ 1][2][3][4]//box index
[-2][-1][0][1][2]//box position
<
[76][0][1][2][ 3]//image index
[ 1][2][3][4][ 0]//box index
[-2][-1][0][1][2]//box position
Pressing left loads the the following image into the first box, moves the first box into the last position, every other box moves (one offsetwidth) to the left.
>
[74][75][76][0][1]//image index
[4][ 0][ 1][2][3]//box index
[-2][-1][0][1][2]//box position
Pressing right loads the the preceding image into the last box, moves the last box into the first position, every other box moves (one offsetwidth) to the right.
Some relevant js
var I=ARRAYOFIMAGES,
nI=images.length,
nP=2,
nB=nP*2+1,
nC=0,
slideWidth=slide.offsetWidth; // CURRENT IMAGE INDEX 200px variable
function defaultPos(a,b){//[-400, -200, 0, 200, 400]
for(a=[],b=0;b<nB;b++){
a[b]=(b-nP)*slideWidth
}
return a
}
function currentInd(a,b){//[75, 76, 0, 1, 2]
for(b=[],a=0;a<nB;a++){
b[a]=(a+nC-nP+nI)%nI
}
return b
}
function next(e){
nC=++nC%nI;
d=1; // direction
calculate()
}
function prev(e){
nC=(--nC+nI)%nI;
d=0;
calculate()
}
function calculate(){
//for(BOXES){
// if(ISIMAGE2CHANGE){box[l].style.backgroundImage='url('+I[IMAGEINDEX]+')')}
// box[l].style.webkitTransform='translate3d('+POSITION+'px'+',0,0)';
//}
}
Partially working DEMO
First Demo
http://jsfiddle.net/VfYR4/
New Demo (shorter but not loading proper image)
http://jsfiddle.net/7Nedw/1/
Note: adjust the delay to -webkit-transition:-webkit-transform 1000ms ease 1000ms; to see what is going on.
Problem
The math is wrong. if the index is 0 and i move backwards the positions and indexes are messed up.
the function returns the wrong index to load,position and in which box to load.
Give your HTML markup like this
<img src="" data-src="images/1.jpg" alt="img0"/>
<img src="" data-src="images/2.jpg" alt="img1"/>
<img src="" data-src="images/3.jpg" alt="img2"/>
<img src="" data-src="images/4.jpg" alt="img3"/>
And use this method, when you will press your left or right button:
function preLoadImages() {
var $image = $(".my-image");
var $imageUnloaded = $(".my-image[src='']");
for(var i=current;i<current+4;i++) { //(current+1) is image index shown to user
var j = (i+$image.length)%$image.length;
console.log("Image to be loaded : "+j);
var $this = $($image[j]);
if($this.attr('src') == '') {
$this.attr('src',$this.data('src'));
}
}
}
You can change the logic slightly if you want to change the number of preload images on each side.
Related
Hello,
I'm doing a website with a javascript slider. I want to use only specific images from one folder for the slider, not all of the img in the DOM. Because I'm adding more img which shouldn't be part of the slider....
I'm using this script:
$(function(){
var i= 0;
//when the next button is clicked on
$('.next').on("click", function(){
//increase the display picture index by 1
i = i + 1;
//if we are at the end of the image queue, set the index back to 0
if (i == $('img').length) {
i=0;
}
//set current image and previous image
var currentImg = $('img').eq(i);
var prevImg = $('img').eq(i-1);
//call function to animate the rotation of the images to the right
animateImage(prevImg, currentImg);
});
//when the previous button is clicked on
$('.previous').on("click", function(){
//if we are at the beginning of the image queue, set the previous image to the first image and the current image to the last image of the queue
if (i==0) {
prevImg = $('img').eq(0);
i=$('img').length-1;
currentImg = $('img').eq(i);
}
//decrease the display picture index by 1
else {
i=i-1;
//set current and previous images
currentImg = $('img').eq(i);
prevImg = $('img').eq(i+1);
}
//call function to animate the rotation of the images to the left
animateImageLeft(prevImg, currentImg);
});
//function to animate the rotation of the images to the left
function animateImageLeft(prevImg, currentImg) {
//move the image to be displayed off the visible container to the right
currentImg.css({"left":"100%"});
//slide the image to be displayed from off the container onto the visible container to make it slide from the right to left
currentImg.animate({"left":"0%"}, 1000);
//slide the previous image off the container from right to left
prevImg.animate({"left":"-100%"}, 1000);
}
//function to animate the rotation of the images to the right
function animateImage(prevImg, currentImg) {
//move the image to be displayed off the container to the left
currentImg.css({"left":"-100%"});
//slide the image to be displayed from off the container onto the container to make it slide from left to right
currentImg.animate({"left":"0%"}, 1000);
//slide the image from on the container to off the container to make it slide from left to right
prevImg.animate({"left":"100%"}, 1000);
}
});
Thank you for any help!
Instead of calling $('img') every time you need the list of images, maintain the array of the images that you want displayed.
For example, if you can give all the img tags for the slider class="slider-img" to make this selection easier.
var imgs = $('img.slider-img');
And replace $('img') in your code with imgs.
Or if you want from all the images served from a specific web address or "folder", you can do the following:
var address = "example.com/silder_imgs";
var imgs = $('img').filter(function() { return $(this).attr(a).includes(address) });
I don't want to play animation,I want to chage sprite's frames by clicking right and left buttons.
var sprite = game.add.sprite(200, 100, 'mySprite');
sprite.frame = 3;
Now, if a right button is pressed I want this sprite goes to next frame
sprite.frame += 1;
If left button is pressed, sprites goes to the previous frame.
sprite.frame -= 1;
If left is pressed and current frame is 0 the sprite does not change it's frame, it stops on frame 0. I want the sprite goes from 0 to the last frame when I click left button.
For example, in Actionscript 3, I can do this:
sprite.gotoAndStop(sprite.totalFrames);
Is there "totalFrames" in Phaser/JS?
I did not find any answer, I have created a custom variable 'totalFrames' for all objects. The first frame is 0, then 1 and so on...
if (rightClick)
{
objects.frame += 1;
}
else if (leftClick)
{
if (objects.frame > 0)
{
objects.frame -= 1;
}
else
{
objects.frame = objects.totalFrames;
}
}
A bit late, buy you could try Phaser.GameObjects.Sprite.anims.getTotalFrames()
Im trying to create a slider that uses an increment/decrement to move and then hide or show the buttons depending on the max number of images in the row. It uses a div within a div, with an overflow of hidden that should move until the max number of images is hit, this is when the arrow should be hidden so the person cannot just keep going into the white space created by the overflow. However, the hide/shows do not work and the person can just keep incrementing because the arrow is still visible even after the max number of images has been reached.
How do I get the left and right arrows to hide when they hit the respective numbers?
Edit: i know the .css is messed-up, i just want to get the arrows to hide/ show first, thanks
var pressCounter = 0;
var maxImgCounter = $('.carousel-image').length; // gain the max amount of images
var maxSlide = maxImgCounter - 4;// - the amount of images visible on the screen so it does notshow white space
if ( pressCounter < maxSlide){
$('#right').show();
}else{
$('#right').hide();
}
if (pressCounter > 0){
$('#left').show();
}else{
$('#left').hide();
}
/* Left arrow */
$('#left').click(function(){
$( '.slide' ).css({
"position": "relative",
"right": -280 * pressCounter
});
pressCounter--;
return pressCounter;
});
/* Right arrow */
$('#right').click(function(){
$( '.slide' ).css({
"position": "relative",
"right": 280 * pressCounter
});
pressCounter++;
return pressCounter;
});
if ( pressCounter < maxSlide){
$('#right').show();
}else{
$('#right').hide();
}
if (pressCounter > 0){
$('#left').show();
}else{
$('#left').hide();
}
Consider what happens when the value is less than maxslide and presscounter is greater than zero. Pretty much, this condition will always be true the way you have it written so both if statements are firing each time - one after the other. The result is that your left and right arrows will always be displayed - allowing users to keep clicking past the last slide.
I am having a few more issues with a script. I am trying to achieve a responsive slide out div script for a "meet the team" page. The way I see it working is that when the persons image is clicked, it slides out their bio. I am running into a few issues though.
1) Script works fine until you click the 3rd or 4th image in the row:
When the 3rd image is clicked, it slides out the div fine, but creates a blank space on the next row (i'm assuming it is pushing the image onto a new line but also adding a margin...)
When the 4th image is clicked, it is creating the bio outside of the container. The only way I can see a fix for this would be to have it slide the opposite way for every 4th item in a row. I can add a counter class to the divs dynamically using my CMS, just not sure how to reference this in the javascript.
2) I'm unsure how to make it work responsively. I am dropping the container from 1/4 to 1/2 on tablet and mobile. So I need to basically double the margin and size of the bio container. How can I declare this in the script?
Many thanks in advance for any help. Credit to Trim Kadrui who helped me with the script so far.
JS Fiddle:
http://jsfiddle.net/QrfzA/21/
Script code:
$(document).ready(function() {
$('.team-photo').click(function() {
var teamBio = $(this).next();
var nextBlock = $(this).parent().next();
if(teamBio.width() > 0){
teamBio.animate({width: 0, opacity: 0});
nextBlock.animate({marginLeft: '0%'});
}
else {
teamBio.css("display", "inline-block");
teamBio.animate({width: '100%', opacity: 100});
nextBlock.animate({marginLeft: '25%'});
}
});
});
$(document).ready(function() {
$('.team-photo').click(function() {
var teamBio = $(this).next();
var nextBlock = $(this).parent().next();
if(teamBio.width() > 0){
nextBlock.css("clear", "none");
teamBio.animate({width: 0, opacity: 0});
nextBlock.animate({marginLeft: '0%'});
}
else {
teamBio.css("display", "inline-block");
teamBio.animate({width: '100%', opacity: 100});
if(nextBlock.position().left>10) {
nextBlock.animate({marginLeft: '25%'});
if(!nextBlock.next().length || nextBlock.next().position().left<10) {
nextBlock.animate({marginLeft: '0'});
nextBlock.css("clear", "both");
}
}
}
});
});
if(nextBlock.position().left>10) does the trick,basically it checks if the there are more than 10 pixels to the left of the nextBlock and then applies the margin left property.
I've checked to see if nextBlock.position().left is greater than 10,you can set it to suite your needs.
EDIT: nextBlock.next().position().left<10 was also needed to be checked in case,the image is last but one in that line. CSS property clear:both was used to send the nextblock to the new line instead of using a margin.
Here is the updated JSFiddle.
I have this :
<div id="randomp" style="position:absolute;top:3px;left:3px;width:165px;height:29px;background:url(/logo2.png) no-repeat;background-size: 165px;"></div>
I want that the propierty "top" and "left" change every time you enter into the page. I mean that some times it appear on the right top corner, right bottom corner, left top corner and left bottom corner..
Here it is what i have tryied:
http://redzer.com.mx/tabla.html
I would probably start with the div styled as position:fixed and with display:none:
<div id="randomp" style="display:none;position:fixed;width:165px;height:29px;background:url(/logo2.png) no-repeat;background-size: 165px;"></div>
Then use jQuery to determine the position CSS to set and turn on visibility
$(document).ready(function() {
// get jQuery object for the div
var $randomp = $('#randomp');
// determine whether to show top or bottom, left or right
var top = Math.round(Math.random()); // generate 0 or 1 value
if (top === 1) {
$randomp.css('top', '3px');
} else {
$randomp.css('bottom', '3px');
}
var left = Math.round(Math.random());
if (left === 1) {
$randomp.css('left', '3px');
} else {
$randomp.css('right', '3px');
}
// show the div
$randomp.show();
});
Of course, you could also use server-side code to do this, but since you asked specifically about javascript/jquery in your tags, I suggested this solution.
I think i got exactly what you need.
EXAMPLE
With javascript i am generating random numbers for the top and left positioning of your image every time you visit the page.
Right now i set them up to get a random number between 0 and 100 but you can change that to whatever you want.
var random1 = Math.ceil(Math.random() * 100);
var random2 = Math.ceil(Math.random() * 100);
$(document).ready(function () {
$('#randomp').css('top', random1);
$('#randomp').css('left', random2);
});