graceSwiper.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <template>
  2. <view class="grace-swiper-card-wrap">
  3. <swiper :style="{width:width+'rpx', height:heightIn+'rpx'}" class="grace-swiper-card"
  4. :indicator-dots="false" :interval="interval" :circular="true" :autoplay="autoplay" :current="currentIndex"
  5. :previous-margin="spacing+'rpx'" :next-margin="spacing+'rpx'" @change="swiperchange">
  6. <swiper-item v-for="(item, index) in swiperItems" :key="index" class="grace-swiper-card-item">
  7. <navigator class="grace-swiper-card-nav" :url="item.url" :open-type="item.opentype" hover-class="none" v-if="item.opentype != 'click'"
  8. :style="{paddingLeft:current != index ? padding +'rpx':'0rpx',
  9. paddingRight:current != index ? padding +'rpx':'0rpx',
  10. paddingTop:current != index ? paddingY +'rpx':'0rpx',
  11. paddingBottom:current != index ? paddingY +'rpx':'0rpx',
  12. transition: 'all 0.2s ease-in 0s'}">
  13. <image :style="{
  14. borderRadius : borderRadius,
  15. transition: 'all 0.2s ease-in 0s',
  16. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  17. height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
  18. opacity:current != index ? opacity : 1}"
  19. :src="item.img" class="grace-swiper-card-image" />
  20. </navigator>
  21. <view class="grace-swiper-card-nav" hover-class="none" v-if="item.opentype == 'click'" @tap.stop="taped" :data-index="index"
  22. :style="{paddingLeft:current != index ? padding +'rpx':'0rpx',
  23. paddingRight:current != index ? padding +'rpx':'0rpx',
  24. paddingTop:current != index ? paddingY +'rpx':'0rpx',
  25. paddingBottom:current != index ? paddingY +'rpx':'0rpx',
  26. transition: 'all 0.2s ease-in 0s'}">
  27. <image :style="{
  28. borderRadius : borderRadius,
  29. transition: 'all 0.2s ease-in 0s',
  30. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  31. height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
  32. opacity:current != index ? opacity : 1}"
  33. :src="item.img" class="grace-swiper-card-image" />
  34. </view>
  35. <view v-if="indicatorType == 'number'" class="grace-indicator-dot-numbers"
  36. :style="{
  37. height:indicatorBarHeight+'rpx', background:indicatorBarBgColor,
  38. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  39. left:current != index ? padding+'rpx':'0rpx', bottom:current != index ? paddingY+'rpx':'0rpx'}">
  40. <text class="grace-indicator-dot-text"
  41. :style="{paddingLeft:'20rpx', 'fontStyle':'italic', color:titleColor}">{{index+1}}</text>
  42. <text class="grace-indicator-dot-text"
  43. :style="{'fontSize':'36rpx', color:titleColor}">/</text>
  44. <text class="grace-indicator-dot-text"
  45. :style="{fontSize:'28rpx', paddingRight:'20rpx', fontStyle:'italic', color:titleColor}">{{swiperItems.length}}</text>
  46. <text class="grace-swiper-text"
  47. :style="{color:titleColor, fontSize:titleSize, height:indicatorBarHeight+'rpx',
  48. lineHeight:indicatorBarHeight+'rpx'}">{{item.title}}</text>
  49. </view>
  50. </swiper-item>
  51. </swiper>
  52. <view class="grace-indicator-dots" v-if="indicatorType == 'dot'"
  53. :style="{width:width+'rpx', height:indicatorBarHeight+'rpx', position:indicatorPosition,
  54. paddingLeft:spacing+'rpx', paddingRight:spacing+'rpx'}">
  55. <view v-for="(item, index) in swiperItems" :key="index"
  56. :class="['grace-indicator-dot',current == index ? 'dot-show' : '']"
  57. :style="{
  58. width : current != index ? indicatorWidth+'rpx' : indicatorActiveWidth +'rpx',
  59. height : indicatorHeight+'rpx',
  60. borderRadius : indicatorRadius+'rpx',
  61. background : current != index ? indicatorColor : indicatorActiveColor}"></view>
  62. </view>
  63. </view>
  64. </template>
  65. <script>
  66. export default{
  67. props:{
  68. width:{ type : Number, default : 750 },
  69. height:{ type : Number, default : 300 },
  70. swiperItems : { type : Array, default : function(){return new Array();} },
  71. borderRadius : { type : String, default : '10rpx'},
  72. indicatorBarHeight:{type : Number, default : 68},
  73. indicatorBarBgColor:{type : String, default : 'rgba(0,0,0,0)'},
  74. indicatorWidth : { type:Number, default:18 },
  75. indicatorActiveWidth :{ type:Number, default:18 },
  76. indicatorHeight : { type:Number, default:18 },
  77. indicatorRadius:{ type:Number, default:18 },
  78. indicatorColor : { type : String, default : "rgba(255, 255, 255, 0.6)" },
  79. indicatorActiveColor : { type : String, default : "#3688FF" },
  80. indicatorType:{ type : String, default : "dot" },
  81. indicatorPosition:{ type : String, default : "absolute" },
  82. spacing : { type : Number, default : 50 },
  83. padding : { type : Number, default : 26 },
  84. interval : { type : Number, default : 5000 },
  85. autoplay : { type : Boolean, default : true },
  86. currentIndex : { type : Number, default : 0 },
  87. opacity:{ type : Number, default:0.66},
  88. titleColor:{type:String, default:"#FFFFFF"},
  89. titleSize:{type:String, default:"28rpx"}
  90. },
  91. data() {
  92. return {
  93. current : 0,
  94. isReady : false,
  95. widthIn : 750,
  96. heightIn : 300,
  97. widthInSamll:700,
  98. heightInSmall:280,
  99. paddingY:0
  100. }
  101. },
  102. watch:{
  103. currentIndex : function (val) {
  104. this.current = val;
  105. }
  106. },
  107. created:function(){
  108. this.current = this.currentIndex;
  109. this.init();
  110. },
  111. methods:{
  112. init : function(){
  113. // 图片宽高计算
  114. this.widthIn = this.width - this.spacing*2;
  115. this.heightIn = this.height / this.width * this.widthIn;
  116. this.paddingY = this.padding * this.height / this.width;
  117. this.widthInSamll = this.widthIn - this.padding * 2;
  118. this.heightInSmall = this.heightIn - this.paddingY * 2;
  119. },
  120. swiperchange : function (e) {
  121. var current = e.detail.current;
  122. this.current = current;
  123. this.$emit('swiperchange', current);
  124. },
  125. taped : function(e){
  126. this.$emit('taped', e.currentTarget.dataset.index);
  127. }
  128. }
  129. }
  130. </script>
  131. <style scoped>
  132. .grace-swiper-card-wrap{position:relative;}
  133. .grace-swiper-card{overflow:hidden;}
  134. .grace-swiper-card-item{box-sizing:border-box; font-size:0; overflow:hidden; line-height:0;}
  135. .grace-swiper-card-nav{font-size:0; display:block; position:relative;}
  136. .grace-swiper-card-image{}
  137. .grace-indicator-dots{width:750rpx; height:68rpx; overflow:hidden; z-index:1; left:0; bottom:0; display:flex; flex-direction:row; flex-wrap:nowrap; box-sizing:border-box; align-items:center; justify-content:center;}
  138. .grace-indicator-dot{margin:6rpx;}
  139. .grace-indicator-dot-text{display:block; text-align:center; line-height:68rpx; padding:0 4rpx; color:#FFFFFF; font-size:32rpx; flex-shrink:0;}
  140. .grace-indicator-dot-numbers{display:flex; flex-direction:row; flex-wrap:nowrap; justify-content:center; overflow:hidden; align-items:center; position:absolute; z-index:1; left:0; bottom:0;}
  141. .grace-swiper-text{width:750rpx; line-height:68rpx; padding-right:25rpx; box-sizing:border-box; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
  142. @keyframes dot-show{from{opacity:0.1;}to{opacity:1;}}
  143. .dot-show{animation:dot-show 300ms linear forwards;}
  144. </style>