vue 纯CSS 旋转木马

贝塞尔曲线--6张图片

<template>
  <div class="cenBotDynamic">
   
    <div class="container">
      <div class="box">
        <div
                v-for="(item, index) in parks"
                :key="item.index"
                :class="['circle', `circle${index + 1}`]"
:style="{animationPlayState:isContinue?'running':'paused'}" @mouseenter="mouseEnter" @mouseleave="mouseLeave"
        >
          <!--, `circle${index + 1}`-->
          <div
                  :id="item.id"
                  :class="{ currClass: item.index == indexs }"

          >
            <div class="circleBox">
              {{item.index}}
            </div>

          </div>
        </div>
        <!-- 椭圆线 -->
        <!--<div class="border"></div>-->
      </div>
    </div>
  </div>
</template>

<script>
  
  
export default {
  name: "index",
  
  data() {
    return {
      parks: [
        {
          index: 5,
        },
        {
          index: 4,
        },
        {
          index: 3,
        },
        {
         index: 2,
       },
      {
         index: 1,
       },
       {
         index: 6,
       }
      ],
      indexs: 0,
isContinue: true,
    };
  },
  methods:{
//控制曲线停止/继续
   mouseEnter(){
      this.isContinue = false
    },
    mouseLeave(){
      this.isContinue = true
    }
  },
  mounted() {

  },
  beforeDestroy() {

  }
}
</script>

<style lang="scss" scoped>
</style>
<style scoped>
  .cenBotDynamic {
    width: 100%;
    height: 100%;
  }
  .container {
    position: absolute;
    top: 6vh;
    left: 10vw;
    width: 60vw;
    height: 50vh;
  }
  /* 动画的容器(椭圆) */
  .box {
    width: 100%;
    height: 100%;
    position: relative;
    /* border: 1px solid blue; */
    box-sizing: border-box;
    border-radius: 50%;
  }

  /*  椭圆线 */
  .border {
    position: absolute;
    width: 80vw;
    height: 100%;
    top: 20vh;
    left: 0.3125rem;
    border: 0.0052rem solid #05acc4;
    border-top-color: rgba(5, 172, 196, 0.1);
    border-left-color: rgba(5, 172, 196, 0.4);
    border-right-color: rgba(5, 172, 196, 0.4);
    border-bottom-color: rgba(5, 172, 196, 0.8);
    box-sizing: border-box;
    border-radius: 50%;
    z-index: 0;
  }

  /* 以下是转动的动画 */
  .circle {
    width: 27.34vw;
    height: 32.22vh;
    position: absolute;
    z-index: 999;
    background-image: url("~@/img/projectManagement/main1/box-bg.png");
    background-size: 100% 100%;
  }

  .circle > div {
    width: 100%;
    height: 100%;
    position: relative;
  }
  .currClass {
    cursor: pointer;
  }

  .circle > div > .circleBox {
    position: absolute;
    width: 100%;
    height: 32.22vh;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    font-size: 0.0729rem;
    color: #fff;
  }

  .circle > div > img {
    width: 100%;
    height: 100%;
  }

  .circle1 {
    animation: animX 10s cubic-bezier(0.36, 0, 0.64, 1) -5s infinite alternate,
    animY 10s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate,
    scale 20s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate;
  }

  .circle2 {
    animation: animX 10s cubic-bezier(0.36, 0, 0.64, 1) -8.33s infinite alternate,
    animY 10s cubic-bezier(0.36, 0, 0.64, 1) -3.33s infinite alternate,
    scale 20s cubic-bezier(0.36, 0, 0.64, 1) -3.66s infinite alternate;
  }

  .circle3 {
    animation: animX 10s cubic-bezier(0.36, 0, 0.64, 1) -11.66s infinite alternate,
    animY 10s cubic-bezier(0.36, 0, 0.64, 1) -6.66s infinite alternate,
    scale 20s cubic-bezier(0.36, 0, 0.64, 1) -6.66s infinite alternate;
  }

  .circle4 {
    animation: animX 10s cubic-bezier(0.36, 0, 0.64, 1) -14.99s infinite alternate,
    animY 10s cubic-bezier(0.36, 0, 0.64, 1) -9.99s infinite alternate,
    scale 20s cubic-bezier(0.36, 0, 0.64, 1) -9.99s infinite alternate;
  }

  .circle5 {
    animation: animX 10s cubic-bezier(0.36, 0, 0.64, 1) -18.32s infinite alternate,
    animY 10s cubic-bezier(0.36, 0, 0.64, 1) -13.32s infinite alternate,
    scale 20s cubic-bezier(0.36, 0, 0.64, 1) -13.32s infinite alternate;
  }

  .circle6 {
    animation: animX 10s cubic-bezier(0.36, 0, 0.64, 1) -21.65s infinite alternate,
    animY 10s cubic-bezier(0.36, 0, 0.64, 1) -16.65s infinite alternate,
    scale 20s cubic-bezier(0.36, 0, 0.64, 1) -16.65s infinite alternate;
  }

  @keyframes animX {
    0% {
      left: -2%;
    }

    100% {
      left: 96%;
    }
  }

  @keyframes animY {
    0% {
      top: -2%;
    }

    100% {
      top: 96%;
    }
  }

  @keyframes scale {
    0% {
      transform: scale(0);
      opacity: 0.1;
    }
    25% {
      transform: scale(0.5);
      opacity: 0.5;
    }
    50% {
      transform: scale(1);
      opacity: 1;
    }
    75% {
      transform: scale(0.5);
      opacity: 0.5;
    }
    100% {
      transform: scale(0);
      opacity: 0.1;
    }
  }
