vue3写垂直轮播效果(translateY)

实现思路:卡片移动使用css的translateY属性实现,每个卡片从最下面移动到最上面,然后直接移动到最下面,每次改变的位移是固定的,假设每次移动50px,当移动到最小时,就让translataY为0,但是一定要进行初始化每个div的初始位置;

代码:

<template>
  <div id="demo">
    <div class="box">
      <!-- 左下角预警 -->
      <div
        class="warning"
        :ref="setItemRef"
        :style="{
          transform: `translateY(${-index * 50}px)`,
          transition: 'transform 0.9s ease',
          zIndex: `${-index + 100}`
        }"
        v-for="(item, index) in warningInfoList"
      >
        <div class="warning-title">{{ item.warning_type }}</div>
        <div class="warning-content" :style="{display: index != 0 ?'none':'block'}">
          <div class="warning-time">{{ item.time }}</div>
          <div class="warning-word">{{ item.warning_content }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { reactive, ref, computed, onMounted, onUnmounted, nextTick } from 'vue'

// let warningInfoList = ref([
//   { warning_type: '台风', warning_content: '大风,注意安全', time: '12日-13' },
//   { warning_type: '暴雨', warning_content: '暴雨,注意安全', time: '12日-13' },
//   { warning_type: '冰雹', warning_content: '冰雹,注意安全', time: '12日-13' }
// ])
import {warningInfo} from '@renderer/api/index.ts';
//预警数据
let warningInfoList = ref([])
const getWarningInfo = async () => {
  let response = await warningInfo({})
  warningInfoList.value = response.data.ret.results
  let maxLength = warningInfoList.value.length
  nextTick(() => {
    setInterval(() => {
      warningInfoList.value.forEach((item, index) => {
        let aTransformY = parseInt(itemRefs[index].style.transform.substring(11))
        let bIndex = itemRefs[index].style.zIndex
        
        // console.log("aTransformY",aTransformY);
        if (aTransformY == -((maxLength - 1) * 50)) {
          aTransformY = 0
          itemRefs[index].children[1].style.display = 'block'
        } else {
          aTransformY -= 50
          itemRefs[index].children[1].style.display = 'none'
        }
        if(bIndex == (100 - maxLength+1)){
          bIndex = 100
        }else {
          bIndex -= 1
        }
        itemRefs[index].style.transform = `translateY(${aTransformY}px)`
        itemRefs[index].style.zIndex = bIndex
        // console.log('itemRefs[index]', itemRefs[index].style)
      })
    }, 3000)
  })
}

const itemRefs = []
const setItemRef = (el) => {
  if (el) {
    itemRefs.push(el)
  }
}
// console.log("itemRefs",itemRefs);
onMounted(async () => {
  await getWarningInfo()
  //初始化
  // nextTick(() => {
  //   setInterval(() => {
  //     warningInfoList.value.forEach((item, index) => {
  //       let aTransformY = parseInt(itemRefs[index].style.transform.substring(11))
  //       let bIndex = itemRefs[index].style.zIndex
        
  //       console.log("aTransformY",aTransformY);
  //       // debugger
  //       if (aTransformY == -((maxLength - 1) * 50)) {
  //         aTransformY = 0
  //         itemRefs[index].children[1].style.display = 'block'
  //       } else {
  //         aTransformY -= 50
  //         itemRefs[index].children[1].style.display = 'none'
  //       }
  //       if(bIndex == (100 - maxLength+1)){
  //         bIndex = 100
  //       }else {
  //         bIndex -= 1
  //       }
  //       itemRefs[index].style.transform = `translateY(${aTransformY}px)`
  //       itemRefs[index].style.zIndex = bIndex
  //       // console.log('itemRefs[index]', itemRefs[index].style)
  //     })
  //   }, 3000)
  // })
})
</script>

<style lang="less" scoped>
#demo {
  position: absolute;
  left: 40px;
  bottom: 30px;
  .box {
    width: 301px;
    height: 360px;
    // overflow: scroll;
    position: relative;
    .warning {
      width: 301px;
      height: 280px;
      position: absolute;
      .warning-title {
        height: 40px;
        background-image: url('../assets/img/title_bg.png');
        font-size: 18px;
        font-family:
          PingFang SC,
          PingFang SC-700;
        font-weight: 700;
        color: #ff6838;
        line-height: 40px;
        padding-left: 60px;
      }
      .warning-content {
        height: 240px;
        border-radius: 0px 0px 8px 8px;
        padding-top: 20px;
        box-sizing: border-box;
        background: rgba(255, 245, 209, 0.9);
        > .warning-time {
          height: 30px;
          font-size: 20px;
          font-family:
            PingFang SC,
            PingFang SC-400;
          font-weight: 500;
          color: #009f80;
          line-height: 30px;
          padding-left: 20px;
          box-sizing: border-box;
          position: relative;
          &::before {
            display: block;
            content: '';
            width: 3px;
            height: 3px;
            border-radius: 50%;
            background-color: #009f80;
            position: absolute;
            top: 50%;
            left: 3%;
          }
        }
        .warning-word {
          padding: 20px 30px;
          box-sizing: border-box;
          font-size: 20px;
          font-family:
            PingFang SC,
            PingFang SC-400;
          font-weight: 400;
          color: #313737;
          line-height: 30px;
        }
      }
    }
  }
}
</style>

如何没有接口,可以使用里面的假数据先测试

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值