vue相册展示功能

相册预览相关代码片段

在这里插入代码片
<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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值