Cluster.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /**
  2. * 地图聚合组件
  3. * @邠心vbe on 2021/08/13
  4. */
  5. import React, { useState } from 'react';
  6. import { Image, ImageBackground, StyleSheet, Text } from 'react-native';
  7. import { Marker } from 'react-native-maps';
  8. export const MyMarker = ({id, coordinate, onPress}) => {
  9. const [tracksViewChanges, setTracksViewChanges] = useState(true);
  10. const onImageLoad = () => {
  11. // 图片加载完成后关闭 tracksViewChanges 以提升性能
  12. setTimeout(() => setTracksViewChanges(false), 100);
  13. };
  14. if (coordinate.upcoming) {
  15. return (
  16. <Marker
  17. key={id}
  18. zIndex={20}
  19. coordinate={coordinate}
  20. tracksViewChanges={tracksViewChanges}
  21. onPress={onPress}>
  22. <Image
  23. style={styles.marker}
  24. onLoad={onImageLoad}
  25. source={require('../../../images/maps/ic_marker_upcoming.png')}/>
  26. </Marker>
  27. )
  28. } else {
  29. return (
  30. <Marker
  31. key={id}
  32. zIndex={20}
  33. coordinate={coordinate}
  34. tracksViewChanges={tracksViewChanges}
  35. onPress={onPress}
  36. style={ui.center}>
  37. { coordinate.hasLabel &&
  38. <Image
  39. style={styles.markerTop}
  40. source={require('../../../images/maps/ic_marker_additional.png')}/>
  41. }
  42. { coordinate.favorite
  43. ? coordinate.available
  44. ? <Image
  45. style={styles.marker}
  46. onLoad={onImageLoad}
  47. source={require('../../../images/maps/ic_marker_star.png')}/>
  48. : <Image
  49. style={styles.marker}
  50. onLoad={onImageLoad}
  51. source={require('../../../images/maps/ic_marker_unstar.png')}/>
  52. : coordinate.available
  53. ? <Image
  54. style={styles.marker}
  55. onLoad={onImageLoad}
  56. source={require('../../../images/maps/ic_marker.png')}/>
  57. : <Image
  58. style={styles.marker}
  59. onLoad={onImageLoad}
  60. source={require('../../../images/maps/ic_marker_un.png')}/>
  61. }
  62. </Marker>
  63. )
  64. }
  65. }
  66. export const MyCluster = (props) => {
  67. const {id, location, properties, onPress, available=false, onOpen} = props;
  68. const pointCount = props.pointCount ? props.pointCount : properties.point_count
  69. const [tracksViewChanges, setTracksViewChanges] = useState(true);
  70. //console.log('renderCluster', props);
  71. return (
  72. <Marker
  73. key={id}
  74. coordinate={location}
  75. zIndex={20}
  76. tracksViewChanges={tracksViewChanges}
  77. onPress={() => onOpen ? onOpen(location, id) : onPress()}>
  78. <ClusterView
  79. pointCount={pointCount}
  80. available={available}
  81. onLoad={() => setTimeout(() => setTracksViewChanges(false), 100)}
  82. />
  83. </Marker>
  84. );
  85. }
  86. export const ClusterView = ({pointCount, available=false, onLoad}) => {
  87. const getStyle = (count) => {
  88. if (count >= 100) {
  89. return [ui.flexcc, styles.large];
  90. } else if (count >= 10) {
  91. return [ui.flexcc, styles.middle];
  92. } else {
  93. return [ui.flexcc, styles.small];
  94. }
  95. }
  96. return (
  97. <ImageBackground
  98. style={getStyle(pointCount)}
  99. onLoad={onLoad}
  100. source={available
  101. ? require('../../../images/maps/ic_cluster.png')
  102. : require('../../../images/maps/ic_cluster_un.png')}>
  103. <Text style={available ? styles.textAvailable : styles.textUnavailable}>{pointCount}</Text>
  104. </ImageBackground>
  105. );
  106. }
  107. const styles = StyleSheet.create({
  108. marker: {
  109. width: 48,
  110. height: 48
  111. },
  112. markerTop: {
  113. width: 24,
  114. height: 24,
  115. marginBottom: -2
  116. },
  117. small: {
  118. width: 48,
  119. height: 48
  120. },
  121. middle: {
  122. width: 50,
  123. height: 50
  124. },
  125. large: {
  126. width: 52,
  127. height: 52
  128. },
  129. textAvailable: {
  130. color: textLight,
  131. fontSize: 18,
  132. fontWeight: 'bold',
  133. paddingBottom: 10
  134. },
  135. textUnavailable: {
  136. color: '#999',
  137. fontSize: 18,
  138. fontWeight: 'bold',
  139. paddingBottom: 10
  140. }
  141. })