</style>

贝塞尔曲线计算方法:

(x轴+y轴时间综合) ÷旋转的div个数 = 每一个div延后出现的时间

本例为:总旋转时间共20秒,X轴10秒,Y轴10秒 每张时间为3.33  第一张animation初始为-5秒 第二张为 -8.33 依次递加

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的 Vue 旋转木马轮播组件代码示例: ```vue <template> <div class="carousel"> <div class="carousel-wrapper" :style="{transform: 'translateX(' + translateX + 'px)'}"> <div class="carousel-item" v-for="(item, index) in items" :key="index"> <img :src="item.image" alt="carousel item"> </div> </div> <div class="carousel-controls"> <button class="carousel-control" @click="prev"> <i class="fas fa-chevron-left"></i> </button> <button class="carousel-control" @click="next"> <i class="fas fa-chevron-right"></i> </button> </div> </div> </template> <script> export default { data() { return { items: [ { image: 'https://via.placeholder.com/400x200?text=Carousel+Item+1' }, { image: 'https://via.placeholder.com/400x200?text=Carousel+Item+2' }, { image: 'https://via.placeholder.com/400x200?text=Carousel+Item+3' } ], currentIndex: 0, translateX: 0 } }, methods: { next() { if (this.currentIndex < this.items.length - 1) { this.currentIndex++ this.translateX -= this.$refs.carouselItem[0].offsetWidth } }, prev() { if (this.currentIndex > 0) { this.currentIndex-- this.translateX += this.$refs.carouselItem[0].offsetWidth } } } } </script> <style> .carousel { position: relative; overflow: hidden; width: 100%; height: 200px; } .carousel-wrapper { display: flex; transition: transform 0.3s ease-in-out; } .carousel-item { flex-shrink: 0; width: 100%; } .carousel-controls { position: absolute; top: 50%; transform: translateY(-50%); width: 100%; display: flex; justify-content: space-between; } .carousel-control { background: none; border: none; outline: none; cursor: pointer; font-size: 2rem; color: #333; } .carousel-control:hover { color: #666; } </style> ``` 在这个示例中,我们首先定义了一个 `carousel` 组件,该组件包含一个图片轮播区域和两个控制按钮。我们使用 `translateX` 属性来控制轮播区域的水平偏移量,并根据当前索引和轮播项的宽度计算出偏移量的值。 `next` 和 `prev` 方法分别用于向前和向后移动轮播项,它们会根据当前索引和轮播项的数量来判断是否可以移动,如果可以,则更新 `currentIndex` 和 `translateX` 值。 最后,我们在样式中使用了 Flexbox 布局来实现轮播项的水平排列,并使用了一些基本样式来美化组件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值