use-fold-anim-into.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { sleep } from '@/utils'
  2. const animTime = 750
  3. const modalClassName = 'install-modal'
  4. const COUNT_DOWN_TIME = 15000 // 15s
  5. function getElemCenter(elem: HTMLElement) {
  6. const rect = elem.getBoundingClientRect()
  7. return {
  8. x: rect.left + rect.width / 2 + window.scrollX,
  9. y: rect.top + rect.height / 2 + window.scrollY,
  10. }
  11. }
  12. const useFoldAnimInto = (onClose: () => void) => {
  13. let countDownRunId: number
  14. const clearCountDown = () => {
  15. clearTimeout(countDownRunId)
  16. }
  17. // modalElem fold into plugin install task btn
  18. const foldIntoAnim = async () => {
  19. clearCountDown()
  20. const modalElem = document.querySelector(`.${modalClassName}`) as HTMLElement
  21. const pluginTaskTriggerElem = document.getElementById('plugin-task-trigger') || document.querySelector('.plugins-nav-button')
  22. if (!modalElem || !pluginTaskTriggerElem) {
  23. onClose()
  24. return
  25. }
  26. const modelCenter = getElemCenter(modalElem)
  27. const modalElemRect = modalElem.getBoundingClientRect()
  28. const pluginTaskTriggerCenter = getElemCenter(pluginTaskTriggerElem)
  29. const xDiff = pluginTaskTriggerCenter.x - modelCenter.x
  30. const yDiff = pluginTaskTriggerCenter.y - modelCenter.y
  31. const scale = 1 / Math.max(modalElemRect.width, modalElemRect.height)
  32. modalElem.style.transition = `all cubic-bezier(0.4, 0, 0.2, 1) ${animTime}ms`
  33. modalElem.style.transform = `translate(${xDiff}px, ${yDiff}px) scale(${scale})`
  34. await sleep(animTime)
  35. onClose()
  36. }
  37. const countDownFoldIntoAnim = async () => {
  38. countDownRunId = window.setTimeout(() => {
  39. foldIntoAnim()
  40. }, COUNT_DOWN_TIME)
  41. }
  42. return {
  43. modalClassName,
  44. foldIntoAnim,
  45. clearCountDown,
  46. countDownFoldIntoAnim,
  47. }
  48. }
  49. export default useFoldAnimInto