Vue + AnimeJS实现3d轮播图的详细代码

 更新时间:2024年01月25日 10:51:35   作者:Kakarotto  
轮播图在开发中是经常用到的,3D轮播图是其中最常用的一种,所以在这篇文章中将给大家介绍Vue + AnimeJS实现3d轮播图,文中有详细的代码示例供大家参考,具有一定的参考价值,需要的朋友可以参考下

效果如下:

基础布局

首先需要设置轮播容器中的子元素位于3D容器中,这是需要设置transform-style。transform-style有两个值,flat:设置元素的子元素位于该元素的平面中、preserve-3d:设置元素的子元素位于3D空间中。

与之对应的还需要设置perspective,指与z=0平面的距离     实现3d效果的轮播图主要需要动态修改transform中translateX,rotateY,scale以及每个图片的层级、透明度。

由上图可知,缩放比例、层级、透明度三个属性中间值最大,然后两边的值逐级递减。在X轴上的偏移值是以中间图片为基准向左(逐级递减)、向右偏移(逐级递增)。Y轴上的旋转以中间图片为基准左边顺时针旋转,右边逆时针旋转。

这里轮播图为无限轮播效果,处理方式是在初始化的时候保存上述五个参数,因为怎么循环,固定位置对应的五个参数是相同的,在切换的时候就不需要重新计算。

因为使用的是vite,获取静态文件资源的时候需要使用new URL()方法来实现资源的引用。初始化代码如下:

<div style="display: flex; align-items: center; justify-content: center">
  <el-icon size="30" @click="clickArrow('left')"><ArrowLeft /></el-icon>
  <div class="carousel-wrapper" ref="carouselRef">
    <div
      v-for="(carousel, index) in carouselList"
      :key="carousel.id"
      :data-base-id="carousel.id"
      class="item"
      :style="computedStyle(index)"
    >
      <img :src="carousel.url" />
    </div>
  </div>
  <el-icon size="30" @click="clickArrow('right')"><ArrowRight /></el-icon>
</div>
const carouselList = ref([
  {
    id: 1,
    url: new URL('../../assets/images/1.jpg', import.meta.url).href
  },
  {
    id: 2,
    url: new URL('../../assets/images/2.jpg', import.meta.url).href
  },
  {
    id: 3,
    url: new URL('../../assets/images/3.jpg', import.meta.url).href
  },
  {
    id: 4,
    url: new URL('../../assets/images/4.jpg', import.meta.url).href
  },
  {
    id: 5,
    url: new URL('../../assets/images/5.jpg', import.meta.url).href
  }
])

const carouselRef = ref()
type CarouseInfo = {
  x: number[]
  y: number[]
  z: number[]
  opacity: number[]
}
const carouselInfo = reactive<CarouseInfo>({
  x: [],
  y: [],
  z: [],
  opacity: []
})

const baseParams = {
  x: 150,
  xOffset: -300,
  y: -25,
  yOffset: 50,
  opacity: 0.6,
  opacityOffset: 0.2
}

const computedStyle = (i: number) => {
  const { opacity, opacityOffset, xOffset, yOffset } = baseParams
  let z = 0
  let opacityNum = 0
  let x = i * baseParams.x + xOffset
  let y = i * baseParams.y + yOffset
  const centerIndex = (carouselList.value.length - 1) / 2

  if (i <= centerIndex) {
    z = i * 5
    opacityNum = i * opacityOffset + opacity
  } else {
    const baseIndex = i - centerIndex * (i - centerIndex)
    z = baseIndex * 5
    opacityNum = baseIndex * opacityOffset + opacity
  }
  carouselInfo.x.push(x)
  carouselInfo.y.push(y)
  carouselInfo.z.push(z)
  carouselInfo.opacity.push(opacityNum)
  return {
    transform: `translateX(${x}px) rotateY(${y}deg) scale(${opacityNum})`,
    zIndex: z,
    opacity: opacityNum
  }
}
.carousel-wrapper {
  width: 900px;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  transform-style: preserve-3d;
  overflow: hidden;
  perspective: 1000px;
}
.item {
  position: absolute;
  user-select: none;
}

