Skip to content

Tổng quan ​

react-native-shared-hero là thư viện shared element (hero) transition thuần native dành cho React Native New Architecture (Fabric) trên iOS và Android.

Cách dùng rất trực quan: bạn bọc view ở màn hình A và view ở màn hình B trong <SharedHero id="...">. Khi màn hình B được mount (hoặc khi màn hình B unmount để quay về A), coordinator ở tầng native sẽ chụp lại trạng thái hai đầu, tạm ẩn hai view thật trong lúc bay và diễn hoạt bản sao trên một lớp overlay cấp Window ở tốc độ làm tươi gốc của màn hình (60 fps hoặc 120 fps ProMotion).

Showcase ​

AndroidiOS

Vì sao lại cần một hướng tiếp cận mới? ​

Khi làm shared element transition trên React Native (đặc biệt với New Architecture), anh em dev thường vướng 3 vấn đề kinh điển:

1. Phụ thuộc chặt vào Stack Navigator

Nhiều thư viện can thiệp trực tiếp vào transition của react-native-screens. Cách này sẽ gãy ngay khi bạn mở native modal, transparent modal, form sheet, <Modal> mặc định của React Native, hoặc chỉ muốn phóng to một chiếc thẻ ngay trên cùng màn hình thông qua state.

2. Bị cắt khung (clipping) bởi view cha

Khi bản sao đang bay vẫn nằm bên trong view container của một màn hình hoặc sheet, bất kỳ view cha nào đặt overflow: 'hidden' hoặc khung giới hạn của bottom sheet đều sẽ cắt mất một phần view đang bay.

3. Vỡ nét ảnh thumbnail khi phóng to

Nếu chỉ lấy ảnh bitmap của thumbnail nhỏ ở danh sách rồi kéo giãn (scale) lên kích thước ảnh bìa lớn ở màn hình chi tiết, ảnh sẽ bị mờ trong suốt quá trình bay. react-native-shared-hero tự động nhận diện trường hợp hai đầu là <Image> và thay bằng ảnh độ phân giải cao của màn hình đích ngay khi decode xong.

react-native-shared-hero giải quyết các điểm nghẽn này từ tầng kiến trúc:

  • Overlay ở tầng Window: Trên iOS, quá trình bay được render trong một UIWindow riêng trong suốt (windowLevel = .alert + 1, isUserInteractionEnabled = false) cho phép xuyên thao tác chạm, nằm trên mọi UIViewController, modal và sheet. Trên Android, phần tử bay trong DecorView.overlay (ViewGroupOverlay). Không có bất kỳ container nào trong cây React có thể che hay cắt view đang bay.
  • Tách biệt hoàn toàn khỏi Router: Việc ghép cặp (pairing) dựa trên vòng đời mount, layout và unmount của native view trong một cửa sổ thời gian ngắn. Nhờ vậy bạn dùng với React Navigation, Expo Router, <Modal> hay useState đều chạy giống hệt nhau.
  • Không tốn tài nguyên khi đứng yên: Khi không có transition nào chạy, cửa sổ overlay không giữ bất kỳ view con nào (backgroundColor = .clear, isUserInteractionEnabled = false), bộ nhớ đệm snapshot dự phòng (lastKnownSnapshots) được giới hạn chặt bằng cơ chế LRU và chỉ chụp lại khi kích thước hoặc view con thực sự thay đổi.

Bảng tính năng ​

Tính năngiOSAndroidGhi chú
Fabric (New Architecture)CóCóViết dưới dạng Fabric ViewManager / RCTViewComponentView
mode="snapshot"CóCóChụp bitmap nhanh, di chuyển + scale + đổi độ mờ
mode="morph"CóCóNội suy mượt khung kích thước, borderRadius, backgroundColor và clip
motionPath="linear" / "arc"CóCóBay thẳng hoặc bay theo đường cong bậc hai kiểu Material
duration + easing cubic-BezierCóCólinear, easeIn, easeOut, easeInOut, standard, emphasized
Vật lý spring nativeCóCóCASpringAnimation trên iOS, SpringAnimation trên Android
Chế độ chuyển độ mờ (fadeMode)CóCócross, in, out, through
Nâng cấp ảnh nét khi zoom-inCóCóGiữ ảnh sắc nét khi cả hai đầu bọc một <Image>
Chống cắt chữ khi <Text> xuống dòngCóCóScale mượt hai lớp snapshot thay vì crop mất dấu hoặc chữ
Vuốt cạnh trái trả về (swipe-back)CóN/ATự động đồng bộ tiến độ với interactivePopGestureRecognizer
Đổi hướng ngay giữa không trungCóCóBắt lấy tọa độ thực đang bay nếu người dùng bấm Back ngay lập tức
Hỗ trợ recycle cho FlatList / FlashListCóCóTự dọn dẹp bucket id cũ khi cell được tái sử dụng

Yêu cầu hệ thống ​

  • React Native: 0.76+ bật New Architecture (Fabric), đã kiểm thử tới React Native 0.82.
  • iOS: iOS 14.0+ (tương thích cả liên kết tĩnh lẫn use_frameworks!).
  • Android: minSdkVersion 24+, Kotlin + AndroidX dynamicanimation.
  • Expo: Chạy tốt với Expo Custom Dev Client (npx expo run:ios / npx expo run:android / EAS Build). Không dùng được trong app Expo Go dựng sẵn vì thư viện có mã native riêng.

Phát hành theo giấy phép MIT.