Vue实现转盘轮播

效果图

在这里插入图片描述

设计思想

1.有左中右三个内容块,左右opacity:0
2. 选择向左,则中间块从左移动到中间,右边快从中间移动到右边
3.反向同理
<template>
  <div class="container">
    <div id="left" ref="left">
      <span class="content">     {{ list[showItem.left] }}   </span>
    </div>
    <div id="mid" ref="mid">
      <span class="content">     {{ list[showItem.mid] }}   </span>
    </div>
    <div id="right" ref="right">
      <span class="content">     {{ list[showItem.right] }}   </span>
    </div>
  </div>
</template>
<script setup>
import {getCurrentInstance, onBeforeUnmount, onMounted, reactive} from "vue";

let currentInstance
let CLEAR_CLASS_TIMEOUT
let CLEAR_CLASS_INTERVAL
onMounted(() => {
  currentInstance = getCurrentInstance()
  CLEAR_CLASS_INTERVAL = setInterval(() => {
    let steps = [-1, 1]
    let step = steps[Math.round(Math.random())]
    move(step)
  }, 1000)
})
onBeforeUnmount(() => {
  clearTimeout(CLEAR_CLASS_TIMEOUT)
  clearInterval(CLEAR_CLASS_INTERVAL)
})

const list = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
const showItem = reactive({left: 0, mid: 1, right: 2})

const move = (step) => {
  let keys = Object.keys(showItem)
  keys.forEach(item => showItem[item] += step)

  if (showItem.left < 0 || showItem.mid < 0 || showItem.right < 0)
    keys.forEach(item => showItem[item] += list.length)
  if (showItem.left >= list.length || showItem.mid >= list.length || showItem.right >= list.length)
    keys.forEach(item => showItem[item] %= list.length)

  setClass(step)
}
const setClass = (step) => {
  let leftClass, midClass, rightClass
  if (step > 0) {
    leftClass = 'midToLeft'
    midClass = 'rightToMid'
    rightClass = ''
  } else {
    leftClass = ''
    midClass = 'leftToMid'
    rightClass = 'midToRight'
  }
  currentInstance.refs.left.className = leftClass
  currentInstance.refs.mid.className = midClass
  currentInstance.refs.right.className = rightClass
  CLEAR_CLASS_TIMEOUT = setTimeout(() => {
    currentInstance.refs.left.className = ''
    currentInstance.refs.mid.className = ''
    currentInstance.refs.right.className = ''
  }, 500)
}
</script>
<style scoped lang="scss">
.container {
  width: fit-content;
  margin: auto auto 20px;
  display: flex;
  padding-top: 60px;

  div {
    width: 400px;
    height: 300px;
    background: #747bff;
    border-radius: 10px;
    position: relative;

    .content {
      position: absolute;
      font-size: 22px;
      top: calc(50% - 21px);
      left: calc(50% - 22px);
    }
  }

  #left, #right {
    opacity: 0;
    width: 350px;
  }

  #left {
    transform: translate(-20px, -30px) skewY(10deg);
  }

  #right {
    transform: translate(20px, -30px) skewY(-10deg);
  }
}

$duration: .5s;

.rightToMid {
  animation: rightToMid ease-in-out $duration;
}

.midToLeft {
  animation: midToLeft ease-in-out $duration;
}

.leftToMid {
  animation: leftToMid ease-in-out $duration;
}

.midToRight {
  animation: midToRight ease-in-out $duration;
}

@keyframes rightToMid {
  0% {
    transform: translate(370px, -30px) skewY(-10deg);
    width: 350px;
    opacity: 0;
  }
}

@keyframes midToLeft {
  0% {
    transform: translate(350px, 0) skewY(0);
    width: 400px;
    opacity: 1;
  }
}


@keyframes leftToMid {
  0% {
    transform: translate(-370px, -30px) skewY(10deg);
    width: 350px;
    opacity: 0;
  }
}

@keyframes midToRight {
  0% {
    transform: translate(-350px, 0px) skewY(0deg);
    width: 400px;
    opacity: 1;
  }
}
</style>
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值