Advanced Slider Customization - javascript

I am trying to achieve below image type of slider using Superslides and Bxslider.
Slider Explanation:
Black boxes are points/stops.
Blue box is car.
Whenever car crosses the half way stop,I need to change the red slider to next one.
User can use mouse scroll or arrow keys to move car forward or backward & on mobile using swipe forward or backward.
What I have done using Superslides and Bxslider
Using callback functions of bxslider to animate the car, but stuck.
Help: I need ideas how to achieve such result.What kind of slider I can use to acheieve something like this.
Reference link but with jQuery

(function($) {
var elem = $.jInvertScroll(['.scroll'], // an array containing the selector(s) for the elements you want to animate
{
height: 6000, // optional: define the height the user can scroll, otherwise the overall length will be taken as scrollable height
onScroll: function(percent) { //optional: callback function that will be called when the user scrolls down, useful for animating other things on the page
console.log(percent);
}
});
$(window).resize(function() {
if ($(window).width() <= 768) {
elem.destroy();
}
else {
elem.reinitialize();
}
});
}(jQuery));
html,
body
{
padding: 0;
margin: 0;
font-family: Arial, sans-serif;
}
/* hide horizontal scrollbars, since we use the vertical ones to scroll to the right */
body
{
overflow-x: hidden;
background: url('../images/bg.jpg') repeat top left;
}
h1
{
font-size: 20px;
font-weight: normal;
color: #2e6e80;
}
/**
* important: keep position fixed, you can however use top:0 instead of bottom:0
* if you want to make it stick to the top of the browser
*/
.scroll
{
position: fixed;
bottom: 0;
left: 0;
}
/**
* z-index ordering of the different layers, do this for your layers,
* also assign absolute width (to prevent issues if the script gets executed before the images get loaded)
*/
.horizon
{
z-index: 1;
width: 3000px;
}
.middle
{
z-index: 500;
width: 4000px;
}
.front
{
z-index: 1000;
width: 6000px;
}
<h1>jInvertScroll Example</h1>
<div class="horizon scroll">
<img src="https://raw.githubusercontent.com/pixxelfactory/jInvertScroll/master/examples/images/horizon.png" alt="" />
</div>
<div class="middle scroll">
<img src="https://raw.githubusercontent.com/pixxelfactory/jInvertScroll/master/examples/images/middle.png" alt="" />
</div>
<div class="front scroll">
<img src="https://raw.githubusercontent.com/pixxelfactory/jInvertScroll/master/examples/images/front.png" alt="" />
</div>
<script src="http://www.pixxelfactory.net/jInvertScroll/js/jquery.min.js"></script>
<script src="http://www.pixxelfactory.net/jInvertScroll/js/jquery.jInvertScroll.js"></script>

Related

Hiding scrollbar and making custom scrollbar

So I wanted to make a page like https://www.guillaumetomasi.com/ .How can I hide the scrollbar and make a custom one like that in the page.
With CSS attributes like overflow-x: hidden and overflow-y: hidden you can hide scrollbars.
The custom scrollbar and the scrolling proccess is controlled by Javascript via and events.
The thing is simple and that's, they are not using any scrolling at all, but what you feel is a modified scroll for those slides is actually a slideshow built by JavaScript functionalities. These side slideshow are nowadays in trend and gives you a feel of pseudo scroll. It will be better if you would ask how to achieve that slideshow in a web page instead of that scrolling...
The scroll bar can be hidden with css ::-webkit-scrollbar {width: 0px;}
The custom scroll bar is made with javascript. Here's an example of how it could be done:
window.addEventListener("scroll", function() {
var section1 = document.getElementById("section1");
var section2 = document.getElementById("section2");
var section3 = document.getElementById("section3");
var indicator = document.getElementById("scroll-indicator");
if (window.scrollY < section2.offsetTop ) { // If scroll height is above section 2
indicator.innerText = "1"
}
if (window.scrollY > (section1.offsetTop + section1.offsetHeight)) { // If scrolled past section 1
indicator.innerText = "2"
}
if (window.scrollY > (section2.offsetTop + section2.offsetHeight)) {// If scrolled past section 2
indicator.innerText = "3"
}
});
p {
position: fixed;
right: 15%;
top: 50%;
color: black;
font-size: 24px;
font-family: arial;
}
::-webkit-scrollbar {
width: 0px; /*This removes the scroll bar*/
}
<div id="section1" style="height: 500px; background-color: lightblue">Scroll Down</div>
<div id="section2" style="height: 500px; background-color: pink">Keep scrolling</div>
<div id="section3" style="height: 500px; background-color: Khaki">Almost there</div>
<p id="scroll-indicator">1</p>

