Javascript slider pause function on hover - javascript

Looking for a little help with this slider that came with a Magento Template I purchased.
I'm trying to add a pause on hover and resume on mouse out but am very new to getting my hands this dirty with the JavaScript.
Hoping for a push in the right direction
Here is the code I'm working with
function decorateSlideshow() {
var $$li = $$('#slideshow ul li');
if ($$li.length > 0) {
// reset UL's width
var ul = $$('#slideshow ul')[0];
var w = 0;
$$li.each(function(li) {
w += li.getWidth();
});
ul.setStyle({'width':w+'px'});
// private variables
var previous = $$('#slideshow a.previous')[0];
var next = $$('#slideshow a.next')[0];
var num = 1;
var width = ul.down().getWidth() * num;
var slidePeriod = 3; // seconds
var manualSliding = false;
// next slide
function nextSlide() {
new Effect.Move(ul, {
x: -width,
mode: 'relative',
queue: 'end',
duration: 1.0,
//transition: Effect.Transitions.sinoidal,
afterFinish: function() {
for (var i = 0; i < num; i++)
ul.insert({ bottom: ul.down() });
ul.setStyle('left:0');
}
});
}
// previous slide
function previousSlide() {
new Effect.Move(ul, {
x: width,
mode: 'relative',
queue: 'end',
duration: 1.0,
//transition: Effect.Transitions.sinoidal,
beforeSetup: function() {
for (var i = 0; i < num; i++)
ul.insert({ top: ul.down('li:last-child') });
ul.setStyle({'position': 'relative', 'left': -width+'px'});
}
});
}
function startSliding() {
sliding = true;
}
function stopSliding() {
sliding = false;
}
// bind next button's onlick event
next.observe('click', function(event) {
Event.stop(event);
manualSliding = true;
nextSlide();
});
// bind previous button's onclick event
previous.observe('click', function(event) {
Event.stop(event);
manualSliding = true;
previousSlide();
});
// auto run slideshow
new PeriodicalExecuter(function() {
if (!manualSliding) nextSlide();
manualSliding = false;
}, slidePeriod);
}
Now I'm guessing the best way would be to manipulate a hover or mouseover observer similar to the next and previous ones to stop and start but I'm just not sure on how to set this up.
Would appreciate a push in the right direction!
Edit ....
So I'm getting much closer but I seem to have a problem yet hopefully someone who know about prototype can help.
I got it to work by adding this variable
var stopSliding = false;
and then adding an if like so
function nextSlide() {
if (!stopSliding) {
new Effect.Move(ul, {
x: -width,
mode: 'relative',
queue: 'end',
duration: 1.0,
//transition: Effect.Transitions.sinoidal,
afterFinish: function() {
for (var i = 0; i < num; i++)
ul.insert({ bottom: ul.down() });
ul.setStyle('left:0');
}
});
}
}
// previous slide
function previousSlide() {
if (!stopSliding) {
new Effect.Move(ul, {
x: width,
mode: 'relative',
queue: 'end',
duration: 1.0,
//transition: Effect.Transitions.sinoidal,
beforeSetup: function() {
for (var i = 0; i < num; i++)
ul.insert({ top: ul.down('li:last-child') });
ul.setStyle({'position': 'relative', 'left': -width+'px'});
}
});
}
}
then
ul.observe('mouseover', function(event) {
stopSliding = true;
});
ul.observe('mouseout', function(event) {
stopSliding = false;
});
This method works but only Safari will auto start my slideshow now and firefox needs interaction to trigger a start.
However I did find that switching the var to true at the start and switching around the order of the mouseovers it then auto starts fine in Firefox and not in Safari.
Had enough for this evening.

So I managed to get it to work in both Firefox, Safari, IE etc using:
Event.observe( window, 'load', function() { stopSliding = false; });
This ensures that my variable "stopSliding" is set.

Related

jquery plugin, settimeout and div not being append, simple weird case

I'm writing a jquery plugin the code below is not working (I mean the setTimeout is working but nothing is append)
var self = this;
for (var i=0; i<=10; i++) {
setTimeout(function() {
self.append(bubble);
}, 1000);
}
And the code below is working:
for (var i=0; i<=10; i++) {
this.append(bubble);
}
this is a jquery selection. I really don't get what's going on. It can't be scope issue .. can it be ? I don't get it. Thanks in advance for you help
Edit: bubble is a simple div (" ")
Below the whole plugin code:
(function($) {
'use strict';
$.fn.randomBubble = function(options) {
var self = this;
var settings = $.extend({
color: 'blue',
backgroundColor: 'white',
maxBubbleSize: 100
}, options);
var frame = {
height: this.height(),
width: this.width(),
}
var bubble = "<div class='randomBubble'> </div>";
this.getLeft = function(width) {
var left = Math.random() * frame.width;
if (left > (frame.width / 2)) {
left -= width;
} else {
left += width;
}
return left
}
this.getTop = function(height) {
var top = Math.random() * frame.height;
if (top > (frame.height / 2)) {
top -= height;
} else {
top += height;
}
return top
}
this.removeBubbles = function() {
var currentBubbles = this.find('.randomBubble');
if (currentBubbles.length) {
currentBubbles.remove();
}
}
window.oh = this;
for (var i = 0; i <= 10; i++) {
var timer = Math.random() * 1000;
setTimeout(function() {
window.uh = self;
self.append(bubble);
console.log("oh");
}, 1000);
}
this.randomize = function() {
//self.removeBubbles();
var allBubbles = this.find('.randomBubble');
allBubbles.each(function(i, el) {
var height = Math.random() * settings.maxBubbleSize;
var width = height;
$(el).css({
color: settings.color,
backgroundColor: settings.backgroundColor,
zIndex: 1000,
position: 'absolute',
borderRadius: '50%',
top: self.getTop(height),
left: self.getLeft(width),
height: height,
width: width
});
});
}
this.randomize();
//var run = setInterval(self.randomize, 4000);
return this.find('.randomBubble');
}
})(jQuery);
Because the bubbles are appended later due to the setTimeout(), this selector in your randomize() function comes up empty:
var allBubbles = this.find('.randomBubble');
That is why appending them in a simple for loop works fine.
If you really want to use the setTimout() to append your bubbles, one option is to style them when you add them:
setTimeout(function() {
var height = Math.random() * settings.maxBubbleSize;
var width = height;
var b = $(bubble).css({
color: settings.color,
backgroundColor: settings.backgroundColor,
zIndex: 1000,
position: 'absolute',
borderRadius: '50%',
top: self.getTop(height),
left: self.getLeft(width) ,
height: height,
width: width
});
self.append(b);
}, 1000);
Fiddle
Is it because you still call randomize() right away, even when you postpone the creation for one second?
You will also return an empty selection in that case, for the same reason.
Also, you probably want to use the timer variable in setTimeout() instead of hardcoding all to 1000 ms?
this is a javascript selection, the selector in jquery is $(this)
$.fn.randomBubble = function(options) {
var self = $(this);
};

jQuery - Morphing button concept - Problems

So I have created a simple morphing button concept. Everything seems good. Except from the fact that after opening and closing the button about 4-5 times, everything seems to mess up and get muddled.
Here is the Fiddle: https://jsfiddle.net/f793yvh5/22/
Here's part of the jQuery:
function Morphing( button, container, content) {
this.button = button;
this.container = container;
this.content = content;
this.overlay = $('div.overlay');
this.span = $('span.close');
var self = this; // so you have a reference to this this.
this.positions = {
endPosition : {
top: 100,
left: '50%',
width: 600,
height: 400,
marginLeft: -300
},
startPosition : {
top: self.container.css('top'),
left: self.container.css('left'),
width: self.container.css('width'),
height: self.container.css('height'),
marginLeft: self.container.css('margin-left')
}
};
}
Morphing.prototype.startMorph = function() {
var self = this;
this.button.on('click', function() {
$(this).fadeOut(200);
// Work on from here!
setTimeout(self.containerMove.bind(self), 200);
});
};
Morphing.prototype.containerMove = function() {
var self = this;
this.overlay.fadeIn();
this.container.addClass('active');
this.container.animate(this.positions.endPosition, 400, function() {
self.content.fadeIn();
self.span.fadeIn();
self.close();
});
};
Morphing.prototype.close = function() {
var self = this;
this.span.on('click', function() {
self.content.fadeOut();
self.span.fadeOut();
self.overlay.fadeOut();
setTimeout(self.animateBack.bind(self), 275);
});
};
Morphing.prototype.animateBack = function() {
var self = this;
this.container.animate(this.positions.startPosition, 400, function() {
self.button.fadeIn(300);
self.container.removeClass('active');
});
};
The other part:
$(document).ready(function() {
var morph = new Morphing( $('button.morphButton'), $('div.morphContainer'), $('h1.content, p.content') );
morph.startMorph();
});
To sum up, this is what jQuery is doing:
Button is clicked:
1. Button fades out,
2. Container behind the button is therefore visible,
3. Overlay fades in,
4. Container animates to center of screen,
5. Content in container fades in.
When the 'X' is pressed:
1. Content fades out,
2. Overlay fades out,
3. Container animates back to button,
4. Button fades in over the container.
Thanks.
Each time you call:
Morphing.prototype.close = function() {
var self = this;
this.span.on('click', function() {
self.content.fadeOut();
self.span.fadeOut();
self.overlay.fadeOut();
setTimeout(self.animateBack.bind(self), 275);
});
};
You define a on click for the span in your newContainer.
Add:
$.fn.once = function(a, b) {
return this.each(function() {
$(this).off(a).on(a,b);
});
};
at the end of your code and then:
Morphing.prototype.close = function() {
var self = this;
this.span.once('click', function() {
self.content.fadeOut();
self.span.fadeOut();
self.overlay.fadeOut();
setTimeout(self.animateBack.bind(self), 275);
});
};
and it should be ok.
Here is an updated Fiddle

Trying to get this script.aculo.us javascript slideshow to do what I want

So I had this slideshow working perfectly fine using .fade and .appear, but the people I'm doing this for weren't satisfied with that and they want it to behave like THIS ONE where the text overlay drops out and the image slides sideways and then the overlay pops back up.
script.aculo.us has a .DropOut, but not an opposite function so I am working with one I found elsewhere.
This is the code I have so far, but the slideshow isn't doing anything. It just loads the first image and overlay and that's it. No animation. I'm sure I have made some syntax mistakes somewhere, but it's valid and not giving any errors.
JSFiddle (includes html and css as well)
Note that this still doesn't accomodate the new image sliding in from the right, which I haven't found an effect for yet. For now I'd just be happy if this worked as is.
var i = 0;
var image_slide = new Array('image-1', 'image-2');
var overlay_slide = new Array('overlay-1', 'overlay-2');
var NumOfImages = image_slide.length;
var wait = 8000;
function SwapImage(x, y) {
$(overlay_slide[y]).DropOut({
duration: 0.5
});
$(overlay_slide[y]).fade({
duration: 0.1
});
$(image_slide[x]).appear({
duration: 0.5
});
$(image_slide[y]).Move({
x: -1000,
y: 0,
mode: 'relative',
duration: 0.5
});
$(overlay_slide[x]).appear({
duration: 0.1
});
$(overlay_slide[x]).Emerge({
duration: 0.5
});
}
function StartSlideShow() {
play = setInterval(Play, wait);
}
function Play() {
var imageShow, imageHide;
imageShow = i + 1;
imageHide = i;
if (imageShow == NumOfImages) {
SwapImage(0, imageHide);
i = 0;
} else {
SwapImage(imageShow, imageHide);
i++;
}
}
Effect.Emerge = function (element) {
element = $(element);
var oldStyle = {
top: element.getStyle('top'),
left: element.getStyle('left')
};
var position = element.positionedOffset();
return new Effect.Parallel(
[new Effect.Move(element, {
x: 0,
y: -100,
sync: true
}),
new Effect.Opacity(element, {
sync: true,
from: 0.0,
to: 1.0
})],
Object.extend({
duration: 0.5,
beforeSetup: function (effect) {
effect.effects[0].element.show().makePositioned().setStyle({
top: (position.top + 100) + 'px'
});
},
afterFinishInternal: function (effect) {
effect.effects[0].element.undoPositioned().setStyle(oldStyle);
}
}, arguments[1] || {}));
};
StartSlideShow();
You were on the right track just needed to play with the Effects library a little more, the Emerge function was too much and you needed to go simpler.
I've updated your jsfiddle
http://jsfiddle.net/aB79G/3/
basically you need to prepare the next slide off to the right and move both pictures at once with Effect.Morph instead of Effect.Move
Also notice how I used the afterFinish callback that allows you to string effects together.

Auto upload image on canvas without submit button

I am using fabric.js i am trying to upload image on canvas without submit button ,image is uploading successfully but the problem is that when i upload one image its uploading 4 time's on canvas just let me know how do i break the loop once count==1
$(document).ready(function(e) {
$('#preview').bind('DOMNodeInserted DOMSubtreeModified DOMNodeRemoved', function(event) {
// alert('NotChanged');
var count=0;
var gal_id =$(this).children('img').attr('id');
if(gal_id=='upload')
{
count++;
// alert(count);
// alert(gal_src);
}
if(count==1)
{
//var gal_id =$(this).children('img').attr('id');
var imgInstance2 = new fabric.Image(gal_id, {
left: 300,
top: 200,
// height:100,
angle: 60
// opacity: 0.85
});
// add image onto canvas
canvas.add(imgInstance2);
parent.$("#upload_image_pop_up").bPopup().close();
}
})
}
You can see here one image attached 4 times.
Got the answer following is my code.
$(document).ready(function(e) {
var flag=0;
$('#preview').bind('DOMNodeInserted', function(event) {
//$('#preview').bind('DOMNodeInserted DOMSubtreeModified DOMNodeRemoved', function(event) {
if(flag==0)
{
// $('#preview').bind('DOMNodeInserted DOMSubtreeModified DOMNodeRemoved', function(event) {
// alert('NotChanged');
var count=0;
var gal_id =$(this).children('img').attr('id');
var gal_src =$(this).children('img').attr('src');
if(gal_id=='upload')
{
count++;
// alert(count);
// alert(gal_src);
}
if(count==1)
{
//var gal_id =$(this).children('img').attr('id');
var imgInstance2 = new fabric.Image(gal_id, {
left: 300,
top: 200,
// height:100,
angle: 60
// opacity: 0.85
});
// add image onto canvas
canvas.add(imgInstance2);
parent.$("#upload_image_pop_up").bPopup().close();
flag=1;
}
}
})

Javascript plugin only firing once

I've built a very basic jQuery plugin that essentially positions a sprite image left by a set amount every x milliseconds to create an animation effect. The plugin at this stage is very basic and only has a few options, and it works pretty well.
Apart from that fact that it only fires once! I have multiple instance of the animation on one page and they all fire, but only ever once each.
Now I'm not expert on Javascript and only just managed to cobble this together but here's the code anyhow:
// Animation Plugin
(function($){
$.fn.anime = function(customOptions) {
// Default Options
var defaultOptions = {
slideWidth : 100,
frames : 10,
speed : 40,
minCycles : 1,
stopFrame : 0
};
// Set options to default
var options = defaultOptions;
// Merge custom options with defaults using the setOptions func
setOptions(customOptions);
// Merge current options with the custom option
function setOptions(customOptions) {
options = $.extend(options, customOptions);
};
return this.each(function() {
// Initialize the animation object
var $elem = $('img', this);
var frameCount = 0;
var currentSlideWidth = options.slideWidth;
var intervalID = null;
var cycleCount = 1;
var animate = function() {
if (frameCount < (options.frames -1)) {
$elem.css('left', '-' + currentSlideWidth + 'px');
frameCount++;
currentSlideWidth += options.slideWidth;
}
else {
if (cycleCount < options.minCycles)
{
frameCount = 0;
currentSlideWidth = options.slideWidth;
$elem.css('left', '-' + currentSlideWidth + 'px');
cycleCount++;
}
else
{
window.clearInterval(intervalID);
$elem.css('left', '0px');
}
}
cycleCount = 1;
};
$(this).bind('mouseover', function(){
var intervalID = window.setInterval(animate, options.speed);
});
});
};
})(jQuery);
The code used to call the actual plugin on a dom element is:
$('#animeBolt').anime({
frames: 50,
slideWidth: 62,
minCycles: 1,
speed: 30,
});
This is the html it is called on:
<div class="anime" id="animeBolt">
<img src="_assets/img/anime-bolt.png" alt="Lightning Bolt" width="3100" height="114">
</div>
And finally the css:
.anime {
position: absolute;
overflow: hidden; }
.anime img {
position: absolute;
left: 0;
top: 0; }
#animeBolt {
top: 2669px;
left: 634px;
width: 62px;
height: 116px; }
How do I get the plugin to fire repeatedly?
I've created and modified jsfiddle example using your code. It's working http://jsfiddle.net/9Yz9j/16/
I've change a couple of things:
added clearInterval on mouseover to preven multiple overlapping intervals
moved intervalID variable to outside of each function, and removed var keyword from mousover handler so the script will remember intervalID set on last mouseover
reseting the frameCount, cycleCount and currentSlideWidth variables on animation end (that was actually a clue thing to get animation going more than just once)
Hope that helps

Categories