I first tried using CSS, but when I was informed that it looks buggy on Safari, I tried with Greensock's Javascript library to see if it fixes it. It still has the same issues, still only on Safari. After a bit of research I saw it discussed on StackOverflow as a Safari bug.
jQuery(function($){
var iconsHoverIn = function() {
TweenMax.to($(this).find('.iconBG'), 0.5, {
rotationY: 180,
opacity: 0
}
);
TweenMax.to($(this).find('.hoverImage'), 0.5, {
rotationY: '-180',
opacity: 1
}
);
}
var iconsHoverOut = function() {
TweenMax.to($(this).find('.iconBG'), 0.5, {
rotationY: 0,
opacity: 1
}
);
TweenMax.to($(this).find('.hoverImage'), 0.5, {
rotationY: 0,
opacity: 0
}
);
}
$('.iconBlock').hover(iconsHoverIn, iconsHoverOut);
});
The bug is: while doing the transition, half of the element seems to transition differently than the other half. It shows a line in the middle, like if the element was made of paper and was bending in half.
Is there any way around it? I presented a few animations to the client, but this animation (rotateY) was the unanimous selection.
Note: I am somewhat new to Javascript and Greensock. You may notice better ways to do what I did. I wouldn't mind suggestions on improving it, but what I am really after is a solution to the bug/glitch.
As the solution you posted in your question itself suggests, adding a translateZ
(which in GSAP terms just means z
) to either .iconBG
element or .hoverImage
element should solve your problem.
Here is the forked codepen of your demo and the code is as belows:
JavaScript:
var iconBlocks = $('.iconBlock');
var iconBGs = iconBlocks.find('.iconBG');
var hoverImages = iconBlocks.find('.hoverImage');
var animDuration = 0.4;
var animEase = Power2.easeOut;
var numIcons = iconBlocks.length;
var timelines = [];
var timeline = null;
for (var i = 0; i < numIcons; i += 1) {
timeline = new TimelineMax({ paused: true });
timeline.fromTo(iconBGs[i], animDuration, { z: 0, rotationY: 0, autoAlpha: 1 }, { rotationY: 180, autoAlpha: 0, ease: animEase }, 0);
timeline.fromTo(hoverImages[i], animDuration, { z: 100, rotationY: 180, autoAlpha: 0 }, { rotationY: 0, autoAlpha: 1, ease: animEase }, 0);
timelines[i] = timeline;
}
iconBlocks.hover(function() { timelines[$(this).index()].play(); }, function() { timelines[$(this).index()].reverse(); });
And yes, I have changed things a bit. Personal preference totally, no right or wrong ways here. Let me know if this helps.