Skip to content

Commit 337edbd

Browse files
authored
Add animate-by-scroll example and update docs (#7487)
Docs and comments only <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a scroll-driven animation example demonstrating how to control chart animations based on scroll position. * **Documentation** * Enhanced animation guide with a new section on customizing animation controllers, including use-case examples and related resources. * Added documentation references to animation functionality. * **Chores** * Updated test exclusion lists for animation-related exports. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 0063aa4 commit 337edbd

6 files changed

Lines changed: 62 additions & 5 deletions

File tree

‎src/animation/AnimationController.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { AnimationHandle } from './AnimationHandle';
66
* and CSS transition-based animations always produce strings,
77
* but it's so much easier to just have them together than to deal with all the generics.
88
*
9+
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animation guide}
10+
*
911
* @since 3.9
1012
*/
1113
export type OnAnimationStateUpdate = (newState: number | string) => void;
@@ -20,6 +22,8 @@ export type OnAnimationStateUpdate = (newState: number | string) => void;
2022
* and calling the onAnimationStart and onAnimationEnd callbacks at the right time,
2123
* while the AnimationController is responsible for calling the tick method of the animation state machine.
2224
*
25+
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animation guide}
26+
*
2327
* @since 3.9
2428
*/
2529
export type AnimationController = (

‎src/animation/AnimationHandle.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ export class CSSTransitionAnimation extends RechartsAnimation<string, NamedBezie
300300
* - the transition itself, takes `animationDuration` ms to finish
301301
* - `onAnimationEnd`: function that is called when the animation is moving from `active` to `completed`
302302
*
303+
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animation guide}
304+
*
303305
* @since 3.9
304306
*/
305307
export type AnimationHandle = JavascriptAnimation | CSSTransitionAnimation;

‎src/animation/timeoutController.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export type CancelableTimeout = () => void;
2222
* - unit tests
2323
* - animations based on something other than time: UI controls, page scroll, mouse movement ...
2424
*
25+
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animation guide}
26+
*
2527
* @since 3.9
2628
*/
2729
export interface TimeoutController {

‎src/animation/useAnimationController.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ const AnimationControllerContext = createContext<AnimationController>(animationC
1313
* - Unit tests are an excellent use (Recharts itself has ton of tests with mock TimeoutController)
1414
* - If you want to animate charts back and forth (Recharts only animates forward)
1515
* - If you want to replace requestAnimationFrame with something else
16-
* - Perhaps a manual animation controls (`@recharts/devtools` does this, it's available on https://recharts.github.io too)
16+
* - Perhaps a manual animation controls (https://recharts.github.io does this)
1717
* - If you want to maybe animate charts based on mouse movement, or page scroll position, instead of time
1818
*
1919
* If you don't use this provider then all charts use the default requestAnimationFrame and default animation logic.
2020
*
2121
* If you use this component then all charts inside use your custom animationController.
2222
*
23+
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animation guide}
24+
*
2325
* @since 3.9
2426
*/
2527
export const AnimationControllerProvider = AnimationControllerContext.Provider;

‎www/src/components/GuideView/Animations/index.tsx‎

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ export function AnimationsGuide() {
409409
stackBlitzTitle="Recharts Custom Animation Example"
410410
defaultTool="controls"
411411
/>
412-
413412
<p>
414413
Also see our other custom animation examples:
415414
<ul>
@@ -428,7 +427,6 @@ export function AnimationsGuide() {
428427
</li>
429428
</ul>
430429
</p>
431-
432430
<h2>Custom shape animations</h2>
433431
<p>
434432
While <code>animationInterpolateFn</code> controls how <em>data points</em> move during animation, some
@@ -602,6 +600,56 @@ export function AnimationsGuide() {
602600
</tr>
603601
</tbody>
604602
</table>
603+
<h2>Customize animation controller</h2>
604+
<p>
605+
Since 3.9 recharts allows you to completely override the controller using{' '}
606+
<LinkToApi>AnimationControllerProvider</LinkToApi>. The animation controller is responsible for communication
607+
between the timing, animation handle, and listener. By default, Recharts uses a requestAnimationFrame-based
608+
controller, but you can implement your own to drive animations from any source: scroll position, WebSocket data,
609+
or even manual controls.
610+
</p>
611+
<p>
612+
Why would you want to use this? Several reasons:
613+
<ul>
614+
<li>Unit tests are an excellent use (Recharts itself has ton of tests with mock TimeoutController)</li>
615+
<li>If you want to animate charts back and forth</li>
616+
<li>
617+
If you want to replace requestAnimationFrame with something else. Perhaps a manual animation controls, as
618+
you can see on every chart on this website
619+
</li>
620+
<li>
621+
If you want to maybe animate charts based on mouse movement, or page scroll position, instead of time{' '}
622+
</li>
623+
</ul>
624+
If you do not use this provider then all charts use the default requestAnimationFrame and default animation
625+
logic.
626+
</p>
627+
<p>
628+
See <RechartsLink to="/examples/ScrollAnimateBarChart">ScrollAnimateBarChart example</RechartsLink> where chart
629+
animates in response to page scroll, not time.
630+
</p>
631+
<p>
632+
See{' '}
633+
<a href="https://github.com/recharts/recharts/blob/main/test/animation/mockAnimationController.ts">
634+
mockAnimationController.ts
635+
</a>{' '}
636+
and{' '}
637+
<a href="https://github.com/recharts/recharts/blob/main/test/animation/MockProgressAnimationManager.ts#L113">
638+
MockProgressAnimationManager
639+
</a>{' '}
640+
to see how Recharts tests animation. Our unit tests then look for example like this:{' '}
641+
<a href="https://github.com/recharts/recharts/blob/main/test/cartesian/Line.animation.spec.tsx">
642+
Line.animation.spec.tsx
643+
</a>
644+
.
645+
</p>
646+
<p>
647+
See{' '}
648+
<a href="https://github.com/recharts/recharts/blob/main/www/src/components/ManualAnimationContext.tsx">
649+
ManualAnimationContext.tsx
650+
</a>{' '}
651+
with code that handles manual animations here on this website.
652+
</p>
605653
</article>
606654
);
607655
}

‎www/src/components/ManualAnimationContext.tsx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ function TimeSetter() {
151151
const radioGroupStyle: CSSProperties = {
152152
display: 'flex',
153153
gap: '12px',
154+
margin: '1ex',
154155
};
155156

156157
/* Label: Vertically centers the default circle with the text */
@@ -159,8 +160,6 @@ const radioLabelStyle = {
159160
alignItems: 'center' /* Forces perfect vertical alignment */,
160161
gap: '8px' /* Adjust this to change space between circle and text */,
161162
cursor: 'pointer',
162-
fontSize: '16px',
163-
color: '#333',
164163
};
165164

166165
/* Optional: Make the default radio slightly larger if it feels tiny */

0 commit comments

Comments
 (0)