new_modal.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import { View, Text, ScrollView } from '@tarojs/components'
  2. import './new_modal.scss'
  3. import React, { useEffect, useRef, useState } from 'react';
  4. import { ModalType } from '@/utils/types';
  5. import Taro from '@tarojs/taro';
  6. import { rpxToPx, vibrate } from '@/utils/tools';
  7. import { MainColorType } from '@/context/themes/color';
  8. import NewButton, { NewButtonType } from './new_button';
  9. import { IconClose } from '@/components/basic/Icons';
  10. let ModalRN, Animated
  11. if (process.env.TARO_ENV == 'rn') {
  12. ModalRN = require("react-native").Modal
  13. Animated = require("react-native").Animated
  14. }
  15. export default function NewModal(props: {
  16. children: React.ReactNode,
  17. title?: string,
  18. btnTitle?: string,
  19. dismiss: Function,
  20. confirm?: Function,
  21. themeColor?: string,
  22. cancelCatchMove?: boolean,
  23. themeIsWhite?: boolean
  24. }) {
  25. const [isDismiss, setIsDismiss] = useState(false)
  26. let animation, animatedStyle;
  27. if (process.env.TARO_ENV == 'rn') {
  28. animation = useRef(new Animated.Value(0)).current;
  29. animatedStyle = {
  30. transform: [
  31. {
  32. translateY: animation.interpolate({
  33. inputRange: [0, 1],
  34. outputRange: [300, 0],
  35. }),
  36. },
  37. ],
  38. };
  39. }
  40. useEffect(() => {
  41. if (process.env.TARO_ENV == 'rn') {
  42. startAnimation()
  43. }
  44. }, [])
  45. const startAnimation = () => {
  46. Animated.spring(animation, {
  47. toValue: 1,
  48. duration: 50,
  49. useNativeDriver: true,
  50. }).start();
  51. };
  52. const endAnimation = () => {
  53. Animated.spring(animation, {
  54. toValue: 0,
  55. duration: 50,
  56. useNativeDriver: true,
  57. }).start();
  58. console.log('end')
  59. };
  60. //阻止中间内容点击事件穿透
  61. function click(e) {
  62. if (process.env.TARO_ENV == 'weapp') {
  63. e.stopPropagation()
  64. }
  65. vibrate()
  66. }
  67. function onClick() {
  68. }
  69. function longPress(e) {
  70. if (process.env.TARO_ENV == 'weapp') {
  71. e.stopPropagation()
  72. }
  73. }
  74. function dismiss() {
  75. setIsDismiss(true)
  76. setTimeout(() => {
  77. props.dismiss()
  78. }, 250)
  79. }
  80. function rndismiss() {
  81. endAnimation()
  82. setTimeout(() => {
  83. props.dismiss()
  84. }, 250)
  85. }
  86. global.dismissModal = dismiss;
  87. if (process.env.TARO_ENV == 'rn') {
  88. return <ModalRN transparent
  89. // animationType="slide"
  90. // style={{backgroundColor:'red'}}
  91. >
  92. <View style={{ flex: 1, backgroundColor: props.themeIsWhite ? '#00000080' : '#00000080' }}>
  93. <View style={{ flex: 1, backgroundColor: 'transparent' }} onClick={(e) => {
  94. rndismiss()
  95. }}></View>
  96. <Animated.View className={isDismiss ? 'modal_bottom_content modal_bottom_dismiss' : 'modal_bottom_content'}
  97. style={[{ flexShrink: 0 }, animatedStyle]} onClick={onClick}>
  98. {
  99. props.children
  100. }
  101. </Animated.View>
  102. </View>
  103. </ModalRN>
  104. }
  105. return <View className={isDismiss ? 'modal modal_dismiss' : 'modal'} catchMove onLongPress={longPress}>
  106. <View style={{ flex: 1, width: 375, flexShrink: 0 }} onClick={(e) => {
  107. if (process.env.TARO_ENV == 'weapp') {
  108. e.stopPropagation()
  109. }; dismiss()
  110. }}>
  111. </View>
  112. <View className={isDismiss ? 'modal_bottom_content modal_bottom_dismiss' : 'modal_bottom_content'} style={{ flexShrink: 0,position:'relative' }} onClick={onClick}>
  113. <View className='modal_title'>{props.title}
  114. <View style={{
  115. display:'flex',
  116. width: rpxToPx(60),
  117. height: rpxToPx(60),
  118. alignItems:'center',
  119. justifyContent:'center',
  120. position:'absolute',
  121. right:rpxToPx(24),
  122. top:rpxToPx(24)
  123. }}>
  124. <NewButton
  125. onClick={dismiss}
  126. type={NewButtonType.img}>
  127. <IconClose color={MainColorType.g03} width={rpxToPx(40)} height={rpxToPx(40)} />
  128. </NewButton>
  129. </View>
  130. </View>
  131. {
  132. props.children
  133. }
  134. <View className='modal_footer'>
  135. <View className='modal_footer_btn'
  136. onClick={() => {
  137. props.confirm && props.confirm()
  138. }}
  139. style={{ backgroundColor: props.themeColor ?? MainColorType.fast }}>{props.btnTitle ?? '确定'}</View>
  140. </View>
  141. </View>
  142. </View>
  143. }