提交 a17f3bc7 编写于 作者: DCloud_JSON's avatar DCloud_JSON

优化 示例drop-card 通过dom的ref操作减少diff、过度动画替代帧动画

上级 7a2ad376
<template> <template>
<view class="root"> <view class="root">
<view class="card" <template v-for="(item,index) in cardList" :key="index">
:style="{'top':Math.abs(x)/-60 + 90 +'px',transform:'scale('+(movePercent/10+0.80)+')','height':cardHeight+'px'}"> <view class="card" ref="card" @touchstart="touchstart($event as TouchEvent,index)" @touchmove="touchmove($event as TouchEvent,index)" @touchend="touchend" @touchcancel="touchend">
<image class="user-img" :src="userList[0]" :style="{'height':cardHeight+'px'}"></image> <image class="card-img" ref="card-img" :src="item"></image>
</view> <template v-if="index == 2">
<view class="card" <view class="state">
:style="{'top':Math.abs(x)/-30 + 45 +'px',transform:'scale('+(movePercent/10+0.90)+')','height':cardHeight+'px'}"> <image class="state-icon like" ref="state-icon-like" src="/static/template/drop-card/like.png" mode="widthFix"></image>
<image class="user-img" :src="userList[1]" :style="{'height':cardHeight+'px'}"></image> <image class="state-icon dislike" ref="state-icon-dislike" src="/static/template/drop-card/dislike.png" mode="widthFix"></image>
</view> </view>
<view @touchmove="touchmove" @touchstart="touchstart" @touchend="touchend" </template>
:style="{'transform':'translate('+x+'px,'+y+'px) rotate('+x/-30+'deg)','height':cardHeight+'px'}" class="card">
<image class="user-img" :src="userList[2]" :style="{'height':cardHeight+'px'}"></image>
<view class="state">
<image class="state-icon like" :style="{'opacity':x < 0 ? 0 : movePercent * 10}" src="/static/template/drop-card/like.png" mode="widthFix"></image>
<image class="state-icon dislike" :style="{'opacity':x > 0 ? 0 : movePercent * 10}" src="/static/template/drop-card/dislike.png" mode="widthFix"></image>
</view> </view>
</view> </template>
</view> </view>
</template> </template>
<script lang="ts"> <script lang="ts">
let sX : number = 0, let sX : number = 0,
sY : number = 0, sY : number = 0,
screenWidth : number = 1; screenWidth : number = 1,
nodesMap = new Map<string, INode[]>();
export default { export default {
data() { data() {
return { return {
x: 0, x: 0,
y: 0, y: 0,
cardHeight:1, cardList: [
userList: [ '/static/template/drop-card/1.jpg',
'/static/template/drop-card/1.png', '/static/template/drop-card/2.jpg',
'/static/template/drop-card/2.png', '/static/template/drop-card/3.jpg'
'/static/template/drop-card/3.png' ] as string[],
] NodesMap: new Map<string, INode[]>(),
} }
}, },
computed: { onReady() {
movePercent() : number { this.setStyle('card',2,'transitionTimingFunction','ease-in-out');
return Math.abs(this.x) / screenWidth this.setStyle('card',2,'transitionProperty','transform');
},
likeOpacity() : number{
return this.x < 0 ? 0 : this.movePercent * 100
},
dislikeOpacity() : number{
return this.x > 0 ? 0 : this.movePercent * 100
}
},
onLoad() {
uni.getSystemInfo({ uni.getSystemInfo({
success: (e) => { success: (e) => {
console.log('e',e); // console.log('e',e);
screenWidth = e.screenWidth screenWidth = e.screenWidth;
this.cardHeight = e.screenHeight - 200 let height = e.screenHeight - 200 + 'px'
for (var i = 0; i < 3; i++) {
this.setStyle('card',i,'height', height);
this.setStyle('card-img',i,'height', height);
}
} }
}) })
},
watch: {
x() {
this.onMove()
},
y() {
this.onMove()
}
},
computed: {
movePercent() : number {
return Math.abs(this.x) / (screenWidth/2*3)
},
likeOpacity() : number {
return this.x < 0 ? 0 : this.movePercent * 100
},
dislikeOpacity() : number {
return this.x > 0 ? 0 : this.movePercent * 100
}
}, },
methods: { methods: {
changeUserList() { setStyle(refName:string,index:number,propertyName:string,propertyStyle:any):void{
let user:string = this.userList[this.userList.length - 1] let nodes:INode[]|null = nodesMap.get(refName)
this.userList.unshift(user) if(nodes == null){
this.userList.pop() nodes = this.$refs.get(refName) as INode[]
this.x = 0; nodesMap.set(refName,nodes)
this.y = 0; }else{
// console.log('直接拿');
}
(nodes)[index].style.setProperty(propertyName,propertyStyle);
}, },
touchstart(e : TouchEvent) { onMove() {
this.setStyle('card',0,'transform', 'scale('+(this.movePercent/10+0.80)+')')
this.setStyle('card',1,'transform', 'scale('+(this.movePercent/10+0.90)+')')
this.setStyle('card',2,'transform', 'translateX('+this.x+'px) translateY('+this.y+'px) rotate('+this.x/-30+'deg)')
this.setStyle('state-icon-like',0,'opacity', x < 0 ? 0 : movePercent * 10)
this.setStyle('state-icon-dislike',0,'opacity', x > 0 ? 0 : movePercent * 10)
},
changeCardList() {
let newArr = this.cardList.slice();
this.cardList[0] = newArr[2]
this.cardList[1] = newArr[0]
this.cardList[2] = newArr[1]
this.x = 0
this.y = 0
},
touchstart(e : TouchEvent,index:number) {
if(index != 2){
return
}
sX = e.touches[0].screenX; sX = e.touches[0].screenX;
sY = e.touches[0].screenY; sY = e.touches[0].screenY;
}, },
touchmove(e : TouchEvent) { touchmove(e : TouchEvent,index:number) {
if(index != 2){
return
}
this.x += e.touches[0].screenX - sX; this.x += e.touches[0].screenX - sX;
this.y += e.touches[0].screenY - sY; this.y += e.touches[0].screenY - sY;
sX = e.touches[0].screenX; sX = e.touches[0].screenX;
sY = e.touches[0].screenY; sY = e.touches[0].screenY;
}, },
touchend() { touchend() {
if (this.x > screenWidth / 6) { // console.log('touchend');
let interval : number = 0;
interval = setInterval(() => { // 设置释放之后飘走的方向 0回到坐标中心 1向右 2向左
this.x += 10 let k:number = 0;
this.y += 3 if (this.x > screenWidth / 6 ) {
if (this.x > screenWidth) { k = 1
clearInterval(interval) }else if(this.x < screenWidth * -1 / 6){
this.changeUserList() k = -1
} }
}, 6) // 设置动画时间
} else if (this.x < screenWidth * -1 / 6) { let time = 400;
let interval : number = 0; this.setStyle('card',2,'transitionDuration',time.toFixed(0));
interval = setInterval(() => {
this.x -= 10 this.x = screenWidth * 1.5 * k
this.y += 3 this.y = Math.abs(screenWidth * 0.5 * k)
if (this.x < -screenWidth) {
clearInterval(interval) setTimeout(()=>{
this.changeUserList() //关闭动画
} this.setStyle('card',2,'transitionDuration',0);
}, 6) // 更改卡片上的图片内容
} else { if(k != 0){
this.x = 0 this.changeCardList()
this.y = 0 }
} },time)
} }
} }
} }
...@@ -109,36 +145,39 @@ ...@@ -109,36 +145,39 @@
} }
.card { .card {
width: 700rpx; width: 700rpx;
height: 750rpx; height: 750rpx;
position: absolute; position: absolute;
margin: 0 25rpx; margin: 0 25rpx;
margin-top: 30px; margin-top: 30px;
border-radius: 10px; border-radius: 10px;
color: #FFF; color: #FFF;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
z-index: 100;
} }
.user-img{ .card-img {
border-radius: 10px; border-radius: 10px;
} }
.state { .state {
top: 20rpx; top: 20rpx;
left: 20rpx; left: 20rpx;
width: 650rpx; width: 650rpx;
padding: 4px; padding: 4px;
position: absolute; position: absolute;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
} }
.state-icon {
width: 30px; .state-icon {
height: 30px; width: 30px;
border: 1px solid #FFF; height: 30px;
background-color: #FFF; border: 1px solid #FFF;
padding: 3px; background-color: #FFF;
border-radius: 100px; padding: 3px;
box-shadow: 0 0 1px #EBEBEB; border-radius: 100px;
box-shadow: 0 0 1px #EBEBEB;
opacity: 0;
} }
</style> </style>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册