Tower Swiper

Preview

2020-11-22-tower_swiper.gif

Algorithm

api

css

position, z-index, margin-left, transform, transition, opacity

js

throttle, debounce, wx.createSelectorQuery(通过 child 计算容器高度)

wxml/html

touchstart, touchmove, touchend

step by step

  1. tower-swiper 设置 position: relative

  2. tower-swiper-item 使用绝对布局 position:absolute 使其在parent中水平居中的位置

  3. tower-swiper-item 通过 transform:translateX() 实现水平(同样可以使用margin-left,这里为了偏移量为自身宽度百分比,便使用了 translateX)

  4. tower-swiper-item 通过 transform:scale() 实现尺寸层次感

  5. tower-swiper-item 通过 z-index 实现堆叠效果,中间至两端的元素,z-index递减

  6. tower-swiper-item 通过 transition 实现过渡效果

  7. 划重点: 通过 js 计算 z-index, left 偏移量

    z-index 从中间往两端依次降低,left偏移量中间为0, 左端为负值,右端为正值

  8. 通过touchstart, touchmove, touchend 处理手势交互

  9. 性能优化: 通过 throttle, debounce 过滤一些不必要的高频事件

tower-swiper-item 整体样式

.tower-swiper-item {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(calc(-50% + var(--left) * 20%));
    z-index: var(--z-index);
    transition: all ease 0.5s;
}

.tower-swiper-item--hidden {
    opacity: 0;
}

.tower-swiper-item__scale {
    transform: scale(var(--scale));
    transition: all ease 0.5s;
}

计算 z-index, left

const { items, active } = this.data;
const l = items.length;
const odd = l % 2;
const half = Math.floor(items.length / 2);
// eslint-disable-next-line no-plusplus
for (let i = 0; i < items.length; i++) {
  const item = items[(half + active + i + odd) % l];
  const zIndex = half - Math.abs(half - i) + odd;
  item.setZIndex(zIndex);
  item.setLeft(i - half);
  item.setScale(1 - (half - zIndex) / 10);
}

通过设置 active 改变中间显示的 item

Usage

{
  "usingComponents": {
    "tower-swiper": "/lib/tower-swiper/index",
    "tower-swiper-item": "/lib/tower-swiper-item/index"
  }
}
<tower-swiper class="tower-swiper">
  <tower-swiper-item wx:for="{{items}}" wx:key="id">
    <image class="item" src="{{item.url}}" mode="aspectFill"></image>
  </tower-swiper-item>
</tower-swiper>
Page({
  data: {
    items: [
      { id: 0, type: 'image', url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big84000.jpg' },
      { id: 1, type: 'image', url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big84001.jpg' },
      { id: 2, type: 'image', url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big39000.jpg' },
      { id: 3, type: 'image', url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big10001.jpg' },
      { id: 4, type: 'image', url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big25011.jpg' },
      { id: 5, type: 'image', url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big21016.jpg' },
      { id: 6, type: 'image', url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big99008.jpg' },
    ],
  },
});

References

License

MIT

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 学会使用CSS选择器熟记CSS样式和外观属性熟练掌握CSS各种选择器熟练掌握CSS各种选择器熟练掌握CSS三种显示...
    七彩小鹿阅读 6,353评论 2 66
  • js插件之iscroll,swiper 1.iscroll 1.1我们在电商网站移动端经常会看见有侧边栏,如下图 ...
    煤球快到碗里来阅读 520评论 0 0
  • 盒子模型(CSS重点) 其实,CSS就三个大模块: 盒子模型 、 浮动 、 定位,其余的都是细节。要求这三部分,...
    xlystar阅读 1,874评论 0 1
  • CSS的出现 在页面成型的初期,我们当靠HTML就能完成一些简单的页面设计和控制,但是随着互联网的发展以及用户的需...
    Kazusa_阅读 3,910评论 0 2
  • 腾讯视频是一个让我们都喜爱的视频观看平台,用户群体也相当庞大。小编也非常喜欢使用腾讯视频播放软件,在娱乐的时间之...
    袁德红orJayson阅读 885评论 0 1