Custom Animations
Introduction to Custom Animations
While jQuery's built-in effects are useful, the animate() method gives you complete control over custom animations. You can animate any CSS numeric property, create complex animation sequences, and build sophisticated interactive experiences.
The animate() Method
The animate() method creates custom animations by changing CSS properties over time.
$(selector).animate({
property: value,
property2: value2
}, duration, easing, callback);
<div id="box" style="width: 100px; height: 100px; background: blue;"></div>
<button id="animateBtn">Animate</button>
<script>
$(document).ready(function() {
$("#animateBtn").click(function() {
$("#box").animate({
width: "300px",
height: "300px",
opacity: 0.5
}, 1000);
});
});
</script>
Animatable Properties
You can animate most CSS numeric properties. Here are the commonly animated properties:
// Position
left, right, top, bottom
// Dimensions
width, height, padding, margin
// Visual
opacity, fontSize, lineHeight
// Border
borderWidth, borderRadius
// Examples
$("#box").animate({
left: "250px",
opacity: 0.8,
fontSize: "20px",
borderRadius: "50%"
}, 1000);
Relative Values
You can use relative values with "+=" or "-=" to animate from the current value.
// Move right by 50px from current position
$("#box").animate({
left: "+=50px"
}, 500);
// Decrease width by 20px
$("#box").animate({
width: "-=20px"
}, 500);
// Multiple relative animations
$("#box").animate({
left: "+=100px",
top: "-=50px",
width: "+=50px"
}, 1000);
Easing Functions
Easing controls the speed of animation at different points in time. jQuery includes "linear" and "swing" (default).
// Linear easing (constant speed)
$("#box").animate({
left: "300px"
}, 1000, "linear");
// Swing easing (starts slow, speeds up, then slows down)
$("#box").animate({
left: "300px"
}, 1000, "swing");
// With callback
$("#box").animate({
left: "300px"
}, 1000, "swing", function() {
alert("Animation complete!");
});
Sequential Animations (Chaining)
Chain multiple animate() calls to create sequential animations.
$("#box")
.animate({ left: "250px" }, 1000)
.animate({ top: "250px" }, 1000)
.animate({ left: "0px" }, 1000)
.animate({ top: "0px" }, 1000);
// With different properties in sequence
$("#box")
.animate({ width: "300px" }, 500)
.animate({ height: "300px" }, 500)
.animate({ opacity: 0.3 }, 500)
.animate({ opacity: 1 }, 500);
Simultaneous Animations
Animate multiple properties at once by including them in the same animate() call.
// All properties animate together
$("#box").animate({
width: "300px",
height: "300px",
left: "200px",
top: "200px",
opacity: 0.5,
fontSize: "24px"
}, 2000);
Animation Queue Control
Use queue: false to animate properties independently from the queue.
// Left animates in queue, opacity animates independently
$("#box")
.animate({ left: "250px" }, 2000)
.animate({ opacity: 0.5 }, { duration: 1000, queue: false });
// Stop current animation
$("#box").stop();
// Stop and clear queue
$("#box").stop(true);
// Stop, clear queue, and jump to end
$("#box").stop(true, true);
Practical Example: Animated Navigation
<style>
.nav-menu {
list-style: none;
padding: 0;
margin: 0;
}
.nav-item {
display: inline-block;
position: relative;
padding: 15px 20px;
cursor: pointer;
overflow: hidden;
}
.nav-underline {
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 3px;
background: var(--primary);
transform: translateX(-50%);
}
</style>
<ul class="nav-menu">
<li class="nav-item">
Home
<div class="nav-underline"></div>
</li>
<li class="nav-item">
About
<div class="nav-underline"></div>
</li>
<li class="nav-item">
Services
<div class="nav-underline"></div>
</li>
</ul>
<script>
$(document).ready(function() {
$(".nav-item").hover(
function() {
$(this).find(".nav-underline")
.stop()
.animate({ width: "100%" }, 300);
},
function() {
$(this).find(".nav-underline")
.stop()
.animate({ width: "0" }, 300);
}
);
});
</script>
Progress Bar Animation
Create an animated progress bar that fills smoothly.
<style>
.progress-container {
width: 100%;
height: 30px;
background: var(--bg-light);
border-radius: 15px;
overflow: hidden;
margin: 20px 0;
}
.progress-bar {
width: 0;
height: 100%;
background: linear-gradient(90deg, var(--primary), var(--primary-light));
border-radius: 15px;
position: relative;
}
.progress-text {
position: absolute;
width: 100%;
text-align: center;
line-height: 30px;
color: white;
font-weight: bold;
}
</style>
<div class="progress-container">
<div class="progress-bar">
<span class="progress-text">0%</span>
</div>
</div>
<button id="startProgress">Start Upload</button>
<script>
$(document).ready(function() {
$("#startProgress").click(function() {
var progressBar = $(".progress-bar");
var progressText = $(".progress-text");
progressBar.animate({ width: "100%" }, {
duration: 3000,
easing: "linear",
step: function(now) {
var percentage = Math.floor(now);
progressText.text(percentage + "%");
},
complete: function() {
progressText.text("Complete!");
}
});
});
});
</script>
step callback executes during each animation step, perfect for updating text or creating custom effects.
Animated Counter
Create a counting animation for statistics or metrics.
<style>
.stat-box {
display: inline-block;
padding: 30px;
margin: 20px;
background: var(--bg-light);
border-radius: 10px;
text-align: center;
min-width: 200px;
}
.stat-number {
font-size: 48px;
font-weight: bold;
color: var(--primary);
}
.stat-label {
font-size: 16px;
color: var(--text-light);
margin-top: 10px;
}
</style>
<div class="stat-box">
<div class="stat-number" data-target="1250">0</div>
<div class="stat-label">Happy Clients</div>
</div>
<div class="stat-box">
<div class="stat-number" data-target="5680">0</div>
<div class="stat-label">Projects Completed</div>
</div>
<script>
$(document).ready(function() {
function animateCounter(element) {
var target = parseInt(element.attr("data-target"));
$({ counter: 0 }).animate({ counter: target }, {
duration: 2000,
easing: "swing",
step: function() {
element.text(Math.floor(this.counter));
},
complete: function() {
element.text(target.toLocaleString());
}
});
}
// Trigger animation when element is in viewport
$(".stat-number").each(function() {
animateCounter($(this));
});
});
</script>
Bouncing Effect
Create a bouncing animation using sequential animations.
<style>
#ball {
width: 50px;
height: 50px;
background: var(--primary);
border-radius: 50%;
position: absolute;
top: 0;
left: 50px;
}
</style>
<div id="ball"></div>
<button id="bounceBtn">Bounce Ball</button>
<script>
$(document).ready(function() {
$("#bounceBtn").click(function() {
$("#ball")
.animate({ top: "300px" }, 500, "linear")
.animate({ top: "100px" }, 400, "linear")
.animate({ top: "300px" }, 300, "linear")
.animate({ top: "200px" }, 200, "linear")
.animate({ top: "300px" }, 100, "linear")
.animate({ top: "280px" }, 50, "linear");
});
});
</script>
Parallax Scrolling Effect
Create a simple parallax effect using animation based on scroll position.
<style>
.parallax-container {
height: 500px;
overflow: hidden;
position: relative;
}
.parallax-layer {
position: absolute;
width: 100%;
height: 100%;
}
#layer1 { background: url("layer1.png") center/cover; }
#layer2 { background: url("layer2.png") center/cover; }
#layer3 { background: url("layer3.png") center/cover; }
</style>
<div class="parallax-container">
<div class="parallax-layer" id="layer1"></div>
<div class="parallax-layer" id="layer2"></div>
<div class="parallax-layer" id="layer3"></div>
</div>
<script>
$(document).ready(function() {
$(window).scroll(function() {
var scrolled = $(window).scrollTop();
// Different layers move at different speeds
$("#layer1").css("top", -(scrolled * 0.2) + "px");
$("#layer2").css("top", -(scrolled * 0.5) + "px");
$("#layer3").css("top", -(scrolled * 0.8) + "px");
});
});
</script>
Card Flip Animation
Create an interactive card flip effect.
<style>
.flip-card {
width: 300px;
height: 200px;
position: relative;
cursor: pointer;
}
.flip-card-front, .flip-card-back {
position: absolute;
width: 100%;
height: 100%;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
}
.flip-card-front {
background: var(--primary);
color: white;
}
.flip-card-back {
background: var(--primary-light);
color: white;
display: none;
}
</style>
<div class="flip-card">
<div class="flip-card-front">Front</div>
<div class="flip-card-back">Back</div>
</div>
<script>
$(document).ready(function() {
var isFlipped = false;
$(".flip-card").click(function() {
var front = $(this).find(".flip-card-front");
var back = $(this).find(".flip-card-back");
if (!isFlipped) {
front.animate({ width: "0", opacity: 0 }, 200, function() {
front.hide();
back.css({ width: "0", opacity: 0 }).show()
.animate({ width: "100%", opacity: 1 }, 200);
});
isFlipped = true;
} else {
back.animate({ width: "0", opacity: 0 }, 200, function() {
back.hide();
front.css({ width: "0", opacity: 0 }).show()
.animate({ width: "100%", opacity: 1 }, 200);
});
isFlipped = false;
}
});
});
</script>
Animation Delay
Use delay() to add pauses between animations.
// Delay before next animation
$("#box")
.animate({ left: "250px" }, 1000)
.delay(2000) // Wait 2 seconds
.animate({ top: "250px" }, 1000);
// Multiple delays
$("#box")
.fadeOut(500)
.delay(1000)
.fadeIn(500)
.delay(1000)
.fadeOut(500);
Clearing Animation Queue
Manage the animation queue to prevent unwanted animation buildup.
// Clear all queued animations
$("#box").clearQueue();
// Clear specific queue
$("#box").clearQueue("fx");
// Finish all animations immediately
$("#box").finish();
// Example: Hover with queue management
$("#box").hover(
function() {
$(this).stop(true, false).animate({
width: "200px"
}, 300);
},
function() {
$(this).stop(true, false).animate({
width: "100px"
}, 300);
}
);
📝 Exercise: Interactive Dashboard Widget
Task: Create an animated dashboard widget that:
- Has a circular progress indicator that animates from 0% to 75%
- Shows a counter that counts from 0 to 1,500 over 2 seconds
- Expands vertically when clicked to reveal detailed statistics
- Has 3 sub-metrics that slide in sequentially when expanded
- Uses color changes to indicate different value ranges (green for good, yellow for warning, red for critical)
- Includes a refresh button that replays all animations
Bonus Challenge: Add sparkline charts that draw themselves using animation, and make the entire widget responsive to different screen sizes.
Performance Best Practices
- Use CSS3 transitions/animations when possible (better performance)
- Avoid animating too many elements simultaneously
- Use
stop()before new animations to prevent queue buildup - Animate transform and opacity for best performance
- Avoid animating colors with jQuery (use CSS or jQuery UI)
- Consider using requestAnimationFrame for complex animations
- Test on mobile devices as they may have slower animation performance
Summary
animate()- Create custom animations on numeric CSS properties- Use relative values (+=, -=) for incremental animations
- Chain animations for sequential effects
- Combine properties in one animate() for simultaneous effects
stepcallback updates during animation progressdelay()adds pauses between animationsstop(),clearQueue(),finish()manage animation queue- Easing controls animation speed curve (linear, swing)