DollPrizeModal.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { Images } from '@/constants/images';
  2. import React, { forwardRef, useImperativeHandle, useState } from 'react';
  3. import { Image, Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
  4. export interface DollPrizeModalRef {
  5. show: (data: any[]) => void;
  6. close: () => void;
  7. }
  8. export const DollPrizeModal = forwardRef<DollPrizeModalRef>((_, ref) => {
  9. const [visible, setVisible] = useState(false);
  10. const [prizeList, setPrizeList] = useState<any[]>([]);
  11. useImperativeHandle(ref, () => ({
  12. show: (data) => {
  13. setPrizeList(data);
  14. setVisible(true);
  15. },
  16. close: () => setVisible(false),
  17. }));
  18. if (!visible) return null;
  19. return (
  20. <Modal visible={visible} transparent animationType="fade" onRequestClose={() => setVisible(false)}>
  21. <View style={styles.overlay}>
  22. <TouchableOpacity style={styles.mask} activeOpacity={1} onPress={() => setVisible(false)} />
  23. <View style={styles.contentContainer}>
  24. <View style={styles.wrapper}>
  25. <Image source={{ uri: Images.welfare.toys.rewardBg }} style={styles.ruleBg} resizeMode="stretch" />
  26. <View style={styles.prizeContainer}>
  27. <ScrollView contentContainerStyle={styles.scrollContent}>
  28. {prizeList.map((item, index) => (
  29. <View key={item.spuId || index} style={[styles.prizeItem, (index + 1) % 3 === 0 && styles.noRightMargin]}>
  30. <View style={styles.prizeImgBox}>
  31. <Image source={{ uri: item.cover }} style={styles.prizeImg} resizeMode="contain" />
  32. </View>
  33. <Text style={styles.prizeText} numberOfLines={1}>{item.name}</Text>
  34. </View>
  35. ))}
  36. </ScrollView>
  37. </View>
  38. </View>
  39. <TouchableOpacity onPress={() => setVisible(false)} style={styles.closeBtn}>
  40. <Image source={{ uri: Images.mine.dialogClose }} style={styles.closeIcon} />
  41. </TouchableOpacity>
  42. </View>
  43. </View>
  44. </Modal>
  45. );
  46. });
  47. const styles = StyleSheet.create({
  48. overlay: {
  49. flex: 1,
  50. backgroundColor: 'rgba(0,0,0,0.6)',
  51. justifyContent: 'center',
  52. alignItems: 'center',
  53. },
  54. mask: {
  55. position: 'absolute',
  56. top: 0,
  57. left: 0,
  58. right: 0,
  59. bottom: 0,
  60. },
  61. contentContainer: {
  62. width: '100%',
  63. alignItems: 'center',
  64. },
  65. wrapper: {
  66. width: 326, // 652rpx
  67. height: 452, // 904rpx
  68. position: 'relative',
  69. alignItems: 'center',
  70. },
  71. ruleBg: {
  72. width: '100%',
  73. height: '100%',
  74. position: 'absolute',
  75. },
  76. prizeContainer: {
  77. position: 'absolute',
  78. top: 78.5, // 157rpx
  79. left: 27, // 54rpx
  80. right: 27, // 54rpx
  81. height: 357.5, // 715rpx
  82. width: 272, // 544rpx
  83. },
  84. scrollContent: {
  85. flexDirection: 'row',
  86. flexWrap: 'wrap',
  87. justifyContent: 'flex-start',
  88. },
  89. prizeItem: {
  90. width: 80, // 160rpx
  91. height: 116.5, // 233rpx
  92. marginRight: 10, // 20rpx
  93. marginTop: 11.5, // 23rpx
  94. alignItems: 'center',
  95. },
  96. noRightMargin: {
  97. marginRight: 0,
  98. },
  99. prizeImgBox: {
  100. width: 80, // 160rpx
  101. height: 100, // 200rpx
  102. justifyContent: 'center',
  103. alignItems: 'center',
  104. },
  105. prizeImg: {
  106. width: '100%',
  107. height: '100%',
  108. },
  109. prizeText: {
  110. color: '#B58100',
  111. marginTop: 6,
  112. textAlign: 'center',
  113. fontSize: 12,
  114. width: '100%',
  115. },
  116. closeBtn: {
  117. marginTop: 15,
  118. },
  119. closeIcon: {
  120. width: 30, // 60rpx
  121. height: 30,
  122. }
  123. });