相册预览相关代码片段
在这里插入代码片
<template>
<j-modal class="picPreview" :title="title" :width="width" :visible="imgListShow" fullscreen
@toggleFullscreen="toggleFullscreen" @cancel="imgListShow = false" :bodyStyle="moduleCenter">
<a-button @click="handleCurrentChange(-1)" style=" height: 50px;" class="right_next">
<a-icon type="left" />
</a-button>
<div id="test_3" @mousemove="move" @mouseup="stop" @mouseleave="mouseLeave">
<a-spin :spinning="confirmLoading">
<img @mousedown="start" :src="handleVideoUrl(furl)" ref="singleImg" class="originStyle"
@error="dealErr($event)" loading="lazy" />
</a-spin>
</div>
<a-button @click="handleCurrentChange(1)" style=" height: 50px;" class="right_next">
<a-icon type="left" style="transform: rotate(180deg);" />
</a-button>
<div class="ctr-box">
<a-button @click="rotateL" title="左旋转">
<a-icon type="redo" />
</a-button>
<a-button @click="rotateR" title="右旋转">
<a-icon type="undo" />
</a-button>
<a-button @click="scale(-1)" title="缩小">
<a-icon type="zoom-out" />
</a-button>
<a-button @click="scale(1)" title="放大">
<a-icon type="zoom-in" />
</a-button>
</div>
<template slot="footer">
<div class="allImg">
<a-button @click="handleCurrentChange(-1)" class="changeImg">
<a-icon type="left" />
</a-button>
<div class="imgbox">
<div ref="imgbox" class="imgbox-item">
<img v-for="(item, index) in imgList" :key="index" :src="handleVideoUrl(item.previewUrl)"
@error="dealErr($event)" :class="{ changeColor: changeColor == index }"
@click="handlerImg(item, index)" />
</div>
</div>
<a-button @click="handleCurrentChange(1)" class="changeImg right">
<a-icon type="left" style="transform: rotate(180deg);" />
</a-button>
</div>
</template>
</j-modal>
</template>
<script>
import Vue from 'vue'
import { filterObj } from '@/utils/util';
import { ACCESS_TOKEN } from '@/store/mutation-types'
export default {
name: "PicPreview",
data() {
return {
width: 1200,
indexImg: 0,
visible: false,
disableSubmit: false,
imgListShow: false,
num: 0,
furl: "",
changeColor: -1,
currentRotate: 0,
currentScale: 0.6,
canDrag: false,
offset_x: 0,
offset_y: 0,
mouse_x: 0,
mouse_y: 0,
ipaginationV: {
current: 1,
pageSize: 21,
pageSizeOptions: ['5', '10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
total: 0
},
confirmLoading: true,
moduleCenter: {
display: "flex",
alignItems: "center",
justifyContent: "center",
textAlign: "center",
height: "730px"
},
downUrl: ""
};
},
computed: {
},
props: {
title: {
//弹框名称
type: String,
required: false,
default: "图片预览"
},
filePreviewShow: {
//是否显示
type: Boolean,
required: true,
default: true
},
imgList: {
type: Array,
required: true,
default: function () {
return [];
}
},
currentImg: {
//当前图像
type: String,
required: false,
default: ""
},
currentIndex: {
//当前图像下标
type: Number,
required: false,
default: 0
}
},
watch: {
// filePreviewShow(newv) {
// if (newv) {
// } else {
// this.imgListShow = this.filePreviewShow;
// this.$refs.imgbox.scrollLeft = 0;
// window.removeEventListener("mousewheel", this.handleScroll, true) ||
// window.removeEventListener("DOMMouseScroll", this.handleScroll, true);
// }
// }
},
mounted() {
setTimeout(() => {
this.scrollImg(this.changeColor - 48, this.changeColor < 48);
}, 500);
},
methods: {
dealErr(e) {
e.target.src = 'https://demo.thingskit.com/assets/product-default.37c30aed.svg'
console.log('图片加载失败')
},
toggleFullscreen(val) {
this.switchFullscreen = {
display: "flex",
alignItems: "center",
justifyContent: "center",
textAlign: "center",
height: val ? "790px" : "400px"
}
},
handleVideoUrl(val) {
const imageRegex = /\.(jpg|jpeg|png|gif|bmp|webp)$/i;
const url = (typeof val === 'object' && val !== null && val.imgUrl) ? val.imgUrl : val;
if (imageRegex.test(url)) {
return window._CONFIG['domianURL'] + url + "?token=" + Vue.ls.get(ACCESS_TOKEN);
} else {
return 'https://demo.thingskit.com/assets/product-default.37c30aed.svg'
}
},
handleshow() {
console.log('预览视频')
this.imgListShow = true
debugger
this.$nextTick(() => {
this.imgListShow = this.filePreviewShow;
this.imgList = this.trimSpace(this.imgList);
if (this.imgList.length === 0) {
this.furl = "";
this.changeColor = -1;
} else {
this.changeColor = this.currentIndex;
// if (this.currentImg) {
// this.changeColor = this.imgList.findIndex(
// a => a === this.currentImg
// );
// }
setTimeout(() => {
this.scrollImg(this.changeColor, this.changeColor < this.imgList.length);
}, 500);
this.confirmLoading =false
console.log('预览视频', this.currentIndex)
console.log('预览视频', this.currentImg)
// this.furl = this.imgList[nextIndex].img;
this.furl = this.currentImg
this.handlerImg(this.furl, this.changeColor);
}
})
},
trimSpace(array) {
for (var i = 0; i < array.length; i++) {
if (
array[i] == " " ||
array[i] == null ||
typeof array[i] == "undefined"
) {
array.splice(i, 1);
i = i - 1;
}
}
return array;
},
//判断滚动方向
handleScroll(e) {
this.scale(-e.deltaY);
},
//点击图片显示
handlerImg(furl, index) {
this.currentRotate = 0;
this.currentScale = 0.6;
this.rotateScale();
if (this.$refs.singleImg) {
this.$refs.singleImg.style.left = 0;
this.$refs.singleImg.style.top = 0;
}
this.furl = furl;
this.changeColor = index;
if (
document.getElementsByClassName("originStyle") &&
document.getElementsByClassName("originStyle")[0] &&
document.getElementsByClassName("originStyle")[0].style
) {
document.getElementsByClassName("originStyle")[0].style.position =
"relative";
}
},
getQueryParams(val = 1) {
console.log(val)
//获取查询条件
let sqp = {}
if (this.superQueryParams) {
sqp['superQueryParams'] = encodeURI(this.superQueryParams)
sqp['superQueryMatchType'] = this.superQueryMatchType
}
var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters);
param.pageNo = this.ipaginationV.current;
if (this.$route.params.code) {
param.cameraCode = this.$route.params.code
}
param.pageSize = this.ipaginationV.pageSize;
param.xcGroup = this.curBuildingValue == 1 ? '' : this.curBuildingValue;
return filterObj(param);
},
async loadData(arg) {
this.confirmLoading = true
if (!this.url.list) {
this.$message.error('请设置url.list属性!')
return
}
if (this.SelctType == 'card') {
this.cardspinning = true
}
// 加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipaginationV.current = 1
}
var params = this.getQueryParams() // 查询条件
this.loading = true
try {
const res = await getAction(this.url.list, params, 20000)
if (res.success) {
const token = await Vue.ls.get(ACCESS_TOKEN)
// 确保 token 已经获取
if (!token) {
throw new Error('Token is missing')
}
this.confirmLoading = false
this.dataSource = [...this.dataSource, ...res.result.records]
console.log('dataSource', this.dataSource)
if (this.SelctType == 'card') {
this.cardspinning = false
}
if (res.result.total) {
this.ipaginationV.total = res.result.total
} else {
this.ipaginationV.total = 0
}
} else {
this.$message.warning(res.message)
}
} catch (error) {
console.error('Error loading data:', error)
} finally {
this.loading = false
}
},
handleCurrentChange(val) {
this.confirmLoading = true
const changeColor = this.changeColor + val;
if (changeColor === this.imgList.length || changeColor === -1) {
return;
}
console.log('changeColor', changeColor)
console.log('changeColor', this.imgList)
this.currentRotate = 0;
this.currentScale = 0.6;
this.rotateScale();
this.$refs.singleImg.style.left = 0;
this.$refs.singleImg.style.top = 0;
this.furl = this.imgList[changeColor];
this.changeColor = changeColor;
const noScroll = (val > 0 && changeColor <= 48) || (val < 0 && changeColor + 1 >= this.imgList.length - 48);
this.scrollImg(changeColor, noScroll);
},
handleCurrentChangeimg(val) {
const changeColor = this.changeColor + val;
if (changeColor === this.imgList.length || changeColor === -1) {
return;
}
this.currentRotate = 0;
this.currentScale = 0.6;
this.furl = this.imgList[changeColor];
this.changeColor = changeColor;
const noScroll = (val > 0 && changeColor <= 48) || (val < 0 && changeColor + 1 >= this.imgList.length - 48);
console.log('noScroll', noScroll)
console.log('val', val)
console.log('changeColor', changeColor)
if (noScroll) {
this.$refs.imgbox.style.transform = `translateX(-${val * 6}0px)`;
} else {
this.$refs.imgbox.style.transform = `translateX(${val * 6}0px)`;
}
if (val > this.imgList.length - 1) {
this.changeColor = -1;
}
},
scrollImg(val, noScroll) {
this.confirmLoading = false
console.log('val', noScroll)
console.log('scrollImg', noScroll)
if (noScroll) {
this.$refs.imgbox.style.transform = `translateX(-${val * 6}0px)`;
} else {
this.$refs.imgbox.style.transform = `translateX(${val * 6}0px)`;
}
if (val > this.imgList.length - 1) {
this.changeColor = -1;
}
},
start(e) {
//鼠标左键点击
e.preventDefault && e.preventDefault(); //去掉图片拖动响应
if (e.button == 0) {
this.canDrag = true;
//获取需要拖动节点的坐标
this.offset_x = document.getElementsByClassName(
"originStyle"
)[0].offsetLeft; //x坐标
this.offset_y = document.getElementsByClassName(
"originStyle"
)[0].offsetTop; //y坐标
//获取当前鼠标的坐标
this.mouse_x = e.pageX;
this.mouse_y = e.pageY;
}
},
move(e) {
e.preventDefault && e.preventDefault();
window.addEventListener("mousewheel", this.handleScroll, true) ||
window.addEventListener("DOMMouseScroll", this.handleScroll, false);
if (this.canDrag == true) {
let _x = e.pageX - this.mouse_x;
let _y = e.pageY - this.mouse_y;
//设置移动后的元素坐标
let now_x = this.offset_x + _x + "px";
let now_y = this.offset_y + _y + "px";
document.getElementsByClassName("originStyle")[0].style.position =
"absolute";
document.getElementsByClassName("originStyle")[0].style.top = now_y;
document.getElementsByClassName("originStyle")[0].style.left = now_x;
}
},
mouseLeave(e) {
this.canDrag = false;
window.removeEventListener("mousewheel", this.handleScroll, true) ||
window.removeEventListener("DOMMouseScroll", this.handleScroll, true);
},
stop(e) {
this.canDrag = false;
},
//旋转放大
rotateScale() {
if (!this.$refs.singleImg) {
return;
}
this.$refs.singleImg.style.Transform =
"rotate(" +
this.currentRotate +
"deg)" +
"scale(" +
this.currentScale +
")";
this.$refs.singleImg.style.webkitTransform =
"rotate(" +
this.currentRotate +
"deg)" +
"scale(" +
this.currentScale +
")";
this.$refs.singleImg.style.MozTransform =
"rotate(" +
this.currentRotate +
"deg)" +
"scale(" +
this.currentScale +
")";
this.$refs.singleImg.style.msTransform =
"rotate(" +
this.currentRotate +
"deg)" +
"scale(" +
this.currentScale +
")";
this.$refs.singleImg.style.transform =
"rotate(" +
this.currentRotate +
"deg)" +
"scale(" +
this.currentScale +
")";
},
//旋转
rotateL() {
this.currentRotate += 15;
this.rotateScale();
},
rotateR() {
this.currentRotate -= 15;
this.rotateScale();
},
//缩放 放大
scale(type) {
if (type >= 0) {
this.currentScale += 0.1;
this.rotateScale();
} else {
this.currentScale -= 0.1;
if (this.currentScale <= 0.1) {
this.currentScale = 0.1;
this.rotateScale();
} else {
this.rotateScale();
}
}
},
downloadIamge(imgsrc, name) {
//下载图片地址和图片名
var image = new Image();
// 解决跨域 Canvas 污染问题
image.src = imgsrc + "?v=" + Math.random(); // 处理缓存
image.crossOrigin = "*"; // 支持跨域图片
image.onload = function () {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
var url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
var a = document.createElement("a"); // 生成一个a元素
var event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || "img"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
};
},
download() {
this.downloadIamge(this.furl, new Date().getTime());
}
}
};
</script>
<style lang="less" scoped>
.picPreview {
.left_pre {
position: absolute;
top: -3px;
right: 0;
width: 55px;
font-size: 40px;
color: #ccc;
background: transparent;
border: 0;
outline: 0;
cursor: pointer;
}
.carousel-container {
width: 1000px;
height: 300px;
margin: 10px auto;
overflow: hidden;
position: relative;
}
.carousel {
width: 100%;
height: 100%;
display: flex;
transition: 0.5s;
}
.ctr-box {
display: flex;
justify-content: center;
align-content: center;
position: absolute;
bottom: 132px;
width: 300px;
justify-content: space-around;
}
/deep/ .ant-modal-footer {
border-top: 0;
.allImg {
width: 100%;
height: 60px;
margin-bottom: 10px;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
.changeImg {
height: 100%;
width: 50px;
cursor: pointer;
padding: 0;
border: 0;
i {
font-size: 60px;
}
&.right {
i {
bottom: 2px;
right: 7px;
position: relative;
}
}
}
.imgbox {
// width: 370px;
height: 100%;
overflow: hidden;
margin: 0 auto;
border: 1px solid #eee;
.imgbox-item {
display: flex;
align-items: center;
justify-content: start;
width: 100%;
height: 100%;
transition: 0.5s;
}
&.min {
justify-content: center;
}
img {
width: 50px;
height: 50px;
margin: 5px;
cursor: pointer;
}
.changeColor {
border: 2px solid #42b983;
}
}
}
}
/deep/ .ant-modal-body {
padding: 0 24px;
.originStyle {
// position: absolute;
left: 0;
top: 0;
cursor: pointer;
// transform-origin: 50% 50%;
}
#test_3 {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
border: 1px solid #eeeeee;
display: flex;
align-items: center;
justify-content: center;
img {
cursor: move;
display: inline-block;
vertical-align: middle;
}
}
}
}
</style>