index.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import React, { useCallback, useEffect, useRef, useState } from "react";
  2. import styles from "./index.module.scss";
  3. import classNames from "classnames";
  4. import { envUrl } from "@/utils/env";
  5. import { imgLodingFu, maoData2, mapData1 } from "./data";
  6. import iconImg1 from "@/assets/img/map/icon1.png";
  7. import iconImg1Ac from "@/assets/img/map/icon1Ac.png";
  8. import iconImg2 from "@/assets/img/map/icon2.png";
  9. import iconImg2Ac from "@/assets/img/map/icon2Ac.png";
  10. import MapSon from "./MapSon";
  11. import { useSelector } from "react-redux";
  12. import { RootState } from "@/store";
  13. import { domShowFu } from "@/utils/domShow";
  14. type Props = {
  15. type: number;
  16. sonChaneType: (val: number) => void;
  17. };
  18. function A0Map({ type, sonChaneType }: Props) {
  19. // 进页面显示加载中
  20. useEffect(() => {
  21. domShowFu("#AsyncSpinLoding", true);
  22. }, []);
  23. // 一级地图 图片的加载
  24. const imgLodingArr = useSelector(
  25. (state: RootState) => state.A0layout.imgLodingArr
  26. );
  27. // 控制二级地图的显示
  28. const [mapSon, setMapSon] = useState(0);
  29. // 大图片是否已经加载完
  30. const isImgLodingFu = useCallback(() => {
  31. let flag = false;
  32. if (imgLodingArr.includes(mapSon)) {
  33. domShowFu("#AsyncSpinLoding", false);
  34. flag = true;
  35. }
  36. return flag;
  37. }, [imgLodingArr, mapSon]);
  38. // 开场动画帧的变化
  39. const [moveInd, setMoveInd] = useState(0);
  40. const moveTime = useRef(-1);
  41. const moveYun = useCallback(() => {
  42. if (!isImgLodingFu()) {
  43. clearInterval(moveTime.current);
  44. let num = 0;
  45. moveTime.current = window.setInterval(() => {
  46. setMoveInd(num);
  47. num++;
  48. if (num > 30 || isImgLodingFu()) {
  49. clearInterval(moveTime.current);
  50. }
  51. }, 50);
  52. }
  53. }, [isImgLodingFu]);
  54. useEffect(() => {
  55. moveYun();
  56. return () => {
  57. clearInterval(moveTime.current);
  58. };
  59. }, [moveYun]);
  60. // 鼠标hover
  61. const [isHover, setIsHover] = useState(0);
  62. return (
  63. <div className={styles.A0Map}>
  64. {/* 开场动画帧 */}
  65. <div
  66. className={classNames(
  67. "videoBoxMove",
  68. isImgLodingFu() ? "videoBoxHide" : ""
  69. )}
  70. >
  71. <img src={`${envUrl}/yunMove/yan_${moveInd}.png`} alt="" />
  72. </div>
  73. {/* 一级地图 */}
  74. <div
  75. className={classNames(
  76. "mapMain",
  77. type === 2 ? "mapMain2" : type === 3 ? "mapMain3" : ""
  78. )}
  79. >
  80. {/* 定位大图标 */}
  81. {mapData1.map((v) => (
  82. <div
  83. onMouseEnter={() => setIsHover(v.id)}
  84. onMouseLeave={() => setIsHover(0)}
  85. onClick={() => {
  86. setMapSon(v.id);
  87. sonChaneType(2);
  88. }}
  89. key={v.id}
  90. className="A0iconBox"
  91. style={{ top: v.y, left: v.x, zIndex: v.ind }}
  92. >
  93. <div className="iconNum">{v.id}</div>
  94. <img className="iconImg1" src={iconImg1} alt="" />
  95. <img className="iconImg2" src={iconImg1Ac} alt="" />
  96. {/* 文字标题 */}
  97. <div
  98. className="txtBox"
  99. hidden={
  100. (isHover === 2 && v.id === 1) || (isHover === 1 && v.id === 2)
  101. }
  102. >
  103. <div>{v.name}</div>
  104. </div>
  105. {/* 悬停出来的图片和名称 */}
  106. <div className="hoverShowBox">
  107. <div className="hoverShowBoxM">
  108. <div className="hoverShowBox1">{v.name}</div>
  109. <div className="hoverShowBox2">
  110. <img src={`${envUrl}/map/icon/${v.id}.jpg`} alt="" />
  111. </div>
  112. </div>
  113. </div>
  114. </div>
  115. ))}
  116. {/* 定位小图标 */}
  117. {maoData2.map((v) => (
  118. <div
  119. onClick={() => {
  120. window.open(v.link);
  121. // setMapSon(v.id);
  122. sonChaneType(3);
  123. }}
  124. key={v.id}
  125. className={classNames(
  126. "A0iconSmBox",
  127. v.type === "right" ? "A0iconSmBoxR" : ""
  128. )}
  129. style={{
  130. top: v.y,
  131. left: v.x,
  132. bottom: v.b,
  133. right: v.r,
  134. zIndex: v.ind,
  135. }}
  136. >
  137. <img className="ic2Img1" src={iconImg2} alt="" />
  138. <img className="ic2Img2" src={iconImg2Ac} alt="" />
  139. {/* 文字标题 */}
  140. <div className={classNames("ic2txtBox", `ic2txtBox${v.id}`)}>
  141. {v.name}
  142. </div>
  143. {/* 悬停出来的图片和名称 */}
  144. <div
  145. className={classNames(
  146. "ic2HoverBox",
  147. v.type === "right" ? "ic2HoverBox2" : ""
  148. )}
  149. >
  150. <div className="ic2HoverBoxll">{v.name}</div>
  151. <div className="ic2HoverBoxrr">
  152. <img src={`${envUrl}/map/icon/${v.id}.jpg`} alt="" />
  153. </div>
  154. </div>
  155. </div>
  156. ))}
  157. <div className="mapBac">
  158. <img
  159. onLoad={() => imgLodingFu(0)}
  160. src={`${envUrl}/map/0.jpg`}
  161. alt=""
  162. />
  163. </div>
  164. </div>
  165. {/* 二级地图 */}
  166. {mapSon ? <MapSon sId={mapSon} /> : null}
  167. {/* <div className="yunBox">
  168. <div className="yunSon1"></div>
  169. <div className="yunSon2"></div>
  170. <div className="yunSon3"></div>
  171. </div> */}
  172. {/* 左下角的返回 */}
  173. {mapSon ? (
  174. <div className="sonToBack" onClick={() => setMapSon(0)}>
  175. <img src={`${envUrl}/map/map${mapSon}.png`} alt="" />
  176. </div>
  177. ) : null}
  178. </div>
  179. );
  180. }
  181. const MemoA0Map = React.memo(A0Map);
  182. export default MemoA0Map;