珠宝小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

251 lines
5.0 KiB

<template>
<view class="swiper-item" ref="swiper_item" :style="itemStyle">
<view class="item-cntent" bubble="true" @click.stop="onClick"><slot></slot></view>
</view>
</template>
<script>
import { getStyleStr } from '../../utils/style.js';
// #ifdef APP-NVUE
const animation = uni.requireNativePlugin('animation');
// #endif
/**
* esc-swiper-item
* @description esc-swiper-item (不支持使用class)
* @property {Number} index 索引(必填)
* @property {Boolean} clickAny 可以点击任意项
* @event {Function} click 点击事件
*/
export default {
name: 'esc-swiper-item',
inject: ['config'],
props: {
index: {
type: Number,
default: 0
},
clickAny: {
type: Boolean,
default: false
}
},
data() {
return {
isAnimated: false,
timingFunction: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
duration: 0,
current: 0,
position: 0,
mScale: 0,
canClick: true
};
},
created() {},
computed: {
size() {
return this.config.size;
},
width() {
return this.config.width;
},
height() {
return this.config.height;
},
itemWidth() {
return this.config.itemWidth;
},
itemHeight() {
return this.config.itemHeight;
},
space() {
return this.config.space;
},
itemStyle() {
if (this.index == this.size - 1) {
return this.rightSpaceStyle();
} else if (this.index == this.size - 2) {
return this.centerSpaceStyle();
} else {
return this.leftSpaceStyle();
}
},
scale() {
if (!this.config.is3D) {
return 1;
}
if (this.myCurrent == this.current) {
return this.mScale || this.config.scale;
} else {
return this.mScale || 1;
}
},
// 当前swiper-item所属current索引
myCurrent() {
if (!this.config.isCircular) {
return this.index;
}
const p = this.index;
const plus = this.config.plus;
const actSize = this.size - plus * 2;
let current = 0;
if (p < plus) {
current = p + (actSize - plus);
} else if (p >= this.size - plus) {
current = p - (actSize + plus);
} else {
current = p - plus;
}
return current;
}
},
methods: {
itemSize() {
let style = {
width: this.itemWidth + 'rpx',
height: (this.itemHeight || this.height) + 'rpx'
};
if (this.config.is3D) {
// #ifndef APP-NVUE
if (this.isAnimated) {
style.transition = 'transform ' + this.duration + 'ms ' + this.timingFunction;
} else {
style.transition = '';
}
style.transform = 'scale(' + this.scale + ')';
// #endif
// #ifdef APP-NVUE
const isIOS = uni.getSystemInfoSync().platform == 'ios';
if (isIOS) {
style.transform = 'scale(' + this.scale + ')';
} else {
if (!this.isAnimated) style.transform = 'scale(' + this.scale + ')';
}
// #endif
}
return style;
},
leftSpaceStyle() {
return getStyleStr({
...this.itemSize(),
marginLeft: this.space + 'rpx'
});
},
centerSpaceStyle() {
return getStyleStr({
...this.itemSize(),
marginLeft: this.space + 'rpx',
marginRight: this.space + 'rpx'
});
},
rightSpaceStyle() {
return getStyleStr({
...this.itemSize(),
marginRight: this.space + 'rpx'
});
},
onClick(e) {
if (!this.canClick) {
return;
}
// #ifdef APP-NVUE
e.stopPropagation();
// #endif
// 点击任意项
if (this.clickAny) {
this.$emit('click', e);
return;
}
// 只能点击当前项
if (this.myCurrent == this.current) {
this.$emit('click', e);
}
},
restoreScale(duration) {
if (!this.config.is3D) {
return;
}
// #ifndef APP-NVUE
this.duration = duration;
this.isAnimated = true;
this.mScale = 0;
setTimeout(() => {
this.duration = 0;
this.isAnimated = false;
}, duration);
// #endif
// #ifdef APP-NVUE
this.isAnimated = true;
this.mScale = 0;
animation.transition(
this.$refs['swiper_item'].ref,
{
styles: {
transform: 'scale(' + this.scale + ')'
},
duration, //ms
timingFunction: this.timingFunction,
needLayout: false,
delay: 0 //ms
},
() => {
this.isAnimated = false;
}
);
// #endif
},
restoreToScale(scale, duration) {
if (!this.config.is3D) {
return;
}
// #ifndef APP-NVUE
this.duration = duration;
this.isAnimated = true;
this.mScale = scale;
setTimeout(() => {
this.duration = 0;
this.isAnimated = false;
this.mScale = 0;
}, duration);
// #endif
// #ifdef APP-NVUE
this.isAnimated = true;
animation.transition(
this.$refs['swiper_item'].ref,
{
styles: {
transform: 'scale(' + scale + ')'
},
duration, //ms
timingFunction: this.timingFunction,
needLayout: false,
delay: 0 //ms
},
() => {
this.isAnimated = false;
this.mScale = 0;
}
);
// #endif
}
}
};
</script>
<style scoped>
.swiper-item {
position: relative;
}
.item-cntent {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
}
</style>