Ever tried to sketch a curve that looks like a lazy smile, then realized you needed the exact shape of a square‑root function?
You’re not alone. Most people see the “√x” graph in a textbook and think, “That’s easy,” only to end up with a jagged line that looks nothing like the smooth curve they imagined. The short version is: getting a clean square‑root curve isn’t magic—it’s just a handful of steps, a bit of patience, and the right tools Turns out it matters..
What Is a Square Root Curve
When we talk about a square root curve, we’re really talking about the graph of the function
[ y = \sqrt{x} ]
or any scaled/shifted version of it, like
[ y = a\sqrt{b(x - h)} + k ]
In plain English, it’s the shape you get when you take the square root of a number and plot the result. The curve starts at the origin (0,0) if you use the basic form, rises quickly at first, then flattens out as x gets larger. It’s the opposite of a parabola that opens upward—where a parabola speeds up, the square‑root curve slows down Worth knowing..
Where You’ll See It
- Physics – distance traveled under constant acceleration when you solve for time.
- Economics – diminishing returns, like how each extra hour of study yields less improvement.
- Design – easing functions in animation, where you want a motion that starts fast and eases into a gentle finish.
Understanding the curve lets you model all those real‑world situations more accurately.
Why It Matters
If you can draw a square root curve by hand, you’ve got a visual intuition for any situation that follows a diminishing‑returns pattern. Miss the shape, and you might over‑estimate growth, under‑estimate risk, or make a UI animation feel jerky.
Take a simple example: you’re planning a marketing campaign and expect each additional dollar spent to bring fewer new customers. Plotting the spend‑versus‑customers relationship with a square‑root curve shows you exactly where the “sweet spot” lies before extra money stops being worth it.
And in data visualization, a clean curve makes your chart look professional. Consider this: a sloppy line screams “I threw this together in Excel without thinking. ” A smooth, mathematically correct curve says, “I know my stuff.
How to Do It (Step‑by‑Step)
Below is the practical workflow for getting a perfect square root curve, whether you’re drawing on paper, using a graphing calculator, or building it in code.
1. Choose Your Domain
The square‑root function only works for non‑negative x values (unless you’re into complex numbers, which is a whole other rabbit hole). Now, decide how far right you need to go. For a quick sketch, 0 ≤ x ≤ 10 is often enough And that's really what it comes down to..
2. Create a Table of Values
| x | √x | y (optional scaling) |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 4 | 2 | 2 |
| 9 | 3 | 3 |
| 16 | 4 | 4 |
If you want a stretched curve, multiply the √x column by a factor a (e.That said, g. Day to day, , y = 2√x). Add a horizontal shift h by plugging (x − h) into the root, and a vertical shift k by adding it at the end The details matter here..
3. Plot the Points
Grab graph paper or open a spreadsheet. Plot each (x, y) pair. The points will naturally line up in that characteristic “slow‑down” shape It's one of those things that adds up..
4. Connect With a Smooth Line
Here’s the trick: don’t use straight‑line segments between every point. Worth adding: instead, use a freehand smooth curve or a curve‑fitting tool. In Excel, select the series, right‑click, and choose “Add Trendline → Power.” Set the exponent to 0.5 and you’ve got a perfect fit That's the part that actually makes a difference..
If you’re coding, most libraries have a built‑in function:
import numpy as np
import matplotlib.pyplot as plt
x = np.Even so, linspace(0, 10, 400)
y = np. sqrt(x)
plt.plot(x, y)
plt.
That one‑liner draws a flawless curve every time.
### 5. Apply Transformations (Optional)
* **Vertical stretch/compression** – multiply the whole function by *a*. Larger *a* makes the curve steeper.
* **Horizontal stretch/compression** – replace x with *b·x*. Smaller *b* stretches it out.
* **Shifts** – add/subtract inside the root for horizontal moves, outside for vertical moves.
Combine them for custom easing:
\[
y = 1.5\sqrt{2(x - 3)} + 0.5
\]
Plot it, and you’ll see the curve start at (3, 0.5) and rise with a gentle slope.
### 6. Verify With Derivatives (Optional but Cool)
The derivative of √x is
\[
\frac{dy}{dx} = \frac{1}{2\sqrt{x}}
\]
That tells you the slope at any point. If you’re building an animation, you can use this to control speed directly. The slope gets smaller as x grows—exactly why the curve flattens.
---
## Common Mistakes / What Most People Get Wrong
1. **Forgetting the domain** – plugging negative x values gives “#NUM!” errors in Excel or complex numbers in code.
2. **Using straight‑line segments** – the result looks jagged, especially with few data points.
3. **Scaling incorrectly** – multiplying *x* instead of the whole √x term flips the curve the wrong way.
4. **Ignoring the vertical shift** – many newbies think adding *k* inside the root works, but it actually shifts the curve horizontally, not vertically.
5. **Treating √x as a linear function** – you can’t just draw a line between (0,0) and (10, √10) and call it a day; the curvature matters.
---
## Practical Tips / What Actually Works
* **Use at least 8–10 points** when you’re plotting by hand. The more points, the smoother the curve feels.
* **Round your square‑root values** to two decimal places for a cleaner look on paper; too many digits make the graph look messy.
* **In Excel**, the “Power” trendline with exponent 0.5 is a hidden gem—no need to calculate each point manually.
* **For UI easing**, most design tools (Figma, After Effects) let you paste the exact function *y = √x* as a custom easing curve.
* **Check the slope** at the start and end if you need a specific speed profile—use the derivative formula to fine‑tune *a* and *b*.
---
## FAQ
**Q: Can I draw a square root curve without a calculator?**
A: Absolutely. Use a simple table of perfect squares (1, 4, 9, 16…) and their roots (1, 2, 3, 4). Plot those points and smooth them out. It’s a classic pen‑and‑paper method.
**Q: What’s the difference between y = √x and y = x^(1/2)?**
A: Nothing mathematically; they’re two ways of writing the same thing. Some graphing tools prefer the exponent notation.
**Q: How do I flip the curve upside down?**
A: Multiply the whole function by –1: y = –√x. The curve now starts at the origin and drops downwards.
**Q: Is there a way to combine a square root curve with a linear one?**
A: Sure. Piecewise functions let you stitch them together, e.g., y = √x for 0 ≤ x ≤ 4, then y = 2x – 4 for x > 4.
**Q: Why does my curve look too “steep” in the beginning?**
A: You probably scaled the *a* factor too high or didn’t apply a horizontal stretch. Reduce *a* or increase the *b* inside the root to tame the early rise.
---
That’s it. You now have the full toolbox: a clear definition, why the shape matters, a step‑by‑step recipe, pitfalls to dodge, and real‑world tips you can start using today. Next time you need a smooth, diminishing‑return curve—whether for a physics problem, a marketing model, or a slick animation—you’ll know exactly how to do a square root curve without breaking a sweat. Happy graphing!
---
## A Quick Reference Cheat Sheet
| Feature | What to Do | Why it Matters |
|---------|------------|----------------|
| **Horizontal stretch** | Use *b* > 1 inside the root | Slows the early climb, keeps the curve spread out |
| **Vertical stretch** | Multiply by *a* > 1 | Raises the overall height, useful for scaling to a target range |
| **Horizontal shift** | Replace *x* with *(x–h)* | Moves the curve right (h > 0) or left (h < 0) |
| **Vertical shift** | Add *k* after the root | Raises or lowers the entire curve without changing shape |
| **Piecewise tweak** | Combine with a line or a plateau | Allows custom “turn‑off” points or a flat top |
---
## Bringing It All Together: A Mini‑Project
**Goal:** Create a “smoothing” easing curve for a button that expands from 0 px to 200 px over 0.5 seconds, starting fast and slowing toward the end.
**Steps:**
1. **Choose a base function.**
\( y = \sqrt{x} \) gives the desired “fast‑then‑slow” feel.
2. **Scale to the time domain.**
We need \(x\) to run from 0 to 1 (normalized time).
→ Use \( y = \sqrt{x} \) with \(x \in [0,1]\).
3. **Stretch vertically to match pixel size.**
Multiply by 200: \( y = 200\sqrt{x} \).
4. **Add a tiny vertical offset to avoid zero‑pixel glitches.**
\( y = 200\sqrt{x} + 1 \).
5. **Export the curve to your animation tool.**
In Figma, copy the points or use the “Custom easing” curve editor and paste the equation directly.
6. **Test.**
Animate the button; you should see a quick burst of growth that tapers off smoothly.
You now have a reusable, mathematically‑sound easing curve that can be copied to other UI elements with just a few tweaks.
---
## Final Thoughts
The square‑root function is deceptively simple, yet it packs a powerful visual and analytical punch. In practice, whether you’re drafting a quick sketch, building a data‑driven model, or designing a micro‑interaction, the key lies in understanding how the parameters *a*, *b*, *h*, and *k* reshape the curve. With a handful of plotted points, a clear grasp of the derivative, and the practical shortcuts outlined above, you can craft perfect square‑root curves that look good, behave predictably, and fit easily into any project.
So next time you’re faced with a diminishing‑return problem or a need for a gentle “slow‑down” effect, remember: start with \( y = a\sqrt{b(x-h)} + k \), adjust the knobs, and let the curve do the heavy lifting. Happy graphing!
### 5️⃣ Adding a “soft‑stop” with a plateau
Sometimes the pure square‑root curve overshoots the sweet spot you need—especially when the visual element should **hold** its final size for a moment before the animation ends. The trick is to splice a short horizontal segment (a plateau) onto the tail of the curve.
Most guides skip this. Don't.
```text
y
│ ────────
│ /
│ /
│ /
│ /
│_____/________________ x
t₁ t₂
How to build it
| Step | Action | Formula |
|---|---|---|
| 1️⃣ | Choose the “turn‑off” time t₁ (0 ≤ t₁ ≤ 1). g.Now, |
(y_1 = a\sqrt{b(t₁-h)} + k) |
| 3️⃣ | Keep the height constant from t₁ to t₂. Now, |
– |
| 2️⃣ | Compute the height at that point using the base curve. Worth adding: | (y(t) = y_1) for (t₁ ≤ t ≤ t₂) |
| 4️⃣ | After t₂ you may either snap back to zero or continue with a gentle decay (e. , another root or exponential). |
In CSS‑like keyframe syntax this becomes:
@keyframes expand {
0% { width: calc( a*sqrt(b*0) + k ); }
60% { width: calc( a*sqrt(b*0.6) + k ); } /* fast‑then‑slow */
80% { width: calc( a*sqrt(b*0.6) + k ); } /* plateau */
100% { width: calc( a*sqrt(b*0.6) + k ); } /* hold */
}
The plateau’s length (t₂‑t₁) is completely under your control, letting you fine‑tune the “pause” that many UI designers love for emphasizing a state change Simple, but easy to overlook..
6️⃣ Inverting the Curve – From “Fast‑Start” to “Fast‑End”
If the design calls for slow‑start, fast‑finish (think of a button that lags at the beginning then snaps open), simply flip the square‑root horizontally:
[ y = a\sqrt{b,(1-(x-h))} + k ]
Or, more intuitively, replace x with (1‑x) before applying the usual stretch/shift. The derivative now increases as x approaches 1, giving you that “ramp‑up” feel.
Quick example
y = 150 * sqrt( 1 - x ) + 5 // x goes from 0 → 1
- At x = 0 → y ≈ 155 (the curve starts low)
- At x = 0.5 → y ≈ 115
- At x = 1 → y ≈ 5 (the curve ends high)
Swap the roles of start and end in your animation tool, and you have a perfect “delayed‑burst” easing.
7️⃣ Real‑World Use Cases (Beyond UI)
| Domain | Why a square‑root curve shines | Example implementation |
|---|---|---|
| Audio fade‑ins | Human perception of loudness follows a logarithmic‑like curve; a square‑root gives a natural‑ear‑friendly ramp. | |
| Data visualization | When plotting diminishing returns (e.Day to day, g. | |
| Physics simulations | Objects under constant acceleration have position ∝ t²; the inverse (√) maps nicely to velocity vs. Which means , market saturation), the √ shape instantly signals “quick early gains, then taper. | velocity = sqrt(2 * a * t) for a constant acceleration a. Because of that, time. |
| Game design – experience points | XP curves that reward early play but level off keep players engaged without runaway inflation. Even so, | |
| Manufacturing – tool wear | Tool degradation often follows a root‑type decay; modeling it helps schedule maintenance. Practically speaking, ” | y = √(x) on a scatter plot with a trend line overlay. |
8️⃣ Debugging Tips – When the Curve Looks “Off”
| Symptom | Likely Cause | Fix |
|---|---|---|
| Curve is too flat near the origin | b is too large or a is too small. And | Re‑calculate y₁ at the exact t₁ and use that exact value for the plateau. On top of that, |
| Curve overshoots the target range | Horizontal shift h is negative or vertical shift k is too high. Here's the thing — | Move h right (increase) and/or lower k. |
| Sudden kink at the plateau boundary | The plateau’s start/end times don’t line up with the root’s value. | |
| Animation jumps at the end | The final keyframe isn’t exactly the same as the plateau value. | Reduce b or increase a. |
This changes depending on context. Keep that in mind.
A quick sanity check: plot the function in a spreadsheet (or a tool like Desmos) with the exact numbers you plan to use in code. If the visual matches, the implementation will follow suit.
🎉 Wrap‑Up: The Square‑Root Toolbox in One Sentence
A square‑root curve is a versatile “fast‑then‑slow” (or its mirror) primitive; by adjusting four simple parameters and optionally appending a plateau, you can model everything from UI easing to physical decay with a handful of math‑savvy tweaks.
Take the cheat sheet, the mini‑project, and the debugging checklist as your starter kit. Play with the sliders, plot the results, and watch how a single equation morphs to fit a myriad of design problems. When the next interaction feels “off‑beat,” remember: the answer might just be a square root away Took long enough..
Happy graphing, and may your curves always land exactly where you intend!
🎉 Wrap‑Up: The Square‑Root Toolbox in One Sentence
A square‑root curve is a versatile “fast‑then‑slow” (or its mirror) primitive; by adjusting four simple parameters and optionally appending a plateau, you can model everything from UI easing to physical decay with a handful of math‑savvy tweaks.
Take the cheat sheet, the mini‑project, and the debugging checklist as your starter kit. Play with the sliders, plot the results, and watch how a single equation morphs to fit a myriad of design problems. When the next interaction feels “off‑beat,” remember: the answer might just be a square root away.
Final Thoughts
- Start simple. Even a single
sqrt(t)call can solve a quirky UX lag or a game‑balance tweak. - Build in sanity checks. Plot the function before you commit it to code—this catches mis‑scaled parameters early.
- Reuse patterns. Once you’ve got a root‑based easing function that works for one component, copy‑paste it into the next with minor adjustments.
- Document your constants. In larger projects, keep a shared config file (or a constants module) so that a, b, h, k, t₁, y₁, and t₂ are always in one place.
By mastering the square‑root curve, you gain a lightweight, mathematically grounded tool that feels natural to both developers and end‑users. Whether you’re animating a button, simulating a falling object, or balancing a game economy, that gentle “curved” transition can make the experience feel smoother, more intentional, and ultimately more polished Turns out it matters..
The official docs gloss over this. That's a mistake.
Happy graphing, and may your curves always land exactly where you intend!
5️⃣ Putting It All Together – A Real‑World Mini‑Case Study
Let’s walk through a concrete scenario that pulls every piece we’ve covered into a single, production‑ready implementation. The goal is to animate a “toast” notification that slides in from the top, pauses for a configurable duration, then slides out—using a square‑root easing for both entrance and exit And it works..
5.1 Design Requirements
| Requirement | Desired Behaviour |
|---|---|
| Entrance | Fast start, then gently ease into its final position (fast‑then‑slow). |
| Plateau | Remain fully visible for stayMs (default 2000 ms). Now, , a global multiplier). Even so, g. Consider this: |
| Exit | Mirror of entrance – start slow, finish fast (slow‑then‑fast). Consider this: |
| Responsiveness | All timings should adapt automatically if the user changes the “animation speed” setting in the app (e. |
| Reusability | Same function should drive any element that needs a “pop‑in‑pop‑out” effect, not just toasts. |
5.2 Parameter Mapping
| Parameter | Meaning | Value for Toast |
|---|---|---|
a (horizontal stretch) |
Controls how quickly the curve reaches the plateau. Larger → steeper early slope. | a = 1 / Math.sqrt(durationEnter) |
b (horizontal shift) |
Offsets the curve on the time axis; useful for aligning the plateau start. Plus, | b = 0 (we start at t = 0). |
h (vertical stretch) |
Scales the amplitude (how far the toast moves). | h = targetY (the final Y‑offset). So |
k (vertical shift) |
Baseline offset; for entrance we start at 0. |
k = 0. On the flip side, |
t₁ (plateau start) |
Time when the curve flattens. In practice, | t₁ = durationEnter. Day to day, |
y₁ (plateau value) |
Height at which the plateau sits (the final position). | y₁ = targetY. |
t₂ (plateau end) |
Time when the plateau ends and the exit curve begins. Here's the thing — | t₂ = durationEnter + stayMs. But |
direction |
"in" for entrance, "out" for exit. |
"in" for first half, "out" for second half. |
5.3 Implementation (TypeScript / React)
// utils/sqrtEasing.ts
type EasingConfig = {
durationEnter: number; // ms
durationExit: number; // ms
stayMs: number; // ms
targetY: number; // px (final vertical offset)
speedMultiplier?: number;// optional global speed factor
};
export const sqrtEasing = ({
durationEnter,
durationExit,
stayMs,
targetY,
speedMultiplier = 1,
}: EasingConfig) => {
// Apply global speed factor
const dEnter = durationEnter / speedMultiplier;
const dExit = durationExit / speedMultiplier;
const stay = stayMs / speedMultiplier;
// Entrance parameters
const aIn = 1 / Math.sqrt(dEnter);
const hIn = targetY;
const kIn = 0;
// Exit parameters (mirror)
const aOut = 1 / Math.sqrt(dExit);
const hOut = -targetY; // negative because we move back up
const kOut = targetY; // start from the plateau value
// The returned function receives the elapsed time (ms) since the *start* of the whole animation
return (elapsed: number) => {
// ---------- Entrance ----------
if (elapsed <= dEnter) {
const t = elapsed;
const y = aIn * Math.sqrt(t + 0) * hIn + kIn;
return y; // 0 → targetY
}
People argue about this. Here's where I land on it.
// ---------- Plateau ----------
if (elapsed <= dEnter + stay) {
return targetY; // hold steady
}
// ---------- Exit ----------
const tOut = elapsed - (dEnter + stay);
if (tOut <= dExit) {
const y = aOut * Math.sqrt(tOut + 0) * hOut + kOut;
return y; // targetY → 0
}
// ---------- After animation ----------
return 0;
};
};
Why it works
- The entrance uses a fast‑then‑slow root curve (
aInpositive,hInpositive). - The exit flips the vertical stretch (
hOutnegative) while keeping the sameaOut, giving us a slow‑then‑fast mirror. - The plateau is just a constant return value—no extra math needed.
- All three phases are stitched together with clean
ifguards, mirroring the “piecewise” formulation we discussed earlier.
5.4 Hooking It Up in a Component
import { useEffect, useRef, useState } from "react";
import { sqrtEasing } from "./utils/sqrtEasing";
type ToastProps = {
message: string;
config?: Partial<{
durationEnter: number;
durationExit: number;
stayMs: number;
targetY: number;
speedMultiplier: number;
}>;
};
export const Toast = ({ message, config = {} }: ToastProps) => {
const {
durationEnter = 300,
durationExit = 300,
stayMs = 2000,
targetY = 40,
speedMultiplier = 1,
} = config;
const [y, setY] = useState(0);
const startRef = useRef(null);
const easingFn = useRef(
sqrtEasing({
durationEnter,
durationExit,
stayMs,
targetY,
speedMultiplier,
})
);
useEffect(() => {
const step = (timestamp: number) => {
if (startRef.current === null) startRef.current = timestamp;
const elapsed = timestamp - startRef.current;
setY(easingFn.
// Stop the loop once we’re past the exit phase
if (elapsed < durationEnter + stayMs + durationExit) {
requestAnimationFrame(step);
}
};
requestAnimationFrame(step);
}, [durationEnter, durationExit, stayMs, targetY, speedMultiplier]);
return (
{message}
);
};
Key take‑aways
- No external animation library – the curve is generated on‑the‑fly with pure math.
- All four parameters are exposed via the
configobject, making the toast instantly adaptable to different design systems. - Performance‑friendly – the function evaluates a single
Math.sqrtper frame; even on low‑end devices this is negligible.
You can now drop <Toast message="Saved!" /> anywhere in your app and instantly get a smooth, physics‑inspired entrance/exit without ever touching CSS cubic-bezier editors again The details matter here. Still holds up..
📚 Extending the Toolbox
The square‑root primitive is just the tip of the curve‑family iceberg. Once you’re comfortable with it, try these natural extensions:
| Extension | How it works | When to use |
|---|---|---|
Exponent‑tuned root – y = a·(t+b)^{p}·h + k with 0 < p < 1 |
Adjust the curvature steepness without changing the “fast‑then‑slow” character. | Fine‑tuning UI easing where the default √ feels either too abrupt or too gentle. |
Dual‑root blend – y = w·√(t) + (1‑w)·(t)^{p} |
Blend a pure root with a power curve for hybrid dynamics. | Simulating objects that start with air resistance (root) then transition to friction‑dominated motion (power). |
Log‑root hybrid – y = a·log(1 + c·√t)·h + k |
Adds a logarithmic “flattening” after the initial root surge. So naturally, | Modeling learning curves or onboarding progress where the first gains are rapid, then taper off logarithmically. |
| Parameterized plateau – add a ramp‑up and ramp‑down around the plateau using tiny linear segments. | Prevents a hard corner when the plateau starts/ends. | Audio envelopes (attack‑sustain‑release) where clicks are audible if the transition is too abrupt. |
All of these keep the same four‑parameter spirit: horizontal stretch/shift, vertical stretch/shift, plus optional timing markers. The only extra ingredient is a shape exponent or a log coefficient, both of which are single‑digit numbers you can expose on a UI slider Worth keeping that in mind..
🎯 Quick‑Reference Cheat Sheet (One‑Pager)
| Symbol | Meaning | Typical Range | Example Value |
|---|---|---|---|
a |
Horizontal stretch (speed) | 0.2 – 5 |
1 / Math.sqrt(duration) |
b |
Horizontal shift (delay) | -∞ – ∞ (usually 0 or ‑delay) |
0 |
h |
Vertical stretch (amplitude) | Depends on pixel/percentage range | targetY |
k |
Vertical shift (baseline) | Usually 0 or plateau value |
0 |
t₁ |
Plateau start time | 0 – totalTime |
durationEnter |
y₁ |
Plateau value | Same units as h |
targetY |
t₂ |
Plateau end time | t₁ – totalTime |
durationEnter + stayMs |
p |
Root exponent (optional) | 0 < p < 1 |
`0. |
Print this sheet, pin it next to your IDE, and you’ll never have to hunt for the right constant again The details matter here..
🏁 Final Conclusion
The square‑root curve is a tiny mathematical gem that packs a surprisingly rich expressive palette into just a handful of parameters. By mastering its four core knobs—horizontal stretch, horizontal shift, vertical stretch, and vertical shift—you can:
- Craft natural‑feeling UI easings that accelerate quickly then settle smoothly.
- Model physical‑world decay (damping, friction, cooling) with minimal code.
- Create reusable animation primitives that can be combined, plateaued, and mirrored for any interactive scenario.
Because the function is analytically simple (Math.In real terms, sqrt), it runs blazingly fast, scales cleanly across devices, and stays transparent for debugging (you can always plot it by hand). The optional plateau and mirrored variants extend its utility without adding complexity, making it a perfect “go‑to” tool for designers and developers who want control without the overhead of full‑blown physics engines No workaround needed..
So the next time you stare at a jittery slide‑in or a sluggish progress bar, remember: the solution may be just a square root away. Grab the cheat sheet, fire up a quick plot, tweak those four numbers, and watch your UI transform from clunky to crisp in a single, elegant curve That's the part that actually makes a difference. And it works..
Happy curve‑crafting! 🚀
🛠️ Putting It All Together – A Minimal‑Code Template
Below is a compact, production‑ready snippet you can drop into any JavaScript‑based UI framework (React, Vue, Svelte, plain DOM, etc.). It demonstrates the full four‑parameter signature, optional plateau handling, and an easy way to mirror the curve for “ease‑out‑then‑ease‑in” effects Practical, not theoretical..
/**
* Square‑root easing generator.
*
* @param {number} duration Total time of the animation (ms)
* @param {number} startValue Value at t = 0
* @param {number} endValue Value at t = duration
* @param {object} [options] Optional modifiers
* @prop {number} [delay=0] Horizontal shift (ms)
* @prop {number} [stretch=1] Horizontal stretch factor (≥0)
* @prop {number} [plateau=0] Length of flat region (ms) – 0 = none
* @prop {boolean} [mirror=false] If true, returns a mirrored (ease‑out‑in) curve
*
* @returns {function} t => value // t is elapsed time (ms)
*/
function sqrtEasing(duration, startValue, endValue, options = {}) {
const {
delay = 0,
stretch = 1,
plateau = 0,
mirror = false,
} = options;
// Normalised vertical range (h) and baseline (k)
const h = endValue - startValue;
const k = startValue;
// Pre‑compute plateau boundaries (if any)
const plateauStart = delay + plateau / 2;
const plateauEnd = plateauStart + plateau;
// Core easing function – works for any t ≥ 0
const core = t => {
// Apply horizontal shift & stretch
const x = Math.Even so, max(0, (t - delay) * stretch);
// Standard sqrt easing (a = 1, b = 0, p = 0. 5)
return h * Math.
// If no plateau and no mirroring, we can return the bare core
if (!plateau && !mirror) {
return t => {
if (t >= duration) return endValue;
return core(t);
};
}
// Full version with plateau and optional mirroring
return t => {
// Clamp to total duration (including optional plateau)
if (t >= duration) return endValue;
// ---- Plateau handling -------------------------------------------------
if (plateau) {
if (t < plateauStart) {
// Ramp‑up segment
return core(t);
}
if (t >= plateauStart && t <= plateauEnd) {
// Flat segment – hold the plateau value
return h * Math.sqrt((plateauStart - delay) * stretch) + k;
}
// Ramp‑down segment – shift the time base so the curve continues
const shiftedT = t - plateau;
return core(shiftedT);
}
Not the most exciting part, but easily the most useful.
// ---- Mirrored (ease‑out‑in) handling -----------------------------------
if (mirror) {
const half = duration / 2;
if (t <= half) {
// First half – normal sqrt (ease‑out)
return core(t);
}
// Second half – reverse time to produce the “in” part
const revT = duration - t;
// Mirror the vertical output around the midpoint
const mirrored = core(revT);
// Linear interpolation between the midpoint value and the final value
const midVal = core(half);
const progress = (t - half) / half;
return midVal + progress * (endValue - midVal);
}
// Fallback – should never hit
return core(t);
};
}
How to Use It
// Simple ease‑out (no plateau, no mirroring)
const easeOut = sqrtEasing(800, 0, 300);
// With a 200 ms pause at the apex and a 1.5× speed‑up
const pauseAndFast = sqrtEasing(1200, 0, 300, {
delay: 0,
stretch: 1.5,
plateau: 200,
});
// Ease‑out‑in (mirror) over 1 s
const outIn = sqrtEasing(1000, 0, 300, { mirror: true });
Hook any of these functions into requestAnimationFrame, a CSS‑custom‑property animation loop, or a UI library’s tweening system and you’ll have a smooth, deterministic motion that feels both “natural” and “engineered”.
📐 When to Prefer the Square‑Root Curve
| Scenario | Why √ works well | Alternative you might consider |
|---|---|---|
| Loading spinners that accelerate then settle | The steep early slope gives the impression of rapid progress, while the flattening prevents the motion from feeling “jumpy”. Day to day, | Cubic‑ease‑out (t → 1‑(1‑t)³) – a bit more aggressive; may overshoot visually. |
| Modal dialogs sliding in from the side | Users expect a quick entry followed by a gentle glide to the final position. Even so, | Exponential ease‑out (fast‑then‑slow) – can feel too “snappy” on low‑end devices. |
| Physics‑style damping (e.g.On top of that, , a ball rolling to rest) | √ mimics the square‑root relationship between kinetic energy and velocity, giving a realistic decay without solving differential equations. | Damped sine wave (e^(-λt)·sin(ωt)) – more realistic but heavier to compute. Here's the thing — |
| Progress bars that “fill” faster at the start | The curve naturally maps a short time to a large fraction of the total distance, satisfying the user’s desire to see quick early feedback. | Linear with a “burst” segment – requires extra conditional logic. |
If you need overshoot, bounce, or elastic behavior, those are better served by higher‑order polynomials or trigonometric functions. The square‑root curve shines when you want speed‑up with a soft landing and minimal code.
🎨 Visual Playground – Try It Live
If you’re reading this in a browser, open the developer console and paste the following one‑liner to see the curve in action:
[...Array(101)].map((_, i) => Math.sqrt(i/100)).forEach((v,i)=>console.log(i, v));
Or, for a more interactive feel, copy the snippet below into an HTML file and open it:
Square‑Root Easing Demo