I have a div with a mouseout and a mouseover event which change the div's opacity.
But the div flickers if the you move the mouse over and out of the div in rapid succession.
I'm trying to find a way to stop the flickering so that it cancels the previous action and thus won't flicker.
I used a clear interval but doesn't seem to fix the problem... this is my fiddle:
http://jsfiddle.net/3xuyc/4/
My code code which clears interval for opacity transition:
function fade(dir){
var interId = null;
function fade_in() {
clearInterval(interId);
var div_id = document.getElementById('my_div');
var opacity = window.getComputedStyle(div_id).opacity;
interId = transition_opacity(div_id, opacity, 1, 0);
}
function fade_out() {
clearInterval(interId);
var div_id = document.getElementById('my_div');
var opacity = window.getComputedStyle(div_id).opacity;
interId = transition_opacity(div_id, opacity, 0,0);
}
if(dir){
fade_in();
} else {
fade_out();
}
}
var div_id = document.getElementById('my_div');
div_id.addEventListener('mouseover', function(){fade(1);}, false);
div_id.addEventListener('mouseout', function(){fade(0);}, false);
Any suggestions on how i can fix this problem?
If I understand correctly, you're using clearInterval to stop the previous fade in/out.
Try declaring var inter_id outside the fade() function. You're setting it to null each time you call fade().
Related
I have a div:
<div class="coverImage" style="background-image:url('3.2.5\\assets\\img\\backgroundCanvas1.jpg');"></div>
and an attached jQuery script to rotate its background every 20 seconds
var coverChange =
{
init: function()
{
var itemInterval = 20000;
var numberOfItems = 4;
var currentItem = 1;
$('.coverImage').attr("style", "background-image:url('3.2.5/assets/img/backgroundCanvas"+currentItem+".jpg'");
//loop through the items
var infiniteLoop = setInterval(function(){
$('.coverImage').attr("style", "background-image:url()");
if(currentItem == numberOfItems -1){
currentItem = 1;
}else{
currentItem++;
}
$('.coverImage').attr("style", "background-image:url('3.2.5/assets/img/backgroundCanvas"+currentItem+".jpg'");
}, itemInterval);
}
};
coverChange.init();
When the image changes it happens to white out the bottom half until I scroll slightly. My main ask is help with a fadeIn of the new image. (everything else is secondary)
I have experimented using the jQuery fadeIn property but cannot get it to work in a seamless aesthetically pleasing way.
I am not looking for code elegance only function, as you can tell :-)
P.S Loading the image initially via CSS did not work.
You should be able to add a simple CSS transition to your coverImage element.
.coverImage {
transition: background 1s;
}
I've created a working example at https://jsfiddle.net/mark_c/pa44n42k/1/
For a fade in out effect, you should simply fade out the div before this step:
$('.coverImage').attr("style", "background-image:url()");
and fade it in after this step:
$('.coverImage').attr("style", "background-image:url('3.2.5/assets/img/backgroundCanvas"+currentItem+".jpg'");
For fade in out you can use simple jquery as I suppose you already have but not the right way, so good luck.
This will give you a nice fade in/out effect. :)
I have custom buttons that replaces the browser scrollbar. The idea is so that scrolling oversize elements in a page wouldn't result to a dozen scroll bar on a page.
See: https://jsfiddle.net/bwgxs6ng/
Since I must show some code sample (according to some SO error message), see this:
$('.right').on('click', function(event) {
var target = $(".image-container");
var current_x = target.scrollLeft();
if( target.length ) {
event.preventDefault();
$(target).animate({
scrollLeft: current_x+100
}, 500);
}
});
It's very simple, basically it takes current scroll position of the parent, and add x to it based on the direction that's clicked.
However, going further, I want it to imitate the hold and continuous scroll, but I'm not sure how to do it.
1) What is the mouse hold event called? (OK, this part is answered, it's called MouseDown as someone point out of the duplicate)
2) What is the continuous scrolling called, and how can I do something that'd imitate the browser's continuous scroll?
You can just call .animate() repeatedly (with easing set to linear, for smooth movement) inside your setInterval() callback. Just arrange for the interval to be equal to the animation duration, so that the next animation starts just when the previous one ends.
Or, better yet, make the interval shorter (say, 50 ms or less) and just call .prop() instead of .animate(), effectively performing your own animation. (This is how jQuery implements animation internally, anyway.)
Anyway, here's how I'd rewrite your code to support smooth continuous scrolling:
var speed_x = 0, speed_y = 0;
var timer = null;
var target = $(".image-container");
function scroll() {
if (speed_x == 0 && speed_y == 0) return;
var current_x = target.scrollLeft();
var current_y = target.scrollTop();
target.prop({
scrollLeft: current_x - speed_x,
scrollTop: current_y - speed_y
});
}
$('.control').on('mouseover mouseout', function (event) {
var $this = $(this);
var speed = (event.type == 'mouseover' ? 10 : 0)
if ($this.hasClass('left')) speed_x = +speed;
if ($this.hasClass('right')) speed_x = -speed;
if ($this.hasClass('up')) speed_y = +speed;
if ($this.hasClass('down')) speed_y = -speed;
}).on( 'mousedown', function () {
scroll();
if (timer !== null) clearInterval(timer);
timer = setInterval(scroll, 50);
return false;
});
$(document).on('mouseup', function () {
if (timer !== null) clearInterval(timer);
timer = null;
});
Note how the animation is started and stopped in the mousedown and mouseup handlers, but the direction of movement is set on mouseover and mouseout. This allows you to change the scrolling direction while holding the mouse down, by dragging the cursor from one edge to another.
(For bonus points, add divs with e.g. class="control up left" in the corners of the scroll area, so that holding the mouse down over those corners will allow you to scroll diagonally. The JS code above already supports it.)
you need to set an interval on mousedown, and clear the interval on mouseup, as done in this fiddle for left and right.
The relevant code change is that we removed the click event and replaced it with
$('.left').on('mousedown', function(event) {
... scroll code ...
interval = setInterval(function(){
... scroll code ...
},500);
})
.on('mouseup',function(){clearInterval(interval);});
I'm playing around with pure JavaScript, so I created a small fade in/out object, to adjust images opacity onmouseover and onmouseout. Fading works fine when the mouseover and mouseout actions are precise:
Start moving the cursor from the white background
Hover over an image
Hover back over the white background
The problem is, as soon as I start to move the mouse "naturally" from one image to another, the fading (or rather the script itself) freezes.
I'm not sure whether it's a animation-speed problem, or there's something I'm missing in the implementation.
If someone has the time to take a look, I would appreciate a peer check, so I can crack the issue and learn new stuff.
Here's a fiddle: http://jsfiddle.net/6bd3xepe/
Thanks!
As I see it, you have one INTERVAL for you FADER, you need one for each IMG.
My jsfiddle fixes this. I added an ALT-attribute to each IMG with "dome" content, so as to circumvent the jsfiddle working on non-cat-images .. ignore that part - commented out below.
There are some fundamental things wrong with the design - keeping track of objects & references is key. Usage of "this" & "that" aren't helping in the current implementation (see comments to OP). Also, on another note, the usage of "toFixed(2)" is not really required IMHO and you can shorten "o = o + 0.1" to "o += 0.1".
JS:
var fader = {
target: document.getElementsByTagName('img'),
interval: [],
speed: 25,
default_opacity: 1,
init: function() {
this.bindEvents();
},
// Get element's opacity and increase it up to 1
fadeIn: function(element) {
var element_opacity = this.getOpacity(element),
that = this,
idx = element.getAttribute('data-idx');
console.log("fI: "+idx+" "+element_opacity);
this.default_opacity = element_opacity.toFixed(2);
this.interval[idx] = setInterval(function() {
if (element_opacity.toFixed(2) < 1) {
element_opacity = element_opacity + 0.1;
element.style.opacity = element_opacity.toFixed(2);
} else {
clearInterval(that.interval[idx]);
}
}, that.speed);
},
// Get current opacity and decrease it back to the default one
fadeOut: function(element) {
var element_opacity = this.getOpacity(element),
that = this,
idx = element.getAttribute('data-idx');
console.log("fO: "+idx+" "+element_opacity);
this.interval[idx] = setInterval(function() {
if (element_opacity.toFixed(2) > that.default_opacity) {
element_opacity = element_opacity - 0.1;
element.style.opacity = element_opacity.toFixed(2);
} else {
clearInterval(that.interval[idx]);
element.removeAttribute('style');
}
}, that.speed);
},
// Get opacity of an element using computed styles
getOpacity: function(element) {
var styles = window.getComputedStyle(element),
opacity = parseFloat(styles.getPropertyValue('opacity'));
return opacity;
},
bindEvents: function() {
var that = this, count = 0;
for (var i in this.target) {
// the whole "dome" is just a fsfiddle hack - otherwise it sees 7 images instead of 4!
//if( this.target[i].alt == "dome" ){
console.log("COUNT: "+count);
this.target[i].setAttribute('data-idx',count);
this.target[i].onmouseover = function() {
that.fadeIn(this);
}
this.target[i].onmouseout = function() {
that.fadeOut(this);
}
count++;
//}
}
}
};
fader.init();
I'm looking for a way to emulate the CSS #keyframes animations using jQuery.
I need to change the background image each x seconds following a list of images provided when the user moves mouse over an element.
The CSS animations should be:
.readon:hover {
animation: readonin 2s;
}
#keyframes readonin {
0% { background-image: url(1.png); }
50% { background-image: url(2.png); }
100% { background-image: url(3.png); }
}
I've found plugins like Spritely but they works with sprites and I need instead to change the image background of the element.
Use the set-interval function of Javascript seems a bad solution because I can't find a way to stop the animation when the user moves the mouse out of the element.
Use something like...
var images = ["1.png", "2.png", "3.png"];
var $element = $(".readon");
var interval = null;
$element.hover(function () {
var $this = $(this);
var i = 0;
var fn = function () {
$this.css("background-image", "url(" + images[i] + ")");
i = ++i % images.length;
};
interval = setInterval(fn, 666);
fn();
},
function () {
clearInterval(interval);
$(this).css("background-image", "none");
});
jsFiddle of a similar concept (with background colours).
It should be clear enough to see what's going on. Basically we start looping over the images and setting them as the background image on mouse over, and reset it when the mouse leaves.
You can use a library like jQuery-Keyframes
to generate new keyframes at runtime if that is what you are after.
I am newbie in JS. Right now i am working on an effect in which i want when page scroll first time then the natural motion animation starts but it's creating a problem because when i scroll the element animation became fast.
Check this more you got the idea.
http://jsfiddle.net/byvLy/
i know that this is a swinging box (figured it out due to the Math.sin())
however, you have to note that scrolling event is fired every few milliseconds during scrolling. in your code, you are calling animate and creating an interval every time the scroll event is fired. that's why your animation is jumpy;
try this instead:
$(function() {
$(window).on('scroll', function() {
swing.start('.cloud1, .cloud2');
});
var swing = (function() {
var animated = false;
function startAnimation(selector) {
if (!animated) {
var banner = $(selector);
var start = 0;
animated = true;
window.setInterval(function() {
banner.css('left', 100 * Math.sin(start) + 80);
start += 0.1;
}, 30);
}
}
return {
start: startAnimation
}
}());
});