Skip to content

feat(money): tilt-driven parallax on Money onboarding card (MUSD-1048)#32892

Merged
Kureev merged 6 commits into
mainfrom
kureev/MUSD-1048-parallax
Jul 9, 2026
Merged

feat(money): tilt-driven parallax on Money onboarding card (MUSD-1048)#32892
Kureev merged 6 commits into
mainfrom
kureev/MUSD-1048-parallax

Conversation

@Kureev

@Kureev Kureev commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a subtle, tilt-driven parallax animation to the "Fund your account" onboarding card on the Money home screen (part of the MUSD-1048 motion work).

The card graphic is a Rive animation (Parallax Block 1 artboard) whose layers respond to device orientation via data-bound xValue/yValue:

  • MoneyNextBestActionParallax renders the Rive artboard with a gradient background behind the transparent artboard, and degrades gracefully to the existing static step image when the feature flag is off, reduce-motion is enabled, or Rive fails to load.
  • useDeviceOrientation derives absolute pitch/roll from the accelerometer with a natural-hold (~45°) neutral, so it is drift-free and centred when the phone is held normally. The angle math (accelerationToTilt) is a pure, unit-tested function.
  • StepperCard gains an optional media slot so the animated graphic replaces the static step image without affecting any other consumer.
  • Gated behind selectMoneyParallaxAnimationEnabledFlag (version-gated remote flag with a local env fallback), and respects OS reduce-motion.

Changelog

CHANGELOG entry: Added a subtle tilt-driven parallax animation to the Money "Fund your account" onboarding card.

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/MUSD-1048

Manual testing steps

Feature: Money onboarding card parallax

  Scenario: Tilting the device animates the onboarding card graphic
    Given I have a Money account with a $0 balance
    And I am on the Money home screen showing the "Fund your account" onboarding card

    When I tilt the device left/right and forward/back
    Then the card graphic layers shift with a subtle parallax
    And the graphic is centred when the device is held naturally

  Scenario: Reduced motion falls back to a static image
    Given the OS "reduce motion" accessibility setting is enabled

    When I view the "Fund your account" onboarding card
    Then the static card image is shown with no animation

Screenshots/Recordings

Before

Static "Fund your account" card image (no motion).

After

IMG_4300.MOV
IMG_4299.MOV

Screen recording on a physical Android device to be attached.

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Low Risk
Opt-in UI motion with static fallbacks, accessibility reduce-motion, and no changes to money/account logic; main risk is accelerometer/Rive battery or perf on low-end devices, mitigated by throttling and feature gating.

Overview
Adds tilt-driven Rive parallax to Money onboarding StepperCard steps (fund + card), gated by selectMoneyParallaxAnimationEnabledFlag (earnMoneyParallaxAnimationEnabled remote + MM_MONEY_PARALLAX_ANIMATION_ENABLED env, default off).

StepperCard now accepts optional media to replace the step image. MoneyOnboardingCard wires MoneyNextBestActionParallax per step artboard, with static PNG fallbacks.

MoneyNextBestActionParallax plays next_best_action_module_v1.riv, maps device tilt to Rive xValue/yValue, and falls back when the flag is off, reduce motion is on, or Rive errors. useDeviceOrientation (accelerometer, low-pass, 30/60 Hz on low-end devices) and useReduceMotion support that path.

Registry entry for earnMoneyParallaxAnimationEnabled and broad unit tests; parent tests mock the parallax component.

Reviewed by Cursor Bugbot for commit 7df7e3c. Bugbot is set up for automated code reviews on this repo. Configure here.

Add a subtle, tilt-driven parallax animation to the "Fund your account"
onboarding card on the Money home screen, driven by a Rive graphic whose
layers respond to device orientation.

- MoneyNextBestActionParallax renders the Rive "Parallax Block 1" artboard
  with data-bound xValue/yValue, a gradient background behind the transparent
  artboard, and a static-image fallback (feature flag / reduce-motion / error).
- useDeviceOrientation derives absolute pitch/roll from the accelerometer with
  a natural-hold neutral (drift-free); the pure accelerationToTilt is unit-tested.
- StepperCard gains an optional media slot so the graphic replaces the static
  step image without affecting other consumers.
- Gate behind selectMoneyParallaxAnimationEnabledFlag.
@Kureev Kureev added team-earn pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. labels Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@github-actions github-actions Bot added the size-L label Jul 7, 2026
Kureev added 2 commits July 7, 2026 16:08
The tilt-driven parallax on the Money onboarding card doesn't need a
kill-switch — reduce-motion and the Rive-error fallback already provide
graceful degradation. Remove selectMoneyParallaxAnimationEnabledFlag and its
usage/tests; animation now gates solely on reduce-motion and Rive load errors.
The Rive file carries a second card artboard for the "Get MetaMask card"
onboarding step. Parameterize MoneyNextBestActionParallax with an artboardName
prop and render the appropriate block per step:

- PARALLAX_ARTBOARD_FUND ("Parallax Block 1") for step 1 (Fund your account)
- PARALLAX_ARTBOARD_CARD ("Parallax Block 2") for step 2 (Get MetaMask card),
  shared across both step-2 variants

