0
点赞
收藏
分享

微信扫一扫

JQ+vue实现图片拼接(无限套娃版)

七千22 2022-03-24 阅读 16
css样式

   /* css初始化 */
        
        * {
            margin: 0;
            padding: 0;
        }
        /* 去掉li的小圆点 */
        
        li {
            list-style: none;
        }
        /* 去掉a的下划线 */
        
        a {
            text-decoration: none;
        }
        /* 搜索框去除边框 */
        
        input,
        button,
        select {
            border: 0;
            /* 设置背景颜色为透明 */
            background-color: transparent;
            /* 去掉外轮廓 */
            outline: none;
        }
        /* em和i标签字体样式 */
        
        em,
        i {
            font-style: normal;
        }
        /* 图片的空白间隙 */
        
        img {
            vertical-align: middle;
        }
        /* 清除浮动 */
        
        .clearfix:after {
            content: '';
            display: block;
            height: 0;
            clear: both;
            visibility: hidden;
        }
        /* 左浮动 */
        
        .fl {
            float: left;
        }
        /* 右浮动 */
        
        .fr {
            float: right;
        }
        
        body {
            background-color: #000;
            color: #fff;
        }
        
        .lay-box {
            display: flex;
        }
        
        .lay-left {
            flex: 0.5;
            margin-top: 2%;
            margin-top: 2%;
        }
        
        .lay-center {
            flex: 2.3;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-top: 10%;
            position: relative;
            flex-direction: column;
            min-height: 500px;
        }
        
        .lay-center-top {
            display: flex;
            width: 100%;
            height: 100%;
        }
        
        .lay-center-bottom {
            width: 100%;
            display: flex;
            justify-content: space-around;
            align-items: center;
            z-index: 1000000;
        }
        
        .lay-right {
            display: flex;
            flex-direction: column;
            flex: 0.2;
            margin-top: 2%;
            z-index: 100000;
        }
        
        .automatic,
        .manual {
            background-color: #22AF90;
            text-align: center;
            padding: 10px 0px;
            border-radius: 5px;
            width: 100%;
            cursor: pointer;
        }
        
        .automatic {
            margin-bottom: 20px;
        }
        
        .lay-centers {
            display: flex;
        }
        
        .lay-center-left,
        .lay-center-right {
            width: 100%;
            height: 100%;
        }
        
        .lay-center-leftimg,
        .lay-center-rightimg {
            width: 100%;
            height: 100%;
        }
        
        .lay-ui {
            display: flex;
        }
        
        .lay-left-contont .lay-ui .choice {
            margin-right: 10px;
        }
        
        .choiceclose {
            margin-right: 10px;
        }
        
        .choiceImg {
            width: 30%;
            height: 30%;
        }
        
        .lay-left-top {
            margin-bottom: 20px;
        }
        /*加载的样式*/
        
        .box {
            border-radius: 4px;
            height: 20px;
            width: 170px;
            background: #ebebeb;
            position: relative;
        }
        
        .box .line {
            background: rgb(92, 151, 4);
            height: 20px;
            text-indent: 999px;
        }
        
        .title {
            font-size: 18px;
            color: #000;
            margin-bottom: 20px;
        }
        
        .loadding {
            position: fixed;
            width: 14%;
            height: 12%;
            background: #fff;
            top: 50%;
            left: 50%;
            margin-top: -6%;
            margin-left: -7%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }
        
        #canvas {
            position: absolute;
            display: none;
        }
        
        #que,
        .clear,
        #undo {
            background-color: #22AF90;
            text-align: center;
            padding: 10px 0px;
            border-radius: 5px;
            width: 10%;
            cursor: pointer;
            display: none;
        }
        
        #imgnewtwo {
            display: none;
        }
        
        .lay-join-box {
            margin-top: 2%;
        }
        
        .lay-joint {
            display: flex;
            margin-top: 1%;
        }
        
        .error {
            margin-bottom: 50px;
            font-size: 18px;
        }
