<template>
  <div class="home" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseup="onMouseUp" @mouseleave="onMouseLeave"
    @touchstart.passive="onTouchStart" @touchmove.prevent="onTouchMove" @touchend="onTouchEnd"
    @touchcancel="onTouchCancel" @wheel.passive="onWheel">

    <div ref="hcon$" class="h-con" :style="{
      left: `-${translateLength}px`,
    }">
      <div class="h-left">
        <img draggable="false" :src="$getImageUrl('h-left.jpg')" alt="">
        <div class="l-con">
          <img draggable="false" class="title" :src="$getImageUrl('title.png')" alt="">
        </div>
      </div>

      <div class="h-right">
        <ul>
          <li v-for="(item, idx) in list" :key="item.id">
            <img @click="onClickItem(item)" draggable="false" class="title" :src="$getImageUrl(`home-img/${idx + 1}.png`)"
              alt="">
          </li>
        </ul>
      </div>
      <img @click="isShowCR = true" draggable="false" class="menu" :src="$getImageUrl('menu.png')" alt="">

    </div>

    <teleport to='body'>
      <Transition>
        <CulturalRelic @close="isShowCR = ''" v-if="isShowCR" />
      </Transition>

      <Transition>
        <TwoDetail :data="current" @close="current = ''" v-if="current && current.isTwo" />
      </Transition>
        
      <Transition>
        <ThreeDetail :data="current" @close="current = ''" v-if="current  && !current.isTwo" />
      </Transition>


    </teleport>
  </div>
</template>

<script setup>
import { onBeforeUnmount, onMounted, ref } from "vue"

import TwoDetail from "@/components/detail/TwoDetail.vue";
import ThreeDetail from "@/components/detail/ThreeDetail.vue";

import CulturalRelic from "@/views/cultural-relic.vue"
import { two, three } from "@/data/category";


let list = three.data.concat(two.data.map(item => {
  return { ...item, isTwo: true }
}))

console.log('result:', list);

const isMouseDown = ref(false);
const lastMoveEventTimeStamp = ref(0);
const moveSpeed = ref(0);
const lastTouchPos = ref(0);
const maxTranslateLength = ref(0);

// 动画帧相关
const lastAnimationTimeStamp = ref(0);
const animationFrameId = ref(0);

const isShowCR = ref('');
const current = ref('')

const isMove = ref(false)



// 镜头平移相关
const translateLength = ref(0);


const hcon$ = ref(null)

const onClickItem = (item) => {
  if (!isMove.value) {
    current.value = item
  }
}

const animationFrameTask = () => {
  const timeStamp = Date.now()
  const timeElapsed = timeStamp - lastAnimationTimeStamp.value

  // 速度减慢
  if (moveSpeed.value > 0) {
    moveSpeed.value -= 0.003 * timeElapsed
    if (moveSpeed.value < 0) {
      moveSpeed.value = 0
    }
  } else if (moveSpeed.value < 0) {
    moveSpeed.value += 0.003 * timeElapsed
    if (moveSpeed.value > 0) {
      moveSpeed.value = 0
    }
  }

  // 根据速度更新距离
  translateLength.value += moveSpeed.value * timeElapsed
  if (translateLength.value < 0) {
    translateLength.value = 0
  } else if (translateLength.value > maxTranslateLength.value) {
    translateLength.value = maxTranslateLength.value
    moveSpeed.value = 0
  }

  lastAnimationTimeStamp.value = timeStamp
  animationFrameId.value = requestAnimationFrame(animationFrameTask)
}

const calcTranslateLimit = () => {
  maxTranslateLength.value = hcon$.value.clientWidth - window.innerWidth
}

const onMouseDown = () => {
  isMouseDown.value = true
  moveSpeed.value = 0
  lastMoveEventTimeStamp.value = 0
  lastAnimationTimeStamp.value = Date.now()
}


const onMouseMove = (e) => {
  if (isMouseDown.value) {
    // 有些pc端浏览器比如firefox会有两次事件时间戳相同的情况发生。
    if (lastMoveEventTimeStamp.value && (e.timeStamp - lastMoveEventTimeStamp.value > 1)) {
      isMove.value = true
      // 更新speed
      const currentMoveSpeed = - e.movementX / (e.timeStamp - lastMoveEventTimeStamp.value)
      moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1
    }
    lastMoveEventTimeStamp.value = e.timeStamp
  }
}