jquery pan a large image within small div container using buttons

Hi there I need to an interactive element using a large image. This image sized 1000x1000 pixel with simple imagery will contain several questions with yes or no. What I want to do is place this image within a small div (say 500x300) with hidden overflow and add hotspots on the image for the yes/no option. What I want is when the user clicks yes, then the hotspot link pans to specific x/y coordinates of the same large image. Viewer will only see within the 500x300 window. So on and so forth. Is this possible? It seems so simple yet only option I can find is the pan by mouse option or iframe option with complicated divs and anchors. I'm not an expert in java/jquery but would love to find a script that is adaptable. Please help!
This sounded fun so I made a custom solution real quick. Demo here: jsBin
It's heavily reliant on the proper CSS, so check that in the bin, but here's the JS part:
var choice = document.querySelectorAll('.choice'),
image = document.getElementById('image')
for ( var i=0; i<choice.length; i++) {
choice[i].addEventListener('click', function (event) {
var x = this.dataset['x'],
y = this.dataset['y'];
image.style.top = '-'+y+'px';
image.style.left = '-'+x+'px';
})
}
Use css transitions for animation. Set up the positions you want the buttons to move the image around to in the image using a series of javascript objects. Then, set up your anchors, text, etc using absolute positioning on top of the image inside of a div container. Finally, add a click action in jQuery to assign your different positions to the top and left css of that container.
The end result, then, will be that you click an anchor, the left and top positions are assigned to the container via css in jQuery, and the transitions will slide the image around with the anchors.
I set up a fiddle here.
Here's the html from the fiddle:
<div id="window">
<div id="container">
<img src="http://upload.wikimedia.org/wikipedia/en/1/1f/Kill_The_Lights_1000x1000.jpg" id="image">
<ul>
<li><a id="city" href="#">City</a></li>
<li><a id="bottom" href="#">Bottom</a></li>
</ul>
</div>
</div>
And the CSS:
#window {
width:500px;
height:300px;
overflow:hidden;
position:relative;
}
#window a {
position: absolute;
z-index: 2;
display: block;
padding: 10px;
background: rgba(255,255,255,.5);
}
#city {
top: 20px;
left: 20px;
}
#bottom {
top: 220px;
left: 220px;
}
#container {
-webkit-transition:left 2s, top 2s, -webkit-transform 2s;
transition:left 2s, top 2s, transform 2s;
position: absolute;
z-index: 1;
top: 0px;
left: 0px;
}
Here's some javascript to give an example of setting up the positions as objects.
var city = {
top: -200,
left: -200
};
var bottom = {
top: -700,
left: -100
}
$('a').click(function() {
var t = this.id;
var c = $('#container');
if (typeof eval(t) !== 'undefined') {
c.css({
'top': eval(t).top,
'left': eval(t).left
});
}
});
I've just made a Fiddle with a demo image from where you could proceed.
HTML:
<div class="imgHolder">
<div class="hotspot one">Click</div>
<img src="image.jpg" />
</div>
CSS:
.imgHolder {
overflow:hidden;
width:300px;
height:300px;
position:relative;
}
.hotspot.one {
position:absolute;
top:10px;
padding:2px;
background-color:#fff;
left:10px;
}
.hotspot:hover {
cursor:pointer;
}
img {
position:relative;
z-index:-1;
}
jQuery:
$(".hotspot").on("click", function () {
$("img").animate({
"right": "+=100px"
});
});
For reference: http://api.jquery.com/animate/
You could e.g. fade hotspots in and out on specific positions and use animate() to move to the next hotspot.