Block 3 is the 786x1704 full-screen reference artboard and is not used in-app.
The gradient background is shared (step 2 uses the same indigo-to-blue).
@Kureev Kureev self-assigned this Jul 7, 2026
@Kureev Kureev removed the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label Jul 7, 2026
@Kureev Kureev marked this pull request as ready for review July 7, 2026 14:39
@Kureev Kureev requested review from a team as code owners July 7, 2026 14:39

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 89aebb7. Configure here.

Comment thread app/components/UI/Money/hooks/useReduceMotion.ts
- Re-add selectMoneyParallaxAnimationEnabledFlag gating so Rive/accelerometer
  work only runs when the flag is on (falls back to the static image otherwise).
- Default useReduceMotion to true so reduce-motion users never briefly see the
  animation before the async accessibility check resolves.
- Guard applyTilt on the Rive instance before driving the view-model setters.
- Restore full-size (w-full aspect-video) sizing to the static fallback branch
  so the image fills the stepper slot as before.
- Mock MoneyNextBestActionParallax in MoneyHomeView tests; rendering the real
  Rive graphic pulled in device sensors that the unit-test env stubs out.
@github-actions github-actions Bot added the risk:medium AI analysis: medium risk label Jul 7, 2026
Add the parallax animation flag to the feature-flag registry so the CI
registry check passes. Not yet in prod (inProd: false).
@Kureev Kureev requested a review from a team as a code owner July 7, 2026 16:14
* Optional custom media rendered in the image slot in place of `image`
* (e.g. an animated graphic). Falls back to `image` when not provided.
*/
media?: ReactNode;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the media being rendered in the StepperCard. It's only being used as a condition. Is that intended?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StepperCard.tsx:60

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not as a condition, but as a ??, so if media exists, it will use it, otherwise fallback to Image

@@ -0,0 +1,132 @@
import React, { useCallback, useState } from 'react';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you haven't already it would be worth creating a Testflight build via GH action to see how it responds on iOS. I noticed for the first time deposit animation that iOS and Android flipped the y-axis. Not a big problem tbh it's just something I didn't know until I tested on both.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have TF access, but will ask @shane-t to take a look if he has time

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should get you access to TestFlight. When you get a sec can you ping the mobile-platform team in #metamask-mobile-dev and request to be added to the internal tester group? Seats are limited but we should still have room.

source={NextBestActionParallaxAnimation}
artboardName={artboardName}
dataBinding={AutoBind(true)}
fit={Fit.Contain}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: I think Fit.Contain can sometimes aggressively shrink the Rive animation on different devices. I'm not a Rive expert but I think fit={Fit.Layout} is meant to be more responsive (as long as the animation file is leveraging responsive layout).

Comment thread app/components/UI/Money/selectors/featureFlags.ts Outdated
Comment thread app/components/UI/Money/selectors/featureFlags.ts Outdated
- Gate all accelerometer setup (interval + device-memory read) on `enabled`, so
  no sensor work happens when the flag is off or reduce-motion is on.
- Default the parallax flag to off (opt-in): the local fallback now requires
  MM_MONEY_PARALLAX_ANIMATION_ENABLED="true", matching the registry's
  productionDefault of false, so the feature stays disabled unless explicitly on.
- Document MM_MONEY_PARALLAX_ANIMATION_ENABLED in .js.env.example.
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeMoney
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: low
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
The PR introduces a new parallax animation component (MoneyNextBestActionParallax) for the MetaMask Card onboarding flow, gated behind a new feature flag earnMoneyParallaxAnimationEnabled (defaulting to false in production). Key changes:

  1. Feature flag registry (CRITICAL file): Adds earnMoneyParallaxAnimationEnabled - additive, low-risk change.
  2. MoneyNextBestActionParallax: New component using Rive animation + device orientation for tilt-driven parallax effect on the Money onboarding card.
  3. StepperCard: Backward-compatible change adding optional media prop to replace static image with custom content.
  4. MoneyOnboardingCard: Integrates the new parallax component into the onboarding steps.
  5. New hooks: useDeviceOrientation and useReduceMotion for animation control.
  6. Feature flag selector: selectMoneyParallaxAnimationEnabledFlag added.

The changes are entirely within the Money/Card feature area. The StepperCard component is only imported by MoneyOnboardingCard (confirmed via importers search). The feature is off by default in production. The E2E test card-home-add-funds.spec.ts (SmokeMoney tag) covers the Card Home and Add Funds flow which is the affected area. No shared navigation, confirmations, or core infrastructure is affected. SmokeMoney is the only relevant tag.

Performance Test Selection:
The parallax animation is gated behind a feature flag that defaults to false in production. No performance-sensitive flows (launch, login, asset loading, swaps, etc.) are affected. The changes are purely UI additions to the Card onboarding screen with no impact on measured performance scenarios.

View GitHub Actions results

@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

@Kureev Kureev requested review from Matt561 and brianacnguyen July 8, 2026 09:13
@Kureev Kureev enabled auto-merge July 8, 2026 21:03
@Kureev Kureev added this pull request to the merge queue Jul 9, 2026
Merged via the queue into main with commit 2c093a5 Jul 9, 2026
98 checks passed
@Kureev Kureev deleted the kureev/MUSD-1048-parallax branch July 9, 2026 10:03
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 9, 2026
@mm-token-exchange-service mm-token-exchange-service Bot added the release-8.3.0 Issue or pull request that will be included in release 8.3.0 label Jul 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-8.3.0 Issue or pull request that will be included in release 8.3.0 risk:medium AI analysis: medium risk size-L team-earn

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants