Files
xk-doctor-wx/components/d-previewImage/d-previewImage.vue
2024-09-19 12:57:55 +08:00

226 lines
4.6 KiB
Vue

<template>
<view class="previewImage" :style="{ 'background-color':'rgba(0,0,0,'+opacity+')'}" v-if="show" @tap="close" @touchmove.stop.prevent >
<swiper class="swiper" :current="index" @change="change">
<swiper-item v-for="(img, i) in urls" :key="i" >
<movable-area class="marea" scale-area>
<movable-view class="mview" direction="all" :out-of-bounds="false" scale="true" @scale="onScale" :inertia="true" damping="90" friction="0.9" scale-min="0.9" scale-max="4" :scale-value="scale">
<image class="image" :src="img" :data-index="i" :data-src="img" mode="widthFix" @touchmove="handletouchmove" @touchstart="handletouchstart" @touchend="handletouchend" />
</movable-view>
</movable-area>
</swiper-item>
</swiper>
<view class="page" v-if="urls.length > 0">
<text class="text">{{ index+1 }} / {{ urls.length }}</text>
</view>
<view class="desc" v-if="descs.length > 0 && descs.length == urls.length&&descs[index].length>0">{{ descs[index] }}</view>
<view class="left-pre" v-if="index > 0" @tap.native.stop='goPre'>
<u-icon name="arrow-right" size="64rpx" color="#fff"></u-icon>>
</view>
<view class="right-next" v-if="urls.length-1-index > 0" @tap.native.stop="goNext">
<u-icon name="arrow-right" size="64rpx" color="#fff"></u-icon>>
</view>
</view>
</template>
<script>
export default {
name: 'd-previewImage', //插件名称
props: {
imgs: {//图片列表
type: Array,
required: true,
default: () => {
return [];
}
},
descs: {//描述列表
type: Array,
required: false,
default: () => {
return [];
}
},
//透明度,0到1之间。
opacity: {
type: Number,
default: 0.8
}
},
data() {
return {
show: false, //显示状态
index: 0, //当前页
time:0,//定时器
interval: 1000, //长按事件
scale: 1, //缩放比例
old: {
scale: 1 //缩放比例
},
urls:this.imgs
};
},
methods: {
goPre(){
this.index = this.index-1;
},
goNext(){
this.index = this.index+1;
},
onScale(e) {
this.old.scale = e.detail.scale
},
//接触开始
handletouchstart(e) {
var tchs = e.touches.length;
if (tchs != 1) {
return false;
}
this.time = setTimeout(() => {
this.onLongPress(e);
}, this.interval);
return false;
},
//清除定时器
handletouchend() {
clearTimeout(this.time);
if (this.time != 0) {
//处理点击时间
}
return false;
},
//清除定时器
handletouchmove() {
clearTimeout(this.time);
this.time = 0;
},
// 处理长按事件
onLongPress(e) {
var src = e.currentTarget.dataset.src;
var index = e.currentTarget.dataset.index;
var data={src:src,index:index}
this.$emit('longPress', data);
},
//图片改变
change(e) {
this.scale = 1;
this.index = e.target.current;
},
//打开
open(urls,e=0) {
if (e===null||e==="") {
return;
}
if(!isNaN(e)){
this.index = e;
}else{
this.index = this.urls.indexOf(e);
}
this.urls = urls
this.show = true;
},
//关闭
close(e) {
this.show = false;
}
}
};
</script>
<!--使用scss,只在本组件生效-->
<style lang="scss" scoped>
.previewImage {
z-index: 999;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000000;
user-select: none;
.left-pre{
position: absolute;
left: 0;
top: calc(50% - 78rpx);
background: rgba(0, 0, 0, 0.4);
width: 78rpx;
height: 156rpx;
border-radius: 0 78rpx 78rpx 0;
z-index: 1001;
.icon-arrow{
width: 64rpx;
height: 64rpx;
margin-top: 46rpx;
}
}
.right-next{
position: absolute;
right: 0;
top: calc(50% - 78rpx);
width: 78rpx;
height: 156rpx;
background: rgba(0, 0, 0, 0.4);
border-radius: 78rpx 0 0 78rpx;
z-index: 1001;
.icon-arrow{
margin-top: 46rpx;
margin-left: 12rpx;
width: 64rpx;
height: 64rpx;
}
}
.swiper {
width: 100%;
height: 100%;
.marea {
height: 100%;
width: 100%;
position: fixed;
overflow: hidden;
.mview {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: auto;
min-height: 100%;
.image {
width: 100%;
}
}
}
}
.page {
position: absolute;
width: 100%;
bottom: 60rpx;
text-align: center;
.text {
color: #fff;
font-size: 34rpx;
font-size: 500;
padding: 3rpx 16rpx;
border-radius: 20rpx;
}
}
.desc {
position: absolute;
top: 51rpx;
width: 100%;
padding: 5rpx 10rpx;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
// background-color: rgba(0, 0, 0, 0.5);
color: #fff;
font-size: 46rpx;
font-size: 500;
letter-spacing: 3rpx;
}
}
</style>