Preview
Algorithm
api
css
position
, z-index
, margin-left
, transform
, transition
, opacity
js
throttle
, debounce
, wx.createSelectorQuery
(通過 child 計(jì)算容器高度)
wxml/html
touchstart
, touchmove
, touchend
step by step
tower-swiper
設(shè)置position: relative
tower-swiper-item
使用絕對(duì)布局position:absolute
使其在parent中水平居中的位置tower-swiper-item
通過transform:translateX()
實(shí)現(xiàn)水平(同樣可以使用margin-left
,這里為了偏移量為自身寬度百分比瘦麸,便使用了translateX
)tower-swiper-item
通過transform:scale()
實(shí)現(xiàn)尺寸層次感tower-swiper-item
通過z-index
實(shí)現(xiàn)堆疊效果毫胜,中間至兩端的元素禁添,z-index
遞減tower-swiper-item
通過transition
實(shí)現(xiàn)過渡效果-
劃重點(diǎn): 通過
js
計(jì)算z-index
,left
偏移量z-index 從中間往兩端依次降低,left偏移量中間為0校赤, 左端為負(fù)值,右端為正值
通過
touchstart
,touchmove
,touchend
處理手勢(shì)交互性能優(yōu)化: 通過
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;
}
計(jì)算 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);
}
通過設(shè)置 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' },
],
},
});