html结构
 <div class="loadding">
        <div class="title">正在拼接中,请稍后...</div>
        <div class="box">
            <div class="line" data-load="100"></div>
        </div>
    </div>
    <div class="lay-box" id='laybox'>
        <div class="lay-left">
            <div class="lay-left-contont">
                <!--默认展示的图片-->
                <div class="lay-ui" v-for="(item,index) in regList" :key='index'>
                    <input type="checkbox" class="choice" name="img" :data="item.imgurl" @click="specifiName(item.imgurl,item.imgdata),specifiNameMan(item.imgurl,item.imgdata,item.hid)" :uid="item.imgdata">
                    <img :src="item.imgurl" alt="" class='choiceImg'>
                </div>
                <!--拼接后的图片-->
                <div class='lay-join-box'>
                    <div class='joint-title'>已拼接</div>
                    <div class="lay-joint" v-for="(item,index) in jointList">
                        <input id='checkboxId1' type="checkbox" class="choice" name="img" :value="index" :data="item.imgurl" :oid="item.oid" :hid="item.hid" @click="specifiName(item.imgurl,item.imgdata,item.hid),specifiNameMan(item.imgurl,item.imgdata,item.hid)">
                        <img :src="item.imgurl" alt="" class='choiceImg'>
                        <button class="error" @click="clean(item.oid,index,item.hid)">×</button>
                    </div>
                </div>


            </div>
        </div>
        <div class="lay-center" id='laycenter'>
            <div class='lay-center-top' id="laycentertop">
                <canvas id="canvas" ref='canvas' @click="main($event)"></canvas>
                <!--手动拼接-->
                <div class="lay-centers" id="imgnewone">
                    <div class="lay-center-left" v-for="item in imgList">
                        <img :src="item" alt="" class='lay-center-leftimg'>
                    </div>
                </div>

                <!--自动拼接-->
                <div class="lay-center-left" id="imgnewtwo">
                    <!--手动拼接展示的图片-->
                    <img :src="bilgurl" alt="" class='lay-center-leftimg' id="manimg">
                    <!--自动拼接展示的图片-->
                    <img :src="bilgurlzi" alt="" class='lay-center-leftimg' id="autoimg">
                </div>
            </div>
            <div class='lay-center-bottom'>
                <button id="que" @click="determine">确定</button>
                <button class="clear" @click="clear">取消</button>
                <button id="undo" :disabled='prohibit' @click="redo">撤销</button>
            </div>


        </div>
        <div class="lay-right">
            <button class='automatic' @click="Automatic">自动拼接</button>
            <button class='manual' @click="Manual($event)">手动拼接</button>
        </div>
    </div>