Slide panel in from right

I'm trying to replicate the effect on this website in the portfolio section where it slides a panel in the full size of the viewport and then slides it out when you click close.
Example here: http://alwayscreative.net/#portfolio
Here's my current markup:
<section class="panel" id="portfolio">
<section class="content">
<h1>What are you <strong>interested</strong> in?</h1>
<a class="btn-portfolio" id="btn-commercial" href="#">Commercial</a>
<a class="btn-portfolio" id="btn-residential" href="#">Residential</a>
</section>
</section>
The .panel section is 100% height and width of the viewport and I'd like 2 different panels to be able to slide in — one for #btn-commercial and one for #btn-residential.
Any ideas how to make this happen?
If it helps any, here's my site so far: http://www.freshbrand.ca/testlink/top40/#portfolio
Here's how you would do it with JQuery but clearly you can do it in normal javascript if you prefer. Set up the panels with position absolute in your css:
.panel {
position: absolute;
top: 0;
height: 100%;
border-width: 0;
margin: 0;
}
.panel inactive{
display: none;
}
.panel active {
display: block;
left: 0;
width: 100%;
height: 100%;
}
in your javascript (after the dom has loaded) get the screen dimensions and set the positions of the inactive elements to just off the right hand edge of the screen:
$('.panel').css('width', screen.innerWidth);
var setup = function() {
$('.portfolio-panel.inactive').css('left', window.innerWidth);
$('.portfolio-panel.active').css('left', 0);
}
setup();
When you wish to slide a panel in from the right, pass its id to the following function:
var slideIn = function(panelId) {
$('#' + panelId).animate({
left: 0
}, 400, function () { // animates the #left property from the screen width down to zero (i.e. slide it in from the right hand edge of the screen)
// tidy up
$('.portfolio-panel.active').removeClass('active').addClass('inactive');
$('#'+panelId).removeClass('inactive').addClass('active');
setup();
});
};
EDIT: The event handler would look something like this:
$('.btn-portfolio').click(function() {
slideIn($(this).attr('id').substr(4)); // extract the panel name from the id and pass it into slideIn
});
The only remaining issue is to eliminate the horizontal scroll bar you will probably see during the animation. Just add overflow-x: hidden; to the element to which the scroll bar belongs (probably body, but it depends on how you've structured and styled the rest of your site)
This is basically a single page website, a lot of jQuery plugins are available for the same.
I personally prefer
http://joelb.me/scrollpath/
Check out it's demo and download the code from github's link
https://github.com/JoelBesada/scrollpath
Hope this helps

Infinity Loop Slider Concepts

I wonder what are the best(good readable code, pest practice code,reusability) concepts to build a Infinity-Image-Loop-Slider for a Website using JavaScript/jQuery? I dont what to know how to code the Slide show but what blueprint matches the requirements mention above.
The main focus of my question is how to arrange the pictures to get the impression of a infinity loop Slider.
By look at Code from different Sliders I came across two solutions:
-change the z-Index of all Images each time the next/previous image is displayed.
-change the Position of the Image in the DOM.
But examine and understanding the code of others is very time-consuming - that's why I ask this question :-)
tl;dr - JSBin Example: http://jsbin.com/ufoceq/8/
A simple approach to create an infinite image slider without too much effort is as follows: let say for the sake of simplicity that you have <n> images to slide in a loop, so that after the nth image the next one to visualize is the 1st (and vice-versa).
The idea is to create a clone of first and last image so that
the clone of the last image is prepended before the first one;
the clone of the first image is appended after the last one.
Whatever is the amount of your images, you will need to append at most only 2 cloned elements.
Again for the simplicity, let say that all images are 100px wide and they're wrapped in a container that you move left/right into a clipped mask with overflow: hidden. Then, all images can be easily aligned in a row with display: inline-block and white-space: nowrap set on the container (with flexbox now it is even easier).
For n = 4 The DOM structure would be something like this:
offset(px) 0 100 200 300 400 500
images | 4c | 1 | 2 | 3 | 4 | 1c
/* ^^ ^^
[ Clone of the last image ] [ Clone of the 1st image ]
*/
At the beginning, your container will be positioned with left: -100px (or also margin-left: -100px or even better (for a matter of performance) transform: translateX(-100px) ), so the slider can show the first image. To switch from an image to another you will need to apply a javascript animation over the same property you've previously chosen.
When your slider is currently at the 4th image, you have to switch from image 4 to 1c, so the idea is to execute a callback at the end of the animation that soon reposition your slider wrapper at the real 1st image offset (e.g. you set left: -100px to the container)
This is analogous when your slider is currently positioned on the 1st element: to show the previous image you just need to perform an animation from image 1 to 4c and when animation has been completed you just move the container so the slider is istantly positioned at the 4th image offset (e.g. you set left: -400px to the container).
You can see the effect on the above fiddle: this is the minimal js/jquery code I used (of course the code can be even optimized so the width of the items is not hardcoded into the script)
$(function() {
var gallery = $('#gallery ul'),
items = gallery.find('li'),
len = items.length,
current = 1, /* the item we're currently looking */
first = items.filter(':first'),
last = items.filter(':last'),
triggers = $('button');
/* 1. Cloning first and last item */
first.before(last.clone(true));
last.after(first.clone(true));
/* 2. Set button handlers */
triggers.on('click', function() {
var cycle, delta;
if (gallery.is(':not(:animated)')) {
cycle = false;
delta = (this.id === "prev")? -1 : 1;
/* in the example buttons have id "prev" or "next" */
gallery.animate({ left: "+=" + (-100 * delta) }, function() {
current += delta;
/**
* we're cycling the slider when the the value of "current"
* variable (after increment/decrement) is 0 or when it exceeds
* the initial gallery length
*/
cycle = (current === 0 || current > len);
if (cycle) {
/* we switched from image 1 to 4-cloned or
from image 4 to 1-cloned */
current = (current === 0)? len : 1;
gallery.css({left: -100 * current });
}
});
}
});
});
As mentioned before, this solution doesn't require really much effort and talking about performance, comparing this approach to a normal slider without looping, it only requires to make two additional DOM insertion when the slider is initialized and some (quite trivial) extra logic to manage a backward/forward loop.
Here is another example when you see two elements at once: in that case you need to clone more elements and make some simple changes to the logic
https://codepen.io/fcalderan/pen/bGbjZdz
I don't know if a simpler or better approach exists, but hope this helps anyway.
Note: if you need to also have a responsive gallery, maybe this answer may help too
I've just created the item slider: check it out:
https://github.com/lingtalfi/jItemSlider/blob/master/README.md
It's 600 lines of code, maybe you can simply browse it.
The idea behind it is inspired by the netflix slider (as of 2016-02-24).
Basically, it uses css transform translations, because those are the fastest/slickest in a browser.
http://eng.wealthfront.com/2015/05/19/performant-css-animations/
Now the basic concept behind the slide movement, is that you only display the current visible slice,
but you also have one invisible slice on the left, and another invisible slice on the right.
And, you also have two extra items, one on each side, so that your items look like this:
previous items - prev extra item - main items - next extra item - next items
Only the main items are visible.
The extra items are partially visible.
The previous and next items are invisible.
More details here:
https://github.com/lingtalfi/jItemSlider/blob/master/doc/conception.md
Now when you slide to the right (for instance), you basically append more items to the right side,
and then remove those from the left side.
This technique is the greatest I've encountered so far, because you don't deal with a long list of items (using
cloning without removing the invisible items), which can make your animation slower.
Note: my first try of this slider was actually cloning without removing, it works, but I don't like it:
https://github.com/lingtalfi/jInfiniteSlider
Also, it's item based (rather than pixels based), and in the end, that's what the user expects because
everything is always aligned, as it should be.
Vanila Javascript!! No-clone technique, getElementsByClassName to the rescue
document.getElementsByClassName selection is a live collection; any changes in DOM is updated in the stored variable unlike querySelector method.
In this technique, we just shift the first slide to the end if we reach the last slide while clicking right or we shift the last slide at the beginning when we reach the first slide while clicking left. Clone creation is not required here. The getElementsByClassName method gives us a live HTML collection to work with which updates as we make changes in the DOM. (In this case, changes in the order of divs)
Here is my GitHub Repository
// slider
const slides = document.getElementsByClassName("slide"); // this selection is a live collection; any changes in DOM is updated in the variable unlike querySelectors
const btnLeft = document.querySelector(`.btn-left`);
const btnRight = document.querySelector(`.btn-right`);
let currentSlideIndex = 0;
let lastSlideIndex = slides.length - 1;
// go to a slide;
function goToSlide(slideIndex) {
[...slides].forEach((s, i) => {
s.style.transform = `translateX(${100 * (i - slideIndex)}%)`
})
currentSlideIndex = slideIndex;
}
goToSlide(currentSlideIndex);
// make ready the next slide if current slide is the first or the last slide
function readyNextSlide() {
// if currentSlide is the last slide, shift the first slide to the end
if (currentSlideIndex === lastSlideIndex) {
slides[lastSlideIndex].insertAdjacentElement("afterend", slides[0]);
slides[lastSlideIndex].style.transform = `translateX(${100}%)`;
currentSlideIndex--; //this is because current slide is now the second last slide
}
// if currentSlide is the first slide, shift the last slide to the beginning
if (currentSlideIndex === 0) {
slides[0].insertAdjacentElement("beforebegin", slides[lastSlideIndex]);
slides[0].style.transform = `translateX(-${100}%)`;
currentSlideIndex++; //this is because current slide is now the second slide
}
}
// put the last slide in the beginning; ('if' condition is not necessary but providing if condition is future proof if user sets the initial slide to be shown as the last slide )
if (currentSlideIndex === lastSlideIndex || currentSlideIndex === 0) readyNextSlide();
// shift all slides left or right based on direction provided
function shiftSlides(direction) {
direction ? currentSlideIndex++ : currentSlideIndex--
if (currentSlideIndex === lastSlideIndex || currentSlideIndex === 0) readyNextSlide();
goToSlide(currentSlideIndex);
}
//button click events
btnRight.addEventListener("click", shiftSlides.bind(null, 1));
btnLeft.addEventListener("click", shiftSlides.bind(null, 0));
body {
display: grid;
height: 100vh;
width: 100vw;
align-items: center;
align-content: center;
justify-content: center;
}
.slider {
position: relative;
width: 600px;
height: 300px;
transform: scale(0.8);
overflow: hidden; /* remove overflow to see what's going on*/
}
.slide {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
transition: transform 1s;
}
.slide b {
position: absolute;
font-size: 10em;
color: black;
opacity: 0.6;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.s1 {
background-color: cornflowerblue;
}
.s2 {
background-color: bisque;
}
.s3 {
background-color: coral;
}
.s4 {
background-color: thistle;
}
.btn {
position: absolute;
top: 50%;
z-index: 10;
border: none;
background: crimson;
font-family: inherit;
color: white;
height: 5.5rem;
width: 5.5rem;
font-size: 3.25rem;
cursor: pointer;
}
.btn-left {
left: 6%;
transform: translate(-50%, -50%);
}
.btn-right {
right: 6%;
transform: translate(50%, -50%);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Infinity Looping Rotating slider</title>
<link rel="stylesheet" href="slider.css">
<script src="slider.js" defer></script>
</head>
<body>
<div class="slider">
<div class="slide s1"><b>1</b></div>
<div class="slide s2"><b>2</b></div>
<div class="slide s3"><b>3</b></div>
<div class="slide s4"><b>4</b></div>
<button class="btn btn-left">←</button>
<button class="btn btn-right">→</button>
</div>
<p>
<b>
This is my response to a questing in StackOverflow about infinity loop slider.<br>
My github repo is Infinity loop Slider by Dibakash
</b>
</p>
</body>
</html>
Thanks a lot of this article!
I had update and used above code.
I hope this will help everyone.
Poor developer.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Directive slider</title>
<style>
/* 四联切换焦点图 */
.slides-wrapper{ position: relative; width: 100%; margin: 10px 0; }
.gallery { position: relative; width: 1200px; height: 180px; overflow:hidden; }
.gallery ul { font-size: 0; white-space: nowrap; position: absolute; top: 0; left: -1200px; margin: 0; padding: 0; }
.gallery li { display: inline-block; vertical-align: top; width: 1200px; height: 180px; white-space: normal; }
.gallery li img{ width: 298px; height:180px; padding: 1px; }
.gallery .arrow { background: url(/shop/templates/default/images/home_bg.png) no-repeat; background-size: 150px 223px; width: 35px; height: 70px; position: absolute; z-index: 2; top: 50px; cursor: pointer; opacity: 0;}
.gallery .prev { background-position: 1px -92px; left: 0;}
.gallery .next { background-position: -30px -92px; right: 0px;}
</style>
<style type="text/css">
.demo_wrapper{
margin: 0 auto;
width: 1200px;
}
.demo_wrapper .title{
text-align: center;
}
</style>
</head>
<body>
<div class="demo_wrapper">
<div class="title">
<h1>Directive slider (Published by fenmingyu)</h1>
</div>
<!-- demo content -->
<div class="slides-wrapper">
<div class="gallery" id="top_sale_gallery">
<ul>
<li>
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-1.jpg?234" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-2.jpg?752" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-3.jpg?320" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-4.jpg?365" alt="">
</li>
<li>
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-1.jpg?852" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-2.jpg?746" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-3.jpg?525" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-4.jpg?550" alt="">
</li>
</ul>
<div class='arrow prev'></div>
<div class='arrow next'></div>
</div>
<div class="gallery" id="top_goods_gallery">
<ul>
<li>
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-1.jpg?793" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-2.jpg?180" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-3.jpg?550" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-4.jpg?851" alt="">
</li>
<li>
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-1.jpg?234" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-2.jpg?752" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-3.jpg?320" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-4.jpg?365" alt="">
</li>
<li>
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-1.jpg?852" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-2.jpg?746" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-3.jpg?525" alt="">
<img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-4.jpg?550" alt="">
</li>
</ul>
<div class='arrow prev'></div>
<div class='arrow next'></div>
</div>
<div style="clear: both;"></div>
</div>
</div>
</body>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function() {
$.fn.gallery = function(settings) {
var defaults = {
time: 3000,
direction:1
};
var settings = $.extend(defaults, settings);
var gallery_wrapper = $(this),
gallery = gallery_wrapper.find('ul'),
items = gallery.find('li'),
len = items.length,
current = 1, /* the current item we're looking */
first = items.filter(':first'),
last = items.filter(':last'),
w = gallery.find('li').width(),
triggers = gallery_wrapper.find('.arrow');
var show_slide = function(direction,w){
gallery.animate({ left: "+=" + (-w * direction) }, function() {
current += direction;
/**
* we're cycling the slider when the the value of "current"
* variable (after increment/decrement) is 0 or when it exceeds
* the initial gallery length
*/
cycle = !!(current === 0 || current > len);
if (cycle) {
/* we switched from image 1 to 4-cloned or
from image 4 to 1-cloned */
current = (current === 0)? len : 1;
gallery.css({left: -w * current });
}
});
};
var picTimer = setInterval(function() {
show_slide(settings.direction,w);
},
settings.time);
return this.each(function(){
/* 1. Cloning first and last item */
first.before(last.clone(true));
last.after(first.clone(true));
/* 2. Set button handlers */
triggers.on('click', function() {
if (gallery.is(':not(:animated)')) {
var cycle = false;
settings.direction = ($(this).hasClass('prev'))? -1 : 1;
/* in the example buttons have id "prev" or "next" */
show_slide(settings.direction,w);
}
clearInterval(picTimer);
picTimer = setInterval(function() {
show_slide(settings.direction,w);
},
settings.time);
});
/* hover show arrows*/
show_slide(settings.direction,w);
gallery_wrapper.hover(function() {
$(this).find(".arrow").css("opacity", 0.0).stop(true, false).animate({
"opacity": "0.3"
},
300);
},function(){
$(this).find(".arrow").css("opacity", 0.3).stop(true, false).animate({
"opacity": "0"
},
300);
});
});
};
$('#top_goods_gallery.gallery').gallery();
$('#top_sale_gallery.gallery').gallery({
time: 5000,
direction:-1
});
});
</script>
</html>
te and use this in my project.

grow/shrink image gallery with jquery WITHOUT affecting the layout

I got an image gallery organized as an <ul>. all images are in <li> elements and when I move my mouse over one of those pictures, it should grow to give the user a visual feedback. thing is, when I just change the size of the image using animate(), the other pictures will be pushed to the side as the resized image uses more space.
therefore I went with cloning the image element, float it right over the original image and then calling animate. this comes with the problem that onMouseOut() is called as soon as the cloned images pops up. so I need a nested hover() function and this is where things got complicated.
I got two errors and I can't find out whats causing them. the first one is, that animate() won't let the cloned image grow beyond the right border of its original, the second is, that I get weird grow/shrink behavior, when moving my mouse quickly over the gallery.
html:
<ul id="gallery1" class="gallery_container">
<li class="frame">
<img src="pic1.jpg" class="picture" /></li><li class="frame">
<img src="pic2.jpg" class="picture" /></li><li class="frame">
<img src="pic3.jpg" class="picture" /></li>
</ul>
css:
.picture
{
height: 200px;
border: 0px;
margin: 0px;
padding: 0px;
}
.frame
{
display: inline-block;
position: relative;
margin: 0px;
margin-right:8px;
padding: 0px;
}
.frame a
{
padding: 0px;
margin: 0px;
}
.gallery_container
{
height: 200px;
width: 150%;
position: relative;
top: 4px;
padding: 0px;
margin: 0px;
}
and finally the code that is giving me those headaches:
$(document).ready(function()
{
var zooming = false;
var zoom = 4;
var speed_zoom = 100;
$('.gallery_container li a').hover(function(element)
{
// disable zooming to prevent unwanted behavior
if(zooming) return;
zooming = true;
$(this).after( $(this).clone(false) );
$(this).next().attr('id', 'focus_frame');
},
function(element) // when the new element pops up, onmouseout is triggered, since the focus_frame is in front of the image
{
$(this).next().hover(function(element)
{
// we need to re-position the element in the dom-tree, since it needs to grow out of a container with overflow: hidden
$('#focus_frame img').animate({'left' : zoom * -1, 'top' : zoom * -1, 'height' : 200+(zoom*2), 'width' : $('#focus_frame img').outerWidth() + (zoom*2)}, speed_zoom);
},
function(element)
{
$(this).remove();
zooming = false;
});
});
});
var $doc=$(document.body)
$doc.on({
"mouseenter" : function (e) {
$doc.find("> .gallery_clone").remove();
var $i=$(this).parent();
$i.pos = $i.offset();
$i.clone()
.addClass("gallery_clone "+$i.parent().parent().attr("class"))
.css({
top:(Math.round($i.pos.top)-3)+"px"
,left:(Math.round($i.pos.left)-3)+"px"
,width:$i.width()
}).appendTo($doc);
}
},
" ul > li > img"
).on ({
"mouseleave" : function (e) {
$(this).remove();
},"> .gallery_clone");
in css .gallery_clone is position:absolute
then i animate .gallery_clone:hover through css but you can do it in the jquery as well i guess, adding a mouseenter event on .gallery_clone
edit : i've literally copy/pasted from my script so you'll have to adapt this code to your html
nb: give css anim a go, it's worth it even if older ie will not animate; (i also made lightbox effect almost pure css for that same gallery - will publish later, not ready for plugin release just now sorry)
nb2: that part "+$i.parent().parent().attr("class") is because in the cms they can chose gallery background color so adding that class forward the background color & other gallery style to the clone (ie you should not need it)

Categories

Resources