首先npm install vue-tantan-stack --save 安装

vue-tantan-stack地址

将包下载到本地,然后把文件放到项目中
在文件中引入组件

stack(:pages='surprise.imgs',:stackinit='stackinit',@isloading='switchLoading',:isShowStack='isShowStack')
stackinit: {visible: 3, //控制显示数量}
<template lang="pug">
ul.stack(ref='stackWrap')li.stack-item(v-for='(item, index) in pages',v-if='isShowStack',:style='[transformIndex(index), transform(index), { width: pageWidth }]',@touchmove.stop.capture.prevent='touchmove',@touchstart.stop.capture.prevent='touchstart',@touchend.stop.capture.prevent='touchend',@touchcancel.stop.capture.prevent='touchend',@mousedown.stop.capture.prevent='touchstart',@mouseup.stop.capture.prevent='touchend',@mousemove.stop.capture.prevent='touchmove',@mouseout.stop.capture.prevent='touchend',@webkit-transition-end='onTransitionEnd(index)',@transitionend='onTransitionEnd(index)')img(:src='$getFixImg("basic", item)')
</template>
<script>
import detectPrefixes from './detect-prefixes.js';
export default {props: {stackinit: {type: Object,default: [],},pages: {type: Array,default: {},},isShowStack: { //控制ref渲染完type: Boolean,default: false,},},created() {if (document.body.clientWidth >= 750) {this.pageWidth = '8.12rem';this.isPc = true;} else {this.pageWidth = '4.06rem';this.isPc = false;}this.$nextTick(() => {this.$emit('isloading');});},mounted() {},data() {return {pageWidth: '100%',isPc: false,basicdata: {start: {},end: {},},temporaryData: {prefixes: detectPrefixes(),offsetY: '',poswidth: 0,posheight: 0,lastPosWidth: '',lastPosHeight: '',lastZindex: '',rotate: 0,lastRotate: 0,visible: this.stackinit.visible || 3,tracking: false,animation: false,currentPage: this.stackinit.currentPage || 0,opacity: 1,lastOpacity: 0,swipe: false,zIndex: 10,},};},computed: {// 划出面积比例offsetRatio() {let width = this.$refs.stackWrap.offsetWidth;let height = this.$refs.stackWrap.offsetHeight;let offsetWidth = width - Math.abs(this.temporaryData.poswidth);let offsetHeight = height - Math.abs(this.temporaryData.posheight);let ratio = 1 - (offsetWidth * offsetHeight) / (width * height) || 0;return ratio > 1 ? 1 : ratio;},// 划出宽度比例offsetWidthRatio() {let width = this.$refs.stackWrap.offsetWidth;let offsetWidth = width - Math.abs(this.temporaryData.poswidth);let ratio = 1 - offsetWidth / width || 0;return ratio;},},mounted() {// 绑定事件// this.$on('next', () => {//    this.next();// });// this.$on('prev', () => {//   this.prev();// });// document.addEventListener('touchmove', (e) => {//    e.preventDefault();// });},methods: {touchstart(e) {if (this.temporaryData.tracking) {return;}// 是否为touchif (e.type === 'touchstart') {if (e.touches.length > 1) {this.temporaryData.tracking = false;return;} else {// 记录起始位置this.basicdata.start.t = new Date().getTime();this.basicdata.start.x = e.targetTouches[0].clientX;this.basicdata.start.y = e.targetTouches[0].clientY;this.basicdata.end.x = e.targetTouches[0].clientX;this.basicdata.end.y = e.targetTouches[0].clientY;// offsetY在touch事件中没有,只能自己计算this.temporaryData.offsetY =e.targetTouches[0].pageY - this.$refs.stackWrap.offsetParent.offsetTop;}// pc操作} else {this.basicdata.start.t = new Date().getTime();this.basicdata.start.x = e.clientX;this.basicdata.start.y = e.clientY;this.basicdata.end.x = e.clientX;this.basicdata.end.y = e.clientY;this.temporaryData.offsetY = e.offsetY;}this.temporaryData.tracking = true;this.temporaryData.animation = false;},touchmove(e) {// 记录滑动位置if (this.temporaryData.tracking && !this.temporaryData.animation) {if (e.type === 'touchmove') {e.preventDefault();this.basicdata.end.x = e.targetTouches[0].clientX;this.basicdata.end.y = e.targetTouches[0].clientY;} else {e.preventDefault();this.basicdata.end.x = e.clientX;this.basicdata.end.y = e.clientY;}// 计算滑动值this.temporaryData.poswidth = this.basicdata.end.x - this.basicdata.start.x;this.temporaryData.posheight = this.basicdata.end.y - this.basicdata.start.y;let rotateDirection = this.rotateDirection();let angleRatio = this.angleRatio();this.temporaryData.rotate =rotateDirection * this.offsetWidthRatio * 15 * angleRatio;}},touchend(e) {this.temporaryData.tracking = false;this.temporaryData.animation = true;// 滑动结束,触发判断// 判断划出面积是否大于0.4if (this.offsetRatio >= 0.4) {// 计算划出后最终位置let ratio = Math.abs(this.temporaryData.posheight / this.temporaryData.poswidth);this.temporaryData.poswidth =this.temporaryData.poswidth >= 0? this.temporaryData.poswidth + 200: this.temporaryData.poswidth - 200;this.temporaryData.posheight =this.temporaryData.posheight >= 0? Math.abs(this.temporaryData.poswidth * ratio): -Math.abs(this.temporaryData.poswidth * ratio);this.temporaryData.opacity = 0;this.temporaryData.swipe = true;this.nextTick();// 不满足条件则滑入} else {this.temporaryData.poswidth = 0;this.temporaryData.posheight = 0;this.temporaryData.swipe = false;this.temporaryData.rotate = 0;}},nextTick() {// 记录最终滑动距离this.temporaryData.lastPosWidth = this.temporaryData.poswidth;this.temporaryData.lastPosHeight = this.temporaryData.posheight;this.temporaryData.lastRotate = this.temporaryData.rotate;this.temporaryData.lastZindex = 20;// 循环currentPagethis.temporaryData.currentPage =this.temporaryData.currentPage === this.pages.length - 1? 0: this.temporaryData.currentPage + 1;// currentPage切换,整体dom进行变化,把第一层滑动置最低this.$nextTick(() => {this.temporaryData.poswidth = 0;this.temporaryData.posheight = 0;this.temporaryData.opacity = 1;this.temporaryData.rotate = 0;});},onTransitionEnd(index) {let lastPage =this.temporaryData.currentPage === 0? this.pages.length - 1: this.temporaryData.currentPage - 1;// dom发生变化正在执行的动画滑动序列已经变为上一层if (this.temporaryData.swipe && index === lastPage) {this.temporaryData.animation = true;this.temporaryData.lastPosWidth = 0;this.temporaryData.lastPosHeight = 0;this.temporaryData.lastOpacity = 0;this.temporaryData.lastRotate = 0;this.temporaryData.swipe = false;this.temporaryData.lastZindex = -1;}},prev() {this.temporaryData.tracking = false;this.temporaryData.animation = true;// 计算划出后最终位置let width = this.$refs.stackWrap.offsetWidth;this.temporaryData.poswidth = -width;this.temporaryData.posheight = 0;this.temporaryData.opacity = 0;this.temporaryData.rotate = '-3';this.temporaryData.swipe = true;this.nextTick();},next() {this.temporaryData.tracking = false;this.temporaryData.animation = true;// 计算划出后最终位置let width = this.$refs.stackWrap.offsetWidth;this.temporaryData.poswidth = width;this.temporaryData.posheight = 0;this.temporaryData.opacity = 0;this.temporaryData.rotate = '3';this.temporaryData.swipe = true;this.nextTick();},rotateDirection() {if (this.temporaryData.poswidth <= 0) {return -1;} else {return 1;}},angleRatio() {let height = this.$refs.stackWrap.offsetHeight;let offsetY = this.temporaryData.offsetY;let ratio = -1 * ((2 * offsetY) / height - 1);return ratio || 0;},inStack(index, currentPage) {let stack = [];let visible = this.temporaryData.visible;let length = this.pages.length;for (let i = 0; i < visible; i++) {if (currentPage + i < length) {stack.push(currentPage + i);} else {stack.push(currentPage + i - length);}}return stack.indexOf(index) >= 0;},// 非首页样式切换transform(index) {let currentPage = this.temporaryData.currentPage;let length = this.pages.length;let lastPage = currentPage === 0 ? this.pages.length - 1 : currentPage - 1;let style = {};let visible = this.temporaryData.visible;if (index === this.temporaryData.currentPage) {return;}if (this.inStack(index, currentPage)) {let perIndex =index - currentPage > 0 ? index - currentPage : index - currentPage + length;style['opacity'] = '1';style['transform'] ='translate3D(' +1 * (this.isPc ? 90 : 50) * (perIndex - this.offsetRatio) +'px' +',0,0) scale(' +(perIndex - this.offsetRatio == 1 ? '0.9' : '0.83') +')';style['transformOrigin'] = 'bottom';style['zIndex'] = visible - perIndex;if (!this.temporaryData.tracking) {style[this.temporaryData.prefixes.transition + 'TimingFunction'] = 'ease';style[this.temporaryData.prefixes.transition + 'Duration'] = 300 + 'ms';}} else if (index === lastPage) {style['transform'] ='translate3D(' +this.temporaryData.lastPosWidth +'px' +',' +this.temporaryData.lastPosHeight +'px' +',0px) ' +'rotate(' +this.temporaryData.lastRotate +'deg)';style['opacity'] = this.temporaryData.lastOpacity;style['zIndex'] = this.temporaryData.lastZindex;style[this.temporaryData.prefixes.transition + 'TimingFunction'] = 'ease';style[this.temporaryData.prefixes.transition + 'Duration'] = 0 + 'ms';} else {style['zIndex'] = '-1';style['transform'] = 'translate3D(0,0,' + -1 * visible * 60 + 'px' + ')';}return style;},// 首页样式切换transformIndex(index) {if (index === this.temporaryData.currentPage) {let style = {};style['transform'] ='translate3D(' +this.temporaryData.poswidth +'px' +',' +this.temporaryData.posheight +'px' +',0px) ' +'rotate(' +this.temporaryData.rotate +'deg)';style['opacity'] = this.temporaryData.opacity;style['zIndex'] = 10;if (this.temporaryData.animation) {style[this.temporaryData.prefixes.transition + 'TimingFunction'] = 'ease';style[this.temporaryData.prefixes.transition + 'Duration'] =(this.temporaryData.animation ? 300 : 0) + 'ms';}return style;}},},
};
</script>
<style>
.stack {width: 100%;height: 100%;position: relative;perspective: 1000px;perspective-origin: 50% 150%;-webkit-perspective: 1000px;-webkit-perspective-origin: 50% 150%;margin: 0;padding: 0;
}
.stack-item {background: #fff;height: 100%;width: 100%;border-radius: 0.28rem;text-align: center;overflow: hidden;position: absolute;opacity: 0;display: -webkit-flex;display: flex;-webkit-flex-direction: column;flex-direction: column;-webkit-touch-callout: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;pointer-events: auto;
}
.stack-item img {width: 100%;height: 100%;display: block;pointer-events: none;
}
.stack-container li.move-back {/* http://matthewlein.com/ceaser/ */-webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.47, 1); /* older webkit */-webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.47, 1.515);transition-timing-function: cubic-bezier(0.175, 0.885, 0.47, 1.515);
}
</style>

isShowStack 控制模块渲染完毕再展示轮播图,要不然会出现$refs.xxx.offsetWidth 为undefined
然后就完事了,样式可自行调整

Vue层叠轮播图tantan-stack相关推荐

  1. 【uniapp】3d轮播图/堆叠轮播图/层叠轮播图

    前言 uniapp 3d轮播图 uniapp实现3D轮播图 从uniapp插件市场下载插件:https://ext.dcloud.net.cn/plugin?id=243#detail 操作步骤 导入 ...

  2. php 走马灯轮播,Vue.js轮播图走马灯代码实例(全)

    这个是html, 数据中我用了一个数组来放图片的目录, data() { return { superurl: [ { url: '', img: '../../../../static/image/ ...

  3. 微信小程序之实现层叠轮播图的效果案例(前端学习收藏夹必备)

    效果展示 代码展示: WXML代码 <view class="selection_cards" bindtouchstart="touchstart" b ...

  4. 小程序轮播图_微信小程序层叠轮播图

    效果展示 Demo代码 wxml <view class="selection_cards" bindtouchstart="touchstart" bi ...

  5. 轮播图实现方法一——层叠轮播图

    轮播图的实现方法有很多种,在此主要介绍一种层叠轮播图的实现方式 主要原理:将所有轮播图照片放在同一层,相互覆盖,通过JS控制当前那一张活跃在最顶端,实现图片轮播. 具体实现如下: HTML部分 < ...

  6. vue实现轮播图代码

    这是一段简单的 Vue 实现轮播图的代码: <template><div><div class="carousel"><transitio ...

  7. jQuery制作漂亮的层叠轮播图

    使用jQuery,HTML5,CSS3制作一个中间顶层最大,两端逐渐变淡.变小的轮播图 先上效果图 实现原理   只需要计算出几个参数,那么各个盒子的大小.位置.透明度这些就都能解决了   1. 整个 ...

  8. 用vue做轮播图 关于require的用法

    一开始,我用html做的页面,头部是轮播图,效果很好. 页面展示图片如下: 代码如下: <!DOCTYPE html> <html lang="en">&l ...

  9. 移动端h5 层叠轮播图,uniapp微信小程序层叠轮播图,3d轮播图

    如果你的项目使用的是jquery的话 推荐使用swiper 进行做 https://www.swiper.com.cn/usage/index.html 如果用的是vue3开发的纯h5项目的话,推荐 ...

最新文章

  1. WR:中国46个饮用水供水系统评估水源水对龙头水细菌群落的“烙印”
  2. Intellij IDEA自动部署项目至远程FTP服务器
  3. linux %3e%3e 重定向,当我访问HTTPS时,网站保持重定向到HTTP,无明显原因
  4. Symfony2插件StofDoctrineExtensionsBundle的使用说明
  5. ASP.NET Core launchsettings.json文件(8)《从零开始学ASP.NET CORE MVC》:
  6. 集群(cluster)amp;高可用性(HA)概念
  7. 5年iPhone用户换小米11 Ultra:惊叹小米变化大
  8. 基于JAVA+SpringMVC+Mybatis+MYSQL的微信小程序图书借阅管理系统
  9. 进出仓原理_通达信浪口主图+窥窃天机副图+进出仓副图强强组合
  10. 消息持续积压几小时怎么办
  11. win11 JDK环境变量的配置
  12. 摄像头 RTSP 以及远程管理
  13. 软件测试结果分析和质量报告
  14. sklearn.neighbors_Nearest Neighbors
  15. 详细理解script标签
  16. 从Ajax聊一聊Jsonp hijacking
  17. WebDAV之葫芦儿·派盘+小书匠
  18. Win11打不开安全中心怎么解决
  19. 让信息跨过高山大海,送达人山人海,奈何光纤损耗太大
  20. 广州数控机器人编程讲解视频_广州数控工业机器人如何编程,使用什么语言?...

热门文章

  1. 固定资产管理系统哪家好?固定资产管理平台有哪些?
  2. IAP( 应用程序內购买): 完全攻略
  3. onedrive右键菜单无释放空间和始终保留在此设备——解决方法
  4. 存储过程及Kettle初体验
  5. 程序员保密协议(合资合作)[范本]
  6. 三位创业者的“侠客行”:用金融监管科技守护投资者
  7. 设置背景透明文字内容不透明方法
  8. uboot-2010-03移植到tiny6410(1)
  9. 数字化会员营销系统如何撬动门店
  10. 预测赢家_新敏捷—赢家