home-guide.tsx 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import { NButton } from 'naive-ui';
  2. import {
  3. defineComponent,
  4. nextTick,
  5. onMounted,
  6. reactive,
  7. ref,
  8. watch
  9. } from 'vue';
  10. import styles from './index.module.less';
  11. import { getImage } from './images';
  12. import {px2vw} from '@/utils/index'
  13. import { visibility } from 'html2canvas/dist/types/css/property-descriptors/visibility';
  14. export default defineComponent({
  15. name: 'coai-guide',
  16. emits: ['close'],
  17. setup(props, { emit }) {
  18. const data = reactive({
  19. box: {},
  20. show: false,
  21. /**
  22. *
  23. width: px2vw(840),
  24. height: px2vw(295)
  25. */
  26. steps: [
  27. {
  28. ele: '',
  29. eleRect: {} as DOMRect,
  30. img: getImage('home1.png'),
  31. handStyle: {
  32. top: '0.91rem'
  33. },
  34. imgStyle: {
  35. left: px2vw(295),
  36. width: px2vw(840),
  37. height: px2vw(295)
  38. },
  39. btnsStyle: {
  40. top: px2vw(215),
  41. left: px2vw(540),
  42. },
  43. boxStyle:{
  44. border:'none',
  45. width:'0px',
  46. height:'0px',
  47. backgroundColor: 'transparent'
  48. // visibility: 'hidden'
  49. },
  50. eleRectPadding:{
  51. left:7,
  52. top:7,
  53. width:14,
  54. height:14
  55. }
  56. },
  57. {
  58. ele: '',
  59. img: getImage('home2.png'),
  60. imgStyle: {
  61. top: '51Px',
  62. left: '-18em',
  63. width: px2vw(401),
  64. height: px2vw(227)
  65. },
  66. btnsStyle: {
  67. top: px2vw(200),
  68. left: px2vw(-90),
  69. },
  70. boxStyle:{
  71. borderRadius:'25px'
  72. },
  73. eleRectPadding:{
  74. left:7,
  75. top:7,
  76. width:14,
  77. height:14
  78. }
  79. },
  80. {
  81. ele: '',
  82. img: getImage('home3.png'),
  83. handStyle: {
  84. top: '-1.39rem',
  85. left: '0.17rem',
  86. transform: 'rotate(180deg)'
  87. },
  88. imgStyle: {
  89. top:px2vw(575),
  90. width: px2vw(454),
  91. height: px2vw(227),
  92. left:px2vw(282)
  93. },
  94. btnsStyle: {
  95. top:px2vw(730),
  96. left:px2vw(450)
  97. },
  98. eleRectPadding:{
  99. left:44,
  100. top:44,
  101. width:88,
  102. height:88
  103. }
  104. },
  105. {
  106. ele: '',
  107. img: getImage('home4.png'),
  108. handStyle: {
  109. top: '-1.39rem',
  110. left: '1.4rem',
  111. transform: 'rotate(180deg)'
  112. },
  113. imgStyle: {
  114. top: '4rem',
  115. left: px2vw(-310),
  116. width: px2vw(477),
  117. height: px2vw(227),
  118. },
  119. btnsStyle: {
  120. top: '-0.85rem',
  121. left: '-3rem',
  122. 'justify-content': 'center',
  123. padding: 0
  124. },
  125. eleRectPadding:{
  126. left:7,
  127. top:7,
  128. width:14,
  129. height:14
  130. }
  131. }
  132. ],
  133. step: 0
  134. });
  135. const tipShow = ref(false);
  136. const guideInfo = localStorage.getItem('teacher-guideInfo');
  137. if (guideInfo && JSON.parse(guideInfo).coaiGuide) {
  138. tipShow.value = false;
  139. } else {
  140. tipShow.value = true;
  141. }
  142. const getStepELe = () => {
  143. const ele: HTMLElement = document.getElementById(`home-${data.step}`)!;
  144. console.log(`coai-${data.step}`,data.steps[data.step].eleRectPadding);
  145. if (ele) {
  146. const eleRect = ele.getBoundingClientRect();
  147. const left = data.steps[data.step].eleRectPadding?.left || 0;
  148. const top = data.steps[data.step].eleRectPadding?.top || 0;
  149. const width = data.steps[data.step].eleRectPadding?.width || 0;
  150. const height = data.steps[data.step].eleRectPadding?.height || 0
  151. data.box = {
  152. left: eleRect.x - left+ 'px',
  153. top: eleRect.y - top +'px',
  154. width: eleRect.width + width+'px',
  155. height: eleRect.height +height+ 'px'
  156. };
  157. }
  158. };
  159. onMounted(() => {
  160. getStepELe();
  161. });
  162. const handleNext = () => {
  163. if (data.step >= 3) {
  164. endGuide();
  165. return;
  166. }
  167. data.step = data.step + 1;
  168. getStepELe();
  169. };
  170. const endGuide = () => {
  171. let guideInfo =
  172. JSON.parse(localStorage.getItem('teacher-guideInfo')) || null;
  173. if (!guideInfo) {
  174. guideInfo = { homeGuide: true };
  175. } else {
  176. guideInfo.homeGuide = true;
  177. }
  178. localStorage.setItem('teacher-guideInfo', JSON.stringify(guideInfo));
  179. tipShow.value = false;
  180. // localStorage.setItem('endC')
  181. };
  182. return () => (
  183. <>
  184. {tipShow.value ? (
  185. <div
  186. v-model:show={tipShow.value}
  187. class={['n-modal-mask', 'n-modal-mask-guide']}>
  188. <div class={styles.content} onClick={() => handleNext()}>
  189. <div
  190. class={styles.backBtn}
  191. onClick={(e: Event) => {
  192. e.stopPropagation();
  193. endGuide();
  194. }}>
  195. 跳过
  196. </div>
  197. <div
  198. class={styles.box}
  199. style={{...data.box,...data.steps[data.step].boxStyle}}
  200. id={`modeType-${data.step}`}>
  201. {data.steps.map((item: any, index) => (
  202. <div
  203. onClick={(e: Event) => e.stopPropagation()}
  204. class={styles.item}
  205. style={{
  206. display: index === data.step ? '' : 'none',
  207. left: `${item.eleRect?.left}px`,
  208. top: `${item.eleRect?.top}px`
  209. }}>
  210. <img
  211. class={styles.img}
  212. style={item.imgStyle}
  213. src={item.img}
  214. />
  215. {/* <img
  216. class={styles.iconHead}
  217. style={item.handStyle}
  218. src={getImage('indexDot.png')}
  219. /> */}
  220. <div class={styles.btns} style={item.btnsStyle}>
  221. {data.step + 1 == data.steps.length ? (
  222. <>
  223. <div
  224. class={styles.btn}
  225. color="transparent"
  226. style={{ 'border-color': '#fff' }}
  227. onClick={() => {
  228. data.step = 0;
  229. getStepELe();
  230. }}>
  231. 再看一遍
  232. </div>
  233. <div
  234. class={[styles.btn, styles.endBtn]}
  235. onClick={() => endGuide()}>
  236. 完成
  237. </div>
  238. </>
  239. ) : (
  240. <div class={styles.btn} onClick={() => handleNext()}>
  241. 下一步 ({data.step + 1}/{data.steps.length})
  242. </div>
  243. )}
  244. </div>
  245. </div>
  246. ))}
  247. </div>
  248. </div>
  249. </div>
  250. ) : null}
  251. </>
  252. );
  253. }
  254. });