Snap.svg hover/unhover bug (for longer unhover) - javascript

If I make a circle and then animate it like this - everything works:
var s = Snap(200,200);
var c = s.circle(100,100,100);
c.hover(function(){
c.animate({fill:"red"}, 500, mina.easeinout);
}, function() {
c.animate({ fill:"black" }, 500, mina.easeinout);
});
It changes the color to red on hover and on "unhover" it goes back to black. But if I make the time in the second function (unhover) 1500 instead of 500 you'll notice that if you hover over the circle, then unhover and hover AGAIN before in less than 1.5 seconds (before the circle's black again) - it will animate to full red and the rapidly go black without animation. Here is the demo:
https://jsfiddle.net/Drasik/5bcu4rc5/1/
Why is this happening and how can I fix it? Thanks!

The animation to black is still running, so if you hover again 500ms after hovering out, you're telling it to turn red in 500ms, then black again in 1000ms (and I think the browser gets confused, hence the suddenness).
To avoid this, you can try to stop the fade to black animation when hovering back in, like this (https://jsfiddle.net/5bcu4rc5/3/):
c.hover(function(){
c.stop(); // stops the black fill from continuing
c.animate({fill:"red"}, 500, mina.easeinout);
}, function() {
c.animate({ fill:"black" }, 1500, mina.easeinout);
});
If alternatively you want to force the full 1500ms to run before the red fill can start, maybe something like this (though there are probably better ways: https://jsfiddle.net/5bcu4rc5/2/):
c.hover(function(){
if (c.className != "unhovering") {
c.animate({fill:"red"}, 500, mina.easeinout);
}
}, function() {
c.className = "unhovering";
c.animate({ fill:"black" }, 1500, mina.easeinout, function() {
c.className = "";
});
});

Related

JS/GSAP solution for infinite animation

I am trying to create a infinite star rain animation, all stars are SVG's.
I tried this to create the animation:
(function($) {
TweenMax.set(".astar", {
x:function(i) {
return i * 50;
}
});
TweenMax.to(".astar", 5, {
ease: Linear.easeNone,
x: "+=500", //move each box 500px to right
modifiers: {
x: function(x) {
return x % 500; //force x value to be between 0 and 500 using modulus
}
},
repeat: -1
});
})(jQuery);
The repeat process is not smooth as you can see on this Codepen:
https://codepen.io/daniellwdb/pen/NXogoB
Is there any JS or GSAP solution to make the animation smooth so that it will look like stars keep spawning from the left and move to the right?
With your current setup, I think the easiest way to pull this off would be to duplicate your starfield so that the beginning of your next loop is identical to the end of your first one. Let's say this is your starfield SVG:
|...o.|
|o....|
|..o..|
Your new "duplicated" starfield would essentially be:
|...o.|...o.|
|o....|o....|
|..o..|..o..|
So when you move that duplicated image from left to right 100%, what you see in the last "frame" is identical to what it will return to when it loops.
Here's a fiddle that shows this concept in action: https://jsfiddle.net/yarp4oLs/5/
I have two identical starfield images that are 200x200 (so 400x200 when side-by-side) and they are displayed in a "viewport" container that is 200x200. Then I just slide them to the left 200px and repeat. Instant stars!

Vibrating screen on scroll using transform: scale

I would like a zoom out effect for my header, what loads zoomed in, and on scroll it zoom out.
What I do is to increase the size with transform: scale(1.4) and on scroll I calculate a percentage from the scrollTop and header height and I multiply it with 0.4. The problem is that on scroll the screen starts to vibrate, the scale isn't smooth. Do you have any idea what's wrong with my code or can you tell me what's the best practice to achieve this?
jQuery(document).ready(function(){
function zoom_out() {
var page_header_height = jQuery('#page-header-custom').outerHeight();
var scroll_top = jQuery(window).scrollTop();
var zoom_multiplier = 0.4;
var multiplier = (zoom_multiplier*(1-((scroll_top-jQuery('#page-header-custom').offset().top)/page_header_height))) > 1 ? 1 : (zoom_multiplier*(1-((scroll_top-jQuery('#page-header-custom').offset().top)/page_header_height)));
if(multiplier <= 1) {
jQuery('#page-header-inner').stop(true, true).transition({ scale: 1/(1+multiplier), translate: '0, -50%' });
jQuery('#page-header-custom').stop(true, true).transition({
scale: 1+multiplier
});
}
}
zoom_out();
jQuery(window).on('scroll', function(){
zoom_out();
});
});
I created a JSFiddle to see it in action.
I've updated your Fiddle with smooth scaling using window.requestAnimationFrame. The scale animation is vibrating because you're triggering a translation on each scroll event. Think about it like this:
user scrolls
zoom_out() gets triggered and tells an element to transition it's transform properties. Your element is now transitioning at a certain speed: "length" / transitiontime.
More scroll events have passed and are all triggering zoom_out(). The next transition will probably happen at a different speed, resulting in 'vibrating' animation.
First you can get rid of jQuery's transition() method. If you fire the function at 60fps or close to 60fps it will appear to animate smoothly to the human eye, without the need of transitioning or animating.
if(multiplier <= 1) {
//jQuery('#page-header-inner').stop(true, true).transition({ scale: 1/(1+multiplier), translate: '0, -50%' });
//jQuery('#page-header-custom').stop(true, true).transition({ scale: 1+multiplier });
//becomes:
jQuery('#page-header-inner').css({ scale: 1/(1+multiplier), translate: '0, -50%' });
jQuery('#page-header-custom').css({ scale: 1+multiplier });
}
}
Getting the function triggered at ~60fps can be achieved in multiple ways:
Throttle your scroll event to 60fps.
Or use window.requestAnimationFrame like in the updated Fiddle
function zoom_out(){
//calculation code & setting CSS
window.requestAnimationFrame(zoom_out);
}
//trigger it once instead of the scroll event handler
window.requestAnimationFrame(zoom_out);

Velocity.js leaving text artefacts on fade out

I am struggling to see why this leaves slight text fragments at the top of where an element has had the HTML replaced and then faded back in. This is the code:
$('.current-station-services li').on('click', function() {
$(this).find('.status').velocity({
opacity: 0
},{
duration: 100,
complete: function() {
$(this).html(data.test);
$(this).velocity({
opacity: 1
})
}
});
});
Here is an image also of the output (artefact above the 'yo!'):
This is a browser issue, not Velocity. Feel free to submit a bug report to webkit/gecko.

"fadeTo" function ignores the time

I have a div and I animate it's position with two divs(which are named as open and close).
I want "open" div to be fade out and invisible when opening animation completes. And become visible with fading in when closing animation completes.
But there is problem with the fading in. Time parameter is ignored and it appears when click action happens.
Here are my codes and a fiddle to see clearly what is going on with the codes;
$('.open').on('click', function(){
$('.menu').animate({"marginLeft":"-30px"},1000);
$('.open').fadeTo(1000, 0);
setTimeout(function () {
$('.open').css({"display":"none"})}, 1000);
});
$('.close').on('click', function(){
$('.menu').animate({"marginLeft":"82%"},1000);
$('.open').fadeTo(1000, 100);
});
the fiddle is http://jsfiddle.net/ctarimli/B9h2w/
as I know; the first paremeter is for time and the second one is the opacity in "fadeTo".
Tell me If I am wrong or what is the solution for this?
Opacity runs from 0 to 1, not 0 to 100. Use:
$('.close').on('click', function () {
$('.menu').animate({
"marginLeft": "82%"
}, 1000);
$('.open').fadeTo(1000, 1);
});
jsFiddle example
From the docs on .fadeTo():
opacity Type: Number A number between 0 and 1 denoting the target
opacity.

Last Div Flickering During jQuery Hover Animation

Here's my code: http://jsfiddle.net/ZspZT/
As you can see from the example, the fourth div block is flickering pretty badly, particularly on the hover-over effect, but also occasionally with the other divs as well.
Thanks in advance!
It appears that the easing function built into .animate is causing your percentage widths to add up to greater than 100%, causing the last sub-DIV to disappear. There are a few ways to solve this.
When I replace your percentage widths with fixed numerical widths, the problem vanishes. I used this in the code below (and your code had a LOT of redundancy to reduce):
$('document').ready(function() {
var speed = 450;
$('.four-ways-slide').hover(function() {
$(this).stop().animate({
width: 425
}, speed).siblings().stop().animate({
width: 25
}, speed);
}, function() {
$(this).siblings().andSelf().stop().animate({
width: 125
}, speed);
});
});
http://jsfiddle.net/mblase75/ZspZT/10/
Another possibility is to use percent widths that add up to 99% instead of 100%, and set a background color on the container DIV to hide the gap. Adding linear easing to the .animate method helps keep the total width from exceeding 100%:
$('document').ready(function() {
var speed = 450;
$('.four-ways-slide').hover(function() {
$(this).stop().animate({
width: '75%'
}, speed, 'linear').siblings().stop().animate({
width: '8%'
}, speed, 'linear');
}, function() {
$(this).siblings().andSelf().stop().animate({
width: '24.5%'
}, speed, 'linear');
});
});
#four-ways-slide-4,#four-ways-slider{background:#999999;}
http://jsfiddle.net/mblase75/ZspZT/9/
try using 'mouseenter' and 'mouseleave' rather than 'hover'. also you should assign variables rather than repeating divs
var one = $('#four-ways-slide-1');
var two = $('#four-ways-slide-2');
var three = $('#four-ways-slide-3');
var four = $('#four-ways-slide-4');
var all = $('.four-ways-slide');
thisIn = function(){
all.animate({width:'8%'},{duration: 450,queue:false});
};
thisOut = function(){
all.animate({width:'25%'},{duration: 450,queue:false});
};
one.mouseenter(function(){
thisIn();
$(this).animate({width:'76%'},{duration: 450,queue:false});
one.mouseleave(function(){
thisOut();
$(this).animate({width:'25%'},{duration: 450,queue:false});
});
});

Categories

Resources