轮播

在项目初始化时保存了初始化参数,点击左侧按钮时,分别获取保存的五个参数中的第一个,然后放到数组中的末尾,点击右侧按钮时,分别获取五个参数中的最后一个,放到数组中的最前面,代码如下:

const switchPosition = (val: number[], type = 'right') => {
  const target = type === 'right' ? val.shift() : val.pop()
  type === 'right' ? val.push(target!) : val.unshift(target!)
  return val
}

为了更好的处理动画,这里使用animejs处理,根据点击之后的参数,重新遍历dom节点,修改每个dom的偏移值、旋转角度、缩放比例、透明度,因为没有在animejs中找到设置层级的属性,所以这里使用原生设置层级。代码如下:

const clickArrow = (arrowType: string) => {
  const x = switchPosition(carouselInfo.x, arrowType)

  const y = switchPosition(carouselInfo.y, arrowType)
  const z = switchPosition(carouselInfo.z, arrowType)
  const opacity = switchPosition(carouselInfo.opacity, arrowType)

  Array.from(carouselRef.value.children).forEach((item, index) => {
    ;(item as HTMLDivElement).style.zIndex = z[index].toString()
    anime({
      targets: item as HTMLDivElement,
      translateX: x[index],
      rotateY: y[index],
      scale: opacity[index],
      opacity: opacity[index],
      easing: 'linear'
    })
  })
}

 至此,一个能够循环的3D轮播图就完成了。代码示例如下:

https://stackblitz.com/edit/vitejs-vite-1mgsdu?file=src%2Fassets%2Fimages%2F4.jpg

以上就是Vue + AnimeJS实现3d轮播图的详细代码的详细内容,更多关于Vue AnimeJS3d轮播图的资料请关注脚本之家其它相关文章!

相关文章

  • 使用Vue进行数据可视化实践分享

    使用Vue进行数据可视化实践分享

    在当今的数据驱动时代,数据可视化变得越来越重要,它能够帮助我们更直观地理解数据,从而做出更好的决策,在这篇博客中,我们将探索如何使用 Vue 和一些常见的图表库(如 Chart.js)来制作漂亮的数据可视化效果,需要的朋友可以参考下
    2024-10-10
  • vue中返回结果是promise的处理方式

    vue中返回结果是promise的处理方式

    这篇文章主要介绍了vue中返回结果是promise的处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • vue把页面转换成图片导出方式(html2canvas导出不全问题)

    vue把页面转换成图片导出方式(html2canvas导出不全问题)

    这篇文章主要介绍了vue把页面转换成图片导出方式(html2canvas导出不全问题),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • vue+epubjs实现电子书阅读器的基本功能

    vue+epubjs实现电子书阅读器的基本功能

    这篇文章主要为大家详细介绍了如何使用vue+epubjs实现电子书阅读器的基本功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • vue elementUI表格控制显示隐藏对应列的方法

    vue elementUI表格控制显示隐藏对应列的方法

    这篇文章主要为大家详细介绍了vue elementUI表格控制显示隐藏对应列的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • vue 授权获取微信openId操作

    vue 授权获取微信openId操作

    这篇文章主要介绍了vue 授权获取微信openId操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Vue的子组件props如何设置多个校验类型

    Vue的子组件props如何设置多个校验类型

    这篇文章主要介绍了Vue的子组件props如何设置多个校验类型问题。具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 父子组件生命周期及子组件获取数据传值问题剖析

    父子组件生命周期及子组件获取数据传值问题剖析

    这篇文章主要介绍了父子组件生命周期及子组件获取数据问题剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • el-select选择器组件下拉框增加自定义按钮的实现

    el-select选择器组件下拉框增加自定义按钮的实现

    本文主要介绍了el-select选择器组件下拉框增加自定义按钮的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • Vue如何处理Axios多次请求数据显示问题

    Vue如何处理Axios多次请求数据显示问题

    这篇文章主要介绍了Vue如何处理Axios多次请求数据显示问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01

最新评论