feat(cursor): improve animated cursor accessibility and performance (…#486
Conversation
…hover-only, reduced-motion)\n\n- Scope cursor hiding to hover-capable, fine pointers\n- Respect prefers-reduced-motion to disable animations\n- Keep existing cursor types and trail effects intact\n\nRefs: RamakrushnaBiswal#273
|
@NirajK017 is attempting to deploy a commit to the bunty's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Thank you for submitting your pull request! 🙌 We'll review it as soon as possible. In the meantime, please ensure that your changes align with our CONTRIBUTING.md. If there are any specific instructions or feedback regarding your PR, we'll provide them here. Thanks again for your contribution! 😊 |
WalkthroughIntroduces a CSS-based animated cursor system with a primary conical cursor, trailing element, and stateful variants (hover, clicking, and type-specific: link, button, input, nav, hero). Includes multiple keyframe animations, pseudo-element effects, responsive/mobile fallbacks, and prefers-reduced-motion handling. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| @keyframes pulse { | ||
| 0%, 100% { | ||
| transform: scale(1); | ||
| } | ||
| 50% { | ||
| transform: scale(1.05); | ||
| } | ||
| } | ||
|
|
||
| @keyframes trailPulse { | ||
| 0%, 100% { | ||
| transform: scale(1); | ||
| opacity: 0.3; | ||
| } | ||
| 50% { | ||
| transform: scale(1.1); | ||
| opacity: 0.2; | ||
| } | ||
| } |
There was a problem hiding this comment.
Animated cursor loses positioning whenever pulse/trailPulse runs
Both keyframes overwrite the whole transform property with just a scale. As soon as the animation ticks, we drop the translate(-50%, -50%) rotate(45deg) that keeps the cursor aligned with the pointer, so the cursor and trail jump away from the pointer (top-left anchored) and flicker orientation. This breaks the feature on every hover-capable device.
Please preserve the base translate/rotate in each keyframe:
@keyframes pulse {
- 0%, 100% {
- transform: scale(1);
- }
- 50% {
- transform: scale(1.05);
- }
+ 0%, 100% {
+ transform: translate(-50%, -50%) rotate(45deg) scale(1);
+ }
+ 50% {
+ transform: translate(-50%, -50%) rotate(45deg) scale(1.05);
+ }
}
@keyframes trailPulse {
- 0%, 100% {
- transform: scale(1);
+ 0%, 100% {
+ transform: translate(-50%, -50%) rotate(45deg) scale(1);
opacity: 0.3;
}
50% {
- transform: scale(1.1);
+ transform: translate(-50%, -50%) rotate(45deg) scale(1.1);
opacity: 0.2;
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @keyframes pulse { | |
| 0%, 100% { | |
| transform: scale(1); | |
| } | |
| 50% { | |
| transform: scale(1.05); | |
| } | |
| } | |
| @keyframes trailPulse { | |
| 0%, 100% { | |
| transform: scale(1); | |
| opacity: 0.3; | |
| } | |
| 50% { | |
| transform: scale(1.1); | |
| opacity: 0.2; | |
| } | |
| } | |
| @keyframes pulse { | |
| 0%, 100% { | |
| transform: translate(-50%, -50%) rotate(45deg) scale(1); | |
| } | |
| 50% { | |
| transform: translate(-50%, -50%) rotate(45deg) scale(1.05); | |
| } | |
| } | |
| @keyframes trailPulse { | |
| 0%, 100% { | |
| transform: translate(-50%, -50%) rotate(45deg) scale(1); | |
| opacity: 0.3; | |
| } | |
| 50% { | |
| transform: translate(-50%, -50%) rotate(45deg) scale(1.1); | |
| opacity: 0.2; | |
| } | |
| } |
🤖 Prompt for AI Agents
In frontend/src/components/AnimatedCursor.css around lines 105 to 123, the pulse
and trailPulse keyframes overwrite the entire transform so the base
translate(-50%,-50%) rotate(45deg) is lost during animation; update every
keyframe step to include the base translate and rotate while applying scale (and
opacity for trailPulse) — e.g. use transform: translate(-50%,-50%) rotate(45deg)
scale(... ) at 0%, 50% and 100% (and keep opacity changes only in trailPulse) so
the cursor stays positioned and oriented while pulsing.
…hover-only, reduced-motion)\n\n- Scope cursor hiding to hover-capable, fine pointers\n- Respect prefers-reduced-motion to disable animations\n- Keep existing cursor types and trail effects intact\n\nRefs: #273
Summary by CodeRabbit