说在前面
🎈常见的轮播图组件我们见得很多了,那么来封装个3D轮播图组件怎么样呢?
效果预览
体验地址
http://jyeontu.xyz/jvuewheel/#/J3DSwipe
组件实现
CSS3:transform-style & perspective
首先我们应该先了解一下transform-style
和perspective
这两个CSS3中的属性。
transform-style
transform--style
属性指定嵌套元素是怎样在三维空间中呈现。
值 | 描述 |
flat | 表示所有子元素在2D平面呈现。 |
preserve-3d | 表示所有子元素在3D空间中呈现。 |
- 浏览器支持
perspective
我们可以通过perspective
来设置一个元素的景深,多少像素的3D元素是从视图的perspective
属性定义。这个属性允许你改变3D元素是怎样查看透视图,这个值决定了 3D效果的强烈程度 越小感觉越强烈,也站的越近。
定义时的perspective
属性,它是一个元素的子元素,透视图,而不是元素本身。
注意:perspective
属性只影响 3D 转换元素。
值 | 描述 |
number | 元素距离视图的距离,以像素计。 |
none | 默认值。与 0 相同。不设置透视。 |
- 浏览器支持
组件参数定义及功能实现
props: { maxWidth: { type: String, default: "150px" }, hoverPause: { type: Boolean, default: true }, blurPause: { type: Boolean, default: true }, speed: { type: String, default: "1500" }, multiple: { type: String, default: "1.4" }, autoPlay: { type: Boolean, default: true }, imgList: { type: Array, default: () => { return []; } } },
如上代码,我们在该组件中主要接收这7个参数,接下来我们结合功能实现来对这些参数进行说明。
1、maxWidth(设置轮播图片的最大宽度)
使用CSS变量来动态设置轮播图片的最大宽度,代码如下:
<div :id="uid + '-j-3d-swipe'" class="j-3d-swipe" :style="{ '--maxWidth': maxWidth }" > …… </div> <style lang="scss" vars="{ maxWidth }" scoped> figure.spinner img { max-width: var(--maxWidth); position: absolute; left: 40%; transform-origin: 50% 50% -500px; outline: 1px solid transparent; } </style>
2、hoverPause(鼠标移动到图片上停止轮播)
该参数可以设置鼠标移动到图片上面时,图片是否停止轮播。这里我们可以通过mouseenter
和mouseleave
事件来模拟监听图片的hover事件(mouseover
当然也可以,但是其触发事件次数会较多)
<img alt="" v-for="(item, index) in imgList" :key="'img-' + index" :src="item" :class="uid + '-img img'" @mouseenter="mouseenter" @mouseleave="mouseleave" /> <script> mouseleave(e) { this.mouseHover = false; }, mouseenter(e) { this.mouseHover = true; }, //轮播切换函数 galleryspin(sign) { if (this.hoverPause && this.mouseHover) return; …… } </script>
3、blurPause(窗口失焦时停止自动轮播)
通过该参数我们可以设置当前window窗口失去焦点的时候,轮播图是否停止自动轮播。这里我们通过window.onfocus
和window.onblur
来监听窗口的状态。
created() { window.onfocus = () => { this.isActive = true; }; window.onblur = () => { this.isActive = false; }; }, methods:{ //轮播切换函数 galleryspin(sign) { if (this.blurPause && !this.isActive) return; …… } }
4、speed(设置自动轮播速度)
通过该参数我们可以设置自动轮播切换速度,默认为1500ms。
setInterval(() => { this.galleryspin(); }, this.speed);
5、multiple(设置鼠标移动到图片上,图片放大效果)
通过该参数我们可以设置鼠标移动到轮播图片上时,图片的放大倍数,如下图:
这里我们可以通过mouseenter
和mouseleave
事件来模拟监听图片的hover事件
<img alt="" v-for="(item, index) in imgList" :key="'img-' + index" :src="item" :class="uid + '-img img'" @mouseenter="mouseenter" @mouseleave="mouseleave" /> <script> mouseleave(e) { const el = e.target; const newWidth = parseInt(el.offsetWidth) / this.multiple + "px"; el.style.width = newWidth; el.style.maxWidth = newWidth; this.mouseHover = false; }, mouseenter(e) { const el = e.target; const newWidth = parseInt(el.offsetWidth) * this.multiple + "px"; el.style.width = newWidth; el.style.maxWidth = newWidth; this.mouseHover = true; }, </script>
6、autoPlay(设置是否自动轮播)
通过该参数我们可以设置轮播图是否自动播放。
mounted() { if (this.autoPlay) { setInterval(() => { this.galleryspin(); }, this.speed); } },
7、imgList(轮播图片列表)
7.1 循环生成图片标签
我们可以通过遍历图片列表来生成图片标签。
<img alt="" v-for="(item, index) in imgList" :key="'img-' + index" :src="item" :class="uid + '-img img'" @mouseenter="mouseenter" @mouseleave="mouseleave" />
7.2 初始化图片角度
计算每张图片的初始角度,使其平均分布。
initView() { const imgs = document.getElementsByClassName(`${this.uid}-img`); for (let i = 0; i < imgs.length; i++) { const angle = (360 / imgs.length) * i; imgs[i].setAttribute( "style", `transform: rotateY(-${angle}deg)` ); } },
7.3 图片轮播事件
每次旋转的角度应该为:360 / this.imgList.length
,通过sign
来区分旋转方向,Boolean(sign)
为false时顺时针转动,反之则逆时针转动。
galleryspin(sign) { if (this.blurPause && !this.isActive) return; if (this.hoverPause && this.mouseHover) return; const id = this.uid + "-spinner"; const spinner = document.getElementById(id); if (!sign) { this.angle = this.angle + 360 / this.imgList.length; } else { this.angle = this.angle - 360 / this.imgList.length; } spinner.setAttribute( "style", "-webkit-transform: rotateY(" + this.angle + "deg); -moz-transform: rotateY(" + this.angle + "deg); transform: rotateY(" + this.angle + "deg);" ); }
组件库引用
这里我将这个组件打包进了自己的一个组件库,并将其发布到了npm上,有需要的同学也可以直接引入该组件进行使用。
引入教程可以看这里:http://jyeontu.xyz/jvuewheel/#/installView
引入后即可直接使用。
源码地址
组件库已开源,想要查看完整源码的可以到 gitee 查看,自己也整理了相关的文档对其进行了简单介绍,具体如下:
组件文档
jvuewheel: http://jyeontu.xyz/jvuewheel/#/JVideoCover
Gitee源码
Gitee源码:gitee.com/zheng_yongt…
觉得有帮助的同学可以帮忙给我点个star,感激不尽~~~
有什么想法或者改良可以给我提个pr,十分欢迎~~~
有什么问题都可以在评论告诉我~~~
往期精彩
说在后面
🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。