index.jsx 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import React, { useEffect, useRef, useState } from 'react';
  2. import { sdk } from '@/utils/map'
  3. import { newMarker, autoPos, autoPoi } from './utils'
  4. import './style.less'
  5. const plugins = ['AMap.Scale', 'AMap.ToolBar', 'AMap.Geolocation', 'AMap.Autocomplete', 'AMap.PlaceSearch']
  6. export default (props) => {
  7. const map = useRef()
  8. const container = useRef()
  9. const inputRef = useRef()
  10. const posMarker = useRef()
  11. const [currentPos, setCurrentPos] = useState([]);
  12. const handleClick = (e) => {
  13. const { lnglat } = e
  14. const pos = [lnglat.getLng(), lnglat.getLat()]
  15. posMarker.current.setMap(map.current);
  16. setCurrentPos(pos)
  17. props.onChange(pos.join(','))
  18. }
  19. useEffect(() => {
  20. // 只加载一次 amap 相关 js
  21. sdk.loadMapModule({ plugins }).then((AMap) => {
  22. const instance = new AMap.Map(container.current, { zoom: 12 })
  23. instance.addControl(new AMap.Scale())
  24. instance.addControl(new AMap.ToolBar())
  25. // 尝试自动定位到当前位置
  26. if (!props.value) {
  27. instance.addControl(autoPos(AMap))
  28. }
  29. // 当前选中点 - 初始的时候没有定位
  30. posMarker.current = newMarker(AMap, {
  31. active: true,
  32. position: props.value ? props.value.split(',') : undefined,
  33. })
  34. if (props.value) {
  35. posMarker.current.setMap(instance);
  36. }
  37. // POI 搜索
  38. autoPoi(instance, AMap, inputRef, { click: handleClick })
  39. instance.on('click', handleClick);
  40. map.current = instance
  41. })
  42. }, [])
  43. useEffect(() => {
  44. if (props.value) {
  45. setCurrentPos(props.value.split(','))
  46. }
  47. }, [props.value])
  48. useEffect(() => {
  49. if (currentPos.length) {
  50. if (posMarker.current) {
  51. posMarker.current.setPosition(currentPos)
  52. }
  53. if (map.current) {
  54. map.current.setCenter(currentPos);
  55. }
  56. if (currentPos.length && map.current) {
  57. posMarker.current.setMap(map.current)
  58. }
  59. }
  60. }, [currentPos])
  61. const boxStyle = {
  62. width: '100%',
  63. height: '400px',
  64. position: 'relative',
  65. ...(props.style || {}),
  66. }
  67. const mapStyle = {
  68. height: '100%',
  69. width: '100%',
  70. margin: 0,
  71. }
  72. const inputStyle = {
  73. width: '200px',
  74. padding: '5px',
  75. position: 'absolute',
  76. zIndex: 9999,
  77. right: '30px',
  78. lineHeight: '1em',
  79. }
  80. const inputSty1 = {
  81. ...inputStyle,
  82. top: '50px',
  83. }
  84. const inputSty2 = {
  85. ...inputStyle,
  86. top: '10px',
  87. background: 'rgba(255, 255, 255, .9)',
  88. border: '1px solid #bbb',
  89. }
  90. return (
  91. <div className={props.className} style={boxStyle}>
  92. <div ref={container} style={mapStyle} id="poi-map-wrapper"></div>
  93. <input placeholder="请输入搜索关键字" ref={inputRef} style={inputSty1} />
  94. <input value={`坐标: ${currentPos.join(',')}`} style={inputSty2} disabled />
  95. </div>
  96. )
  97. }