Browse Source

feat(swiper): support show center

suzigang 3 years ago
parent
commit
234b153913

+ 1 - 1
src/packages/__VUE/popup/__tests__/popup.spec.ts

@@ -18,7 +18,7 @@ test('should change z-index when using z-index prop', async () => {
   });
   await nextTick();
   const pop: any = wrapper.find('.nut-popup');
-  expect(pop.element.style.zIndex).toEqual('99');
+  expect(pop.element.style.zIndex).toEqual('100');
 });
 
 test('should change animation duration when using duration prop', () => {

+ 38 - 2
src/packages/__VUE/swiper/demo.vue

@@ -86,6 +86,29 @@
         </nut-swiper-item>
       </nut-swiper>
     </view>
+    <h2>{{ translate('horizontalCenter') }}</h2>
+    <view class="demo-box">
+      <nut-swiper :init-page="page4" :loop="false" width="280" height="150" :is-center="true" style="height: 150px">
+        <nut-swiper-item v-for="item in list" :key="item">
+          <img :src="item" alt="" />
+        </nut-swiper-item>
+      </nut-swiper>
+    </view>
+    <h2>{{ translate('verticalCenter') }}</h2>
+    <view class="demo-box vertical-center">
+      <nut-swiper
+        :init-page="page4"
+        :loop="false"
+        direction="vertical"
+        height="220"
+        :is-center="true"
+        style="height: 300px"
+      >
+        <nut-swiper-item v-for="item in list" :key="item">
+          <img :src="item" alt="" />
+        </nut-swiper-item>
+      </nut-swiper>
+    </view>
   </div>
 </template>
 
@@ -103,7 +126,9 @@ useTranslate({
     indicator: '自定义指示器',
     indicator1: '自定义指示器(异步3s)',
     btns: '手动切换',
-    vertical: '垂直方向'
+    vertical: '垂直方向',
+    horizontalCenter: '水平居中展示',
+    verticalCenter: '垂直居中展示'
   },
   'en-US': {
     basic: 'Basic Usage',
@@ -113,7 +138,9 @@ useTranslate({
     indicator: 'Custom indicator',
     indicator1: 'Custom indicator(Asynchronous loading(3s))',
     btns: 'Manual switching',
-    vertical: 'Vertical direction'
+    vertical: 'Vertical direction',
+    horizontalCenter: 'Horizontal center display',
+    verticalCenter: 'Vertical center display'
   }
 });
 export default createDemo({
@@ -182,6 +209,15 @@ export default createDemo({
       height: 100%;
     }
   }
+  &.vertical-center {
+    .nut-swiper-item {
+      height: 300px;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
   ::v-deep(.nut-swiper-pagination-vertical) {
     i {
       width: 6px;

+ 95 - 0
src/packages/__VUE/swiper/doc.en-US.md

@@ -416,6 +416,100 @@ You can manually switch through `api` (`prev`, `next`)
 
 :::
 
+### Horizontal center display
+
+`is-center` means that it can be centered and must be passed to `width` at the same time
+
+:::demo
+
+```html
+<template>
+  <nut-swiper :init-page="page" :loop="false" width="280" height="150" :is-center="true" style="height: 150px">
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg'" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/welcomenutui.jpg" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/fristfabu.jpg" alt="" />
+    </nut-swiper-item>
+  </nut-swiper>
+</template>
+<script lang="ts">
+  import { reactive, toRefs } from 'vue';
+  export default {
+    setup() {
+      const state = reactive({
+        page: 0
+      });
+      return { ...toRefs(state) };
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .nut-swiper-item {
+    line-height: 150px;
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+</style>
+```
+
+:::
+
+### Vertically centered display
+
+`is-center` means that it can be centered and must be passed to `height` at the same time
+
+:::demo
+
+```html
+<template>
+  <nut-swiper :init-page="page" :loop="false" direction="vertical" height="220" :is-center="true" style="height: 300px">
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg'" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/welcomenutui.jpg" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/fristfabu.jpg" alt="" />
+    </nut-swiper-item>
+  </nut-swiper>
+</template>
+<script lang="ts">
+  import { reactive, toRefs } from 'vue';
+  export default {
+    setup() {
+      const state = reactive({
+        page: 0
+      });
+      return { ...toRefs(state) };
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .nut-swiper-item {
+    line-height: 300px;
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+</style>
+```
+
+:::
+
 
 ## API
 
@@ -435,6 +529,7 @@ You can manually switch through `api` (`prev`, `next`)
 | touchable             | if touchable to slide                                                      | Boolean         | true          |
 | is-preventDefault                  | Disable default events during sliding                                              | Boolean  | true           |
 | is-stopPropagation               | Is bubbling prohibited during sliding                    | Boolean         | true    |
+| is-center| The corresponding `width` and `height` must be passed to determine whether to display in the middle`  | Boolean   | false    |
 
 
 

+ 96 - 0
src/packages/__VUE/swiper/doc.md

@@ -417,6 +417,101 @@ app.use(Swiper).use(SwiperItem);
 :::
 
 
+### 水平居中展示
+
+`is-center` 代表可居中,同时必须传 `width`
+
+:::demo
+
+```html
+<template>
+  <nut-swiper :init-page="page" :loop="false" width="280" height="150" :is-center="true" style="height: 150px">
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg'" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/welcomenutui.jpg" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/fristfabu.jpg" alt="" />
+    </nut-swiper-item>
+  </nut-swiper>
+</template>
+<script lang="ts">
+  import { reactive, toRefs } from 'vue';
+  export default {
+    setup() {
+      const state = reactive({
+        page: 0
+      });
+      return { ...toRefs(state) };
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .nut-swiper-item {
+    line-height: 150px;
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+</style>
+```
+
+:::
+
+### 垂直居中展示
+
+`is-center` 代表可居中,同时必须传 `height`
+
+:::demo
+
+```html
+<template>
+  <nut-swiper :init-page="page" :loop="false" direction="vertical" height="220" :is-center="true" style="height: 300px">
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg'" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/welcomenutui.jpg" alt="" />
+    </nut-swiper-item>
+    <nut-swiper-item>
+      <img src="https://storage.360buyimg.com/jdc-article/fristfabu.jpg" alt="" />
+    </nut-swiper-item>
+  </nut-swiper>
+</template>
+<script lang="ts">
+  import { reactive, toRefs } from 'vue';
+  export default {
+    setup() {
+      const state = reactive({
+        page: 0
+      });
+      return { ...toRefs(state) };
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .nut-swiper-item {
+    line-height: 300px;
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+</style>
+```
+
+:::
+
+
 ## API
 
 ### Props
@@ -435,6 +530,7 @@ app.use(Swiper).use(SwiperItem);
 | touchable             | 是否可触摸滑动                                                      | Boolean         | true          |
 | is-preventDefault                  | 滑动过程中是否禁用默认事件                                              | Boolean  | true           |
 | is-stopPropagation               | 滑动过程中是否禁止冒泡                    | Boolean         | true    |
+| is-center               | 是否居中展示,必须传对应的`width` 和 `height`                    | Boolean         | false    |
 
 
 

+ 15 - 2
src/packages/__VUE/swiper/index.taro.vue

@@ -7,6 +7,7 @@
     @touchmove="onTouchMove"
     @touchend="onTouchEnd"
     @touchcancel="onTouchEnd"
+    :catch-move="isPreventDefault"
   >
     <view
       :class="{
@@ -105,6 +106,10 @@ export default create({
     isStopPropagation: {
       type: Boolean,
       default: true
+    },
+    isCenter: {
+      type: Boolean,
+      default: false
     }
   },
   emits: ['change'],
@@ -163,9 +168,18 @@ export default create({
     const activePagination = computed(() => (state.active + childCount.value) % childCount.value);
 
     const getStyle = () => {
+      let offset = 0;
+      if (!props.isCenter) {
+        offset = state.offset;
+      } else {
+        let val = isVertical.value
+          ? (state.rect as DOMRect).height - size.value
+          : (state.rect as DOMRect).width - size.value;
+        offset = state.offset + (state.active === childCount.value - 1 ? -val / 2 : val / 2);
+      }
       state.style = {
         transitionDuration: `${state.moving ? 0 : props.duration}ms`,
-        transform: `translate${isVertical.value ? 'Y' : 'X'}(${state.offset}px)`,
+        transform: `translate${isVertical.value ? 'Y' : 'X'}(${offset}px)`,
         [isVertical.value ? 'height' : 'width']: `${size.value * childCount.value}px`,
         [isVertical.value ? 'width' : 'height']: `${isVertical.value ? state.width : state.height}px`
       };
@@ -359,7 +373,6 @@ export default create({
     };
 
     const onTouchStart = (e: TouchEvent) => {
-      if (props.isPreventDefault) e.preventDefault();
       if (props.isStopPropagation) e.stopPropagation();
       if (!props.touchable) return;
       touch.start(e);

+ 16 - 1
src/packages/__VUE/swiper/index.vue

@@ -103,6 +103,10 @@ export default create({
     isStopPropagation: {
       type: Boolean,
       default: true
+    },
+    isCenter: {
+      type: Boolean,
+      default: false
     }
   },
   emits: ['change'],
@@ -160,9 +164,18 @@ export default create({
     const activePagination = computed(() => (state.active + childCount.value) % childCount.value);
 
     const getStyle = () => {
+      let offset = 0;
+      if (!props.isCenter) {
+        offset = state.offset;
+      } else {
+        let val = isVertical.value
+          ? (state.rect as DOMRect).height - size.value
+          : (state.rect as DOMRect).width - size.value;
+        offset = state.offset + (state.active === childCount.value - 1 ? -val / 2 : val / 2);
+      }
       state.style = {
         transitionDuration: `${state.moving ? 0 : props.duration}ms`,
-        transform: `translate${isVertical.value ? 'Y' : 'X'}(${state.offset}px)`,
+        transform: `translate${isVertical.value ? 'Y' : 'X'}(${offset}px)`,
         [isVertical.value ? 'height' : 'width']: `${size.value * childCount.value}px`,
         [isVertical.value ? 'width' : 'height']: `${isVertical.value ? state.width : state.height}px`
       };
@@ -219,6 +232,8 @@ export default create({
         targetOffset = range(targetOffset, minOffset.value, 0);
       }
 
+      // console.log(offset, currentPosition, targetOffset);
+
       return targetOffset;
     };
 

+ 32 - 0
src/sites/mobile-taro/vue/src/exhibition/pages/swiper/index.vue

@@ -86,6 +86,29 @@
         </nut-swiper-item>
       </nut-swiper>
     </view>
+    <h2>水平居中展示</h2>
+    <view class="demo-box">
+      <nut-swiper :init-page="page4" :loop="false" width="280" height="150" :is-center="true" style="height: 150px">
+        <nut-swiper-item v-for="item in list" :key="item">
+          <img :src="item" alt="" />
+        </nut-swiper-item>
+      </nut-swiper>
+    </view>
+    <h2>垂直居中展示</h2>
+    <view class="demo-box vertical-center">
+      <nut-swiper
+        :init-page="page4"
+        :loop="false"
+        direction="vertical"
+        height="220"
+        :is-center="true"
+        style="height: 300px"
+      >
+        <nut-swiper-item v-for="item in list" :key="item">
+          <img :src="item" alt="" />
+        </nut-swiper-item>
+      </nut-swiper>
+    </view>
   </div>
 </template>
 
@@ -157,6 +180,15 @@ export default {
       height: 100%;
     }
   }
+  &.vertical-center {
+    .nut-swiper-item {
+      height: 300px;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
   .nut-swiper-pagination-vertical {
     i {
       width: 6px;