js代码
 <script>
        $(document).ready(function() {
            var imgListone = []
            var imgListtwo = []
            var ManualimgListone = []
            var ManualimgListtwo = []
                //全局定义的数组
            var newList = []
                // 加载
            var step = 1, //加载基数
                status = 100, //加载步骤数
                $line = $('.line'),
                $lineVal = $line.text(),
                $attrVal = $line.data('load'), //进度条属性值
                $number = parseInt($('.numb').text()),
                $numberVal = parseFloat($number / status); //进度数值

            $line.css('width', $lineVal + '%'); //出事进度值

            function watchFn() {
                var self = $(this);
                var showVal = $attrVal / status;

                var numberHtml = parseInt($numberVal * step);

                //数值小于10让其显示小数点后面一位
                if ($number < 10) {
                    numberHtml = parseFloat($numberVal * step).toFixed(1);
                }

                //设置进度条、进度数值的样式/内容
                $line.css('width', showVal * step + '%');
                $('.numb').html(numberHtml);

                //基数大于步骤数清空定时器
                if (step >= status) {
                    clearInterval(timer);
                }

                step += 1;
            }
            //定时器,每个步骤15毫秒
            var timer = setInterval(watchFn, 60);

            // vue部分
            var app = new Vue({
                el: '#laybox',
                data: function() {
                    return {
                        regList: [], //默认展示的数组
                        //自动配准的数组
                        jointList: [], //拼接后的数组
                        checkboxId: [], //选中的复选框的id
                        //存放拼接后hid的数组(自动)
                        hidList: [],
                        //存放拼接后hid的数组(手动)
                        minhidList: [],
                        //手动配准的数组
                        ManId: [], //手动配准的数组
                        ManList: [], //手动配准的数组
                        imgList: [],
                        selectArr: [],
                        checkboxList: [], //选中的值
                        // 配准代码
                        clicks: 0,
                        lastClick: [0, 0],
                        //算法的坐标
                        coordinateA: [],
                        coordinateB: [],
                        // 撤销的数组
                        undoHistoryA: [],
                        a: {},
                        b: {},
                        prohibit: true,
                        x: 0,
                        y: 0,
                        trigter: true,
                        //自动配准的计时器
                        timer: null,
                        // 手动配准的计时器
                        timers: null,
                        //手动的接口图片
                        bilgurl: '',
                        //自动的接口图片
                        bilgurlzi: '',
                        ash: false, //是否置灰
                        oid: null,
                        str: '', //用于拼接(自动)
                        str1: '', //用于拼接(手动)
                        jointObj: {}, //放置拼接的对象
                        checkObj: {}, //放置没有
                        numIndex: null,
                        hid: 0, //最新的下标
                        axClick: 0, //接口调用的计次
                    }
                },
                mounted() {
                    this.regList = JSON.parse(localStorage.getItem("SplicList"))
                    $('.loadding').hide()
                },
                methods: {
                    //自动配准的数据
                    specifiName(item, id, hid) {
                        //自动配准的数组
                        this.checkboxList.push(item)
                        this.checkboxId.push(id)
                            //存放新增的hid
                        this.hidList.push(hid)
                        this.minhidList.push(hid)
                    },
                    //手动配准的代码
                    specifiNameMan(item, id, hid) {
                        //手动配准的数组
                        this.ManList.push(item)
                        this.ManId.push(id)
                            //存放新增的hid
                        this.minhidList.push(hid)
                        this.hidList.push(hid)
                    },
                    //清除
                    clean(id, index, hid) {
                        //自动拼接
                        //对应的下标
                        this.numIndex = index
                            //取出当前删除的图片oid,并进行对比
                        var oid = id
                        var newArr = oid.split('-')
                            //操作oid
                        var reelect = $("input[name='img']")
                        for (var i = 0; i < reelect.length; i++) {
                            if (reelect[i].checked == true) {
                                for (var j = 0; j < newArr.length; j++) {
                                    if (reelect[i].getAttribute('uid') == newArr[j]) {
                                        reelect[i].disabled = false
                                        reelect[i].checked = false
                                    }
                                }
                            }
                        }
                        //操作hid
                        for (var i = 0; i < reelect.length; i++) {
                            if (reelect[i].checked == true) {
                                for (var j = 0; j < this.hidList.length; j++) {
                                    if (reelect[i].getAttribute('hid') == hid) {
                                        reelect[i].disabled = false
                                        reelect[i].checked = false
                                    }
                                }
                            }
                        }

                        // 手动操作hid
                        for (var i = 0; i < reelect.length; i++) {
                            if (reelect[i].checked == true) {
                                for (var j = 0; j < this.minhidList.length; j++) {
                                    if (reelect[i].getAttribute('hid') == hid) {
                                        reelect[i].disabled = false
                                        reelect[i].checked = false
                                    }
                                }
                            }
                        }

                        this.jointList.splice(this.numIndex, 1)
                            //判断是否要清空其他元素
                        if (this.jointList.length == 0) {
                            this.bilgurlzi = ''
                            this.bilgurl = ''
                            this.axClick = 0
                            $('#autoimg').hide()
                            $('#manimg').hide()
                        }

                        //手动拼接
                    },
                    //自动配准
                    Automatic() {
                        $('#imgnewone').hide()
                        this.ManList = []
                        this.ManId = []
                        if (this.checkboxList.length < 2) {
                            alert('请选择两张图片')
                            return false
                        } else {
                            //置灰的判断
                            var reelect = $("input[name='img']")
                            for (var i = 0; i < reelect.length; i++) {
                                if (reelect[i].checked == true) {
                                    reelect[i].disabled = true
                                }
                            }
                            var canvas = document.getElementById("canvas")
                            context = canvas.getContext('2d');
                            context.clearRect(0, 0, canvas.width, canvas.height);
                            $('.loadding').show()
                                //自动配准接口
                            var newimg = ''
                            var newCheck = []
                            newCheck = this.checkboxId
                            var hid = 0
                            var imgNUm1 = this.checkboxList[0]
                            var imgNUm2 = this.checkboxList[1]
                            var imgNUm3 = this.checkboxList[2]
                            var imgNUm4 = this.checkboxList[3]
                            var imgNUm5 = this.checkboxList[4]
                            var imgNUm6 = this.checkboxList[5]
                            $.ajax({
                                type: "GET",
                                url: "http://www.nb.cn/Remote/Index/imageMosaic",
                                async: false,
                                data: {
                                    fisrtImage: imgNUm1,
                                    secondImage: imgNUm2,
                                    thirdImage: imgNUm3,
                                    fourthImage: imgNUm4,
                                    fifthImage: imgNUm5,
                                    sixthImage: imgNUm6
                                },
                                success: function(ret) {
                                    newimg = ret.data.fusion_image
                                    this.str = newCheck.join('-')
                                    hid++
                                    this.hid = hid
                                    let jointObj = {
                                        imgurl: newimg,
                                        oid: this.str,
                                        hid: this.hid
                                    }
                                    newList.push(jointObj)
                                    setTimeout(() => {
                                        $('.loadding').hide()
                                        $('#manimg').hide()
                                        $('#autoimg').show()
                                        $('#imgnewtwo').show()

                                    }, 800)
                                },
                            });
                            this.jointList = newList
                            this.checkboxId = []
                            this.checkboxList = []
                            this.jointList.forEach((item, index) => {
                                this.bilgurlzi = this.jointList[index].imgurl
                            });
                        }

                    },
                    //手动配准
                    Manual(e) {
                        $('#imgnewtwo').hide()
                        this.checkboxList = []
                        this.checkboxId = []
                        if (this.ManList.length != 2) {
                            alert('请选择两张图片')
                            return false
                        } else {
                            $('#que').show()
                            $('.clear').show()
                            $('#undo').show()
                            $('#canvas').show()
                            this.imgList = this.ManList
                            $('#imgnewone').show()
                            var canvas = document.querySelector('#canvas')
                            canvas.width = $('#laycenter').width()
                            canvas.height = $('#laycenter').height()
                        }
                    },
                    getCursorPosition(e) {
                        if (e.pageX != undefined && e.pageY != undefined) {
                            var rect = canvas.getBoundingClientRect();
                            this.x = e.clientX - rect.left * (canvas.width / rect.width);
                            this.y = e.clientY - rect.top * (canvas.height / rect.height);

                        }
                        return [this.x, this.y];
                    },
                    drawLine(e) {
                        var canvas = document.getElementById("canvas")
                        context = canvas.getContext('2d');
                        context.beginPath();
                        this.x = this.getCursorPosition(e)[0];
                        this.y = this.getCursorPosition(e)[1];
                        context.strokeStyle = '#f0f0f0';
                        if (this.trigter == true) {
                            const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
                            const compressed = pako.deflate(new Uint8Array(imageData
                                .data));
                            this.undoHistoryA.push(compressed);
                            this.trigter = false
                        }
                        context.arc(this.x, this.y, 2, 0, 2 * Math.PI)
                        context.stroke();


                        if (this.clicks != 1) {
                            this.clicks++;

                        } else {
                            context.moveTo(this.lastClick[0], this.lastClick[1]);
                            context.lineTo(this.x, this.y, 6);
                            context.strokeStyle = '#f0f0f0';
                            context.stroke();
                            this.clicks = 0;
                        }
                        this.lastClick = [this.x, this.y];
                        if (this.clicks == 0) {
                            const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
                            const compressed = pako.deflate(new Uint8Array(imageData
                                .data));
                            this.undoHistoryA.push(compressed);
                            this.prohibit = false
                            var x = this.x
                            var y = this.y
                            this.b = {
                                x,
                                y
                            }
                            this.coordinateB.push(this.b)

                        } else {

                            var x = this.x
                            var y = this.y
                            this.a = {
                                x,
                                y
                            }
                            this.coordinateA.push(this.a)
                        }
                    },
                    main(e) {
                        var canvas = document.getElementById('canvas')
                        this.drawLine(e)
                    },
                    redo() {
                        // 撤销
                        {
                            this.undoHistoryA.pop();
                            const compressed = this.undoHistoryA[this.undoHistoryA.length - 1]
                            this.coordinateA.pop()
                            this.coordinateB.pop()

                            try {
                                const decompressed = pako.inflate(compressed); // 解压
                                const uint8ClampedArray = new Uint8ClampedArray(decompressed);
                                const imageData = new ImageData(uint8ClampedArray, canvas.width, canvas
                                    .height);

                                context.putImageData(imageData, 0, 0);
                            } catch (error) {
                                console.error(error);
                            }
                            if (this.undoHistoryA.length === 0) {
                                this.prohibit = true;
                            }


                        }
                    },
                    determine() {
                        //置灰的判断
                        var reelect = $("input[name='img']")
                        for (var i = 0; i < reelect.length; i++) {
                            if (reelect[i].checked == true) {
                                reelect[i].disabled = true
                            }
                        }
                        if (this.coordinateA.length < 4 || this.coordinateB.length < 4) {
                            alert('最少标注四条线段')
                            return false
                        }
                        var imgNUm1 = this.imgList[0]
                        var imgNUm2 = this.imgList[1]
                        var newimg = ''
                        var newChecks = []
                        newChecks = this.ManId
                        var hids = 0
                        $('.loadding').show()
                        $.ajax({
                            type: "GET",
                            url: "http://www.nb.cn/Remote/Index/manualSplicing",
                            async: false,
                            data: {
                                fisrtImage: imgNUm1,
                                secondImage: imgNUm2,
                                fixedPoint: this.coordinateA,
                                movedPoint: this.coordinateB
                            },
                            success: function(ret) {
                                newimg = ret.data.fusion_image
                                this.str1 = newChecks.join('-')
                                hids++
                                this.hid = hids
                                this.jointObj = {
                                    imgurl: newimg,
                                    oid: this.str1,
                                    hid: this.hid
                                }
                                newList.push(this.jointObj)
                                setTimeout(() => {
                                    $('.loadding').hide()
                                }, 800)
                            },
                        });

                        // 数组id拼接
                        this.jointList = newList
                        this.ManId = []
                        this.jointList.forEach((item, index) => {
                            this.bilgurl = this.jointList[index].imgurl
                        });

                        $('#imgnewtwo').show()
                        $('#imgnewone').hide()
                            //按钮隐藏
                        $('#que').hide()
                        $('.clear').hide()
                        $('#undo').hide()
                        $('#canvas').hide()
                            //图片展示隐藏
                        $('#manimg').show()
                        $('#autoimg').hide()
                        this.ManList = []
                        this.ManId = []
                        context.clearRect(0, 0, canvas.width, canvas.height);
                    },
                    clear() {
                        var canvas = document.getElementById('canvas')
                        context = canvas.getContext('2d');
                        context.clearRect(0, 0, canvas.width, canvas.height);
                        this.imgList = []
                        $('#que').hide()
                        $('.clear').hide()
                        $('#undo').hide()
                        $('#canvas').hide()
                    }
                }
            })
        });
    </script>

数据可以自行模拟
引入了vue.js jquery.js pako.js

举报

相关推荐

0 条评论