Code in JSFiddle:
http://jsfiddle.net/wardrobe/6UVDD/
I want to use jQuery to slow the animation speed of a CSS-animated atom to a crawl on mouseover, but to do so using some kind of easing. I can get jQuery to change the play state to paused easy enough, but to slow to a crawl seems harder.
HTML
<div id="atom">
<div id="cloud">
<div class="orbit">
<div class="path">
<div class="electron"></div>
</div>
</div>
<div class="orbit">
<div class="path">
<div class="electron"></div>
</div>
</div>
<div class="orbit">
<div class="path">
<div class="electron"></div>
</div>
</div>
<div class="orbit">
<div class="path">
<div class="electron"></div>
</div>
</div>
<div id="nucleus"></div>
</div>
</div>
CSS:
#atom { position: absolute; top: 50%; left: 50%; width:300px; margin-left: -170px; margin-top: -146px; transition: all 1.5s; }
#cloud { width:300px; height:300px; -webkit-perspective: 1000; position:relative; -webkit-animation-play-state:paused;}
#nucleus { position:absolute; top:50%; left:50%; margin: -10px 0 0 -10px; width:25px; height:25px; border-radius:25px; -webkit-border-radius:25px; -moz-border-radius:25px; background: #272727;}
.orbit { position:absolute; top:0; left:0; width:300px; height:300px; border-radius:300px; -webkit-border-radius:300px; -moz-border-radius:300px; border:5px solid #ccc; -webkit-transform-style: preserve-3d; -webkit-transform: rotateX(80deg) rotateY(20deg);}
#cloud .orbit:nth-child(2) {-webkit-transform: rotateX(80deg) rotateY(70deg)}
#cloud .orbit:nth-child(3) {-webkit-transform: rotateX(80deg) rotateY(-20deg)}
#cloud .orbit:nth-child(4) {-webkit-transform: rotateX(80deg) rotateY(-50deg)}
#cloud .orbit:nth-child(2) .path, #cloud .orbit:nth-child(2) .electron {-webkit-animation-delay: -1.0s}
#cloud .orbit:nth-child(3) .path, #cloud .orbit:nth-child(3) .electron {-webkit-animation-delay: -1.5s}
#cloud .orbit:nth-child(4) .path, #cloud .orbit:nth-child(4) .electron {-webkit-animation-delay: -0.5s}
.path { width:300px; height:300px; position:relative; -webkit-transform-style: preserve-3d; -webkit-animation-name: pathRotate; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; }
.electron { position: absolute; top:-5px; left:50%; margin-left:-5px; width:10px; height:10px; border-radius:10px; background:#ccc; -webkit-animation-name: electronFix; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; }
@-webkit-keyframes pathRotate { from { -webkit-transform: rotateZ(0deg);} to { -webkit-transform: rotateZ(360deg); } }
@-webkit-keyframes electronFix { from { -webkit-transform: rotateX(90deg) rotateY(0deg); } to { -webkit-transform: rotateX(90deg) rotateY(-360deg); } }
JS:
$(function() {
$("#atom").mouseover(function() {
$( ".path" ).animate({"-webkit-animation-duration": "25s"}, {duration: 'slow'});
$( ".electron" ).animate({"-webkit-animation-duration": "25s"}, {duration: 'slow'});
}).mouseout(function() {
$( ".path" ).animate({"-webkit-animation-duration": "2s"}, {duration: 'slow'});
$( ".electron" ).animate({"-webkit-animation-duration": "2s"}, {duration: 'slow'});
});
});
Thanks
The easiest way I know how to do it would be to use something like GSAP which allows for this functionality quite easily. Potentially you could without a library like GSAP, but it'd be incredibly complicated, time consuming, likely jumpy, and perform worse
However, when a library like GSAP is introduced it becomes a bit more simple. Hopefully the comments help a bit in explaining the code
Essentially I recreated the animations using GSAP, put them on a Timeline, and slowed the Timeline on hover
Demo
// Used to change the timings of all animations collectively
var timeline = new TimelineMax({}),
electrons = document.querySelectorAll('.electron'),
paths = document.querySelectorAll('.path'),
startDuration = 2,
delay = 0.5,
// Gets the start of the last electron
lastTweenStartTime = (electrons.length - 1) * delay,
// Calculates when the last electron is done animating
lastTweenEndTime = lastTweenStartTime + startDuration;
// Apply the GSAP animation to each electron and path
for (var i = 0; i < electrons.length; i++) {
// Create the individual delay to create offset
var myDelay = (i * delay);
orbit(electrons[i], paths[i], myDelay);
}
// Slow the animation on mouseover
document.getElementById("atom").onmouseover = function () {
TweenLite.to(timeline, startDuration, {
timeScale: 0.1
});
}
// Set the animation back to normal on mouse leave
document.getElementById("atom").onmouseout = function () {
TweenLite.to(timeline, startDuration, {
timeScale: 1
});
}
// Repeat it when the last electron is done animating
timeline.add(repeat, lastTweenEndTime);
// Start ahead so there is no load time
timeline.seek(1.5);
// Give each electron and path their individual animations
function orbit(electron, path, delay) {
var e = TweenMax.fromTo(electron, startDuration,
// Initial rotationX of 90 to make dots visible
{ rotationX: '90' },
// Keep the dots upright for the duration of the animation
{
rotationZ: '-360',
rotationX: '90',
ease: Linear.easeNone,
repeat: 1
});
var p = TweenMax.to(path, startDuration, {
rotationZ: '360',
ease: Linear.easeNone,
repeat: 1
});
// Add that animation to the total timeline
timeline.add([e, p], delay);
}
// Repeat the animation
function repeat() {
timeline.play(lastTweenStartTime);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With