const onMouseUp = () => {
  isMouseDown.value = false
  setTimeout(() => {
    isMove.value = false
  });
}

const onMouseLeave = () => {
  isMouseDown.value = false
  setTimeout(() => {
    isMove.value = false
  });
}

const onTouchStart = (e) => {
  isMouseDown.value = true
  moveSpeed.value = 0
  lastMoveEventTimeStamp.value = 0
  lastAnimationTimeStamp.value = Date.now()
  lastTouchPos.value = e.changedTouches[0].clientX
}


const onTouchMove = (e) => {
  if (isMouseDown.value && e.changedTouches.length === 1) {
    // 疯狂操作的极端情况下两个时间戳之间的时差会不合理，甚至为0
    if (lastMoveEventTimeStamp.value && (e.timeStamp - lastMoveEventTimeStamp.value > 1)) {
      // 更新speed
      isMove.value = true
      const currentMoveSpeed = - (e.changedTouches[0].clientX - lastTouchPos.value) / (e.timeStamp - lastMoveEventTimeStamp.value) * 1.5
      moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1
      lastTouchPos.value = e.changedTouches[0].clientX
    }
    lastMoveEventTimeStamp.value = e.timeStamp
  }
}


const onTouchEnd = () => {
  isMouseDown.value = false
  setTimeout(() => {
    isMove.value = false
  });
}


const onTouchCancel = () => {
  isMouseDown.value = false
  setTimeout(() => {
    isMove.value = false
  });
}


const onWheel = (e) => {
  translateLength.value += e.deltaY
  if (translateLength.value < 0) {
    translateLength.value = 0
  } else if (translateLength.value > maxTranslateLength.value) {
    translateLength.value = maxTranslateLength.value
    moveSpeed.value = 0
  }
}



onMounted(() => {
  animationFrameId.value = requestAnimationFrame(animationFrameTask)
  window.addEventListener('resize', calcTranslateLimit)
  calcTranslateLimit()
  document.onreadystatechange = () => {
    if (document.readyState === 'complete') {
      // 页面上所有资源加载完成后执行的逻辑
      console.log('所有资源加载完成');
      calcTranslateLimit()
    }
  };
})

onBeforeUnmount(() => {
  document.onreadystatechange = null
  window.removeEventListener('resize', calcTranslateLimit)
})




</script>

<style lang="less" scoped>
.home {
  // background-image: url('@/assets/images/bg-top.png');
  height: 100%;
  width: 100%;

  .h-con {
    height: 100%;
    display: flex;
    width: max-content;
    position: relative;

    .h-left {
      height: 100%;
      position: relative;
      width: max-content;

      >img {
        height: 100%;
      }

      .l-con {

        .logo {
          position: absolute;
          left: 1rem;
          top: 1rem;
          width: 16%;
        }

        .title {
          position: absolute;
          left: 50%;
          top: 50%;
          width: 70%;
          transform: translate(-50%, -50%);
        }
      }
    }

    .h-right {
      background-image: url('@/assets/images/bg-top.jpg');
      background-repeat: no-repeat;
      background-size: auto 80%;
      background-color: #dddad1;
      background-position: 0 0;
      height: 100%;
      position: relative;
      font-size: 0;
      user-select: none;

      &::after {
        width: 100%;
        position: absolute;
        bottom: 0;
        content: '';
        display: inline-block;
        height: 20%;
        box-sizing: border-box;
        border-top: 2rem solid #8B8980;
        background-image: linear-gradient(180deg, #93918A 0%, #AAA89F 63%);
      }

      >ul {
        height: 100%;
        position: relative;
        z-index: 999;
        display: flex;
        align-items: flex-end;
        padding-left: 10rem;
        margin-bottom: 10rem;

        >li {
          list-style: none;
          margin: 0 6rem;

          >img {
            max-width: 80%;
            cursor: pointer;
          }
        }
      }
    }
  }
}

.menu{
  position: fixed;
  right: 2rem;
  top: 2rem;
  width: 3%;
  cursor: pointer;
  z-index: 999;
}
</style>
