欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

平面图拖动标记,计数,保存

程序员文章站 2022-06-01 21:33:16
...
<template></template>
    <div class="plan-bg">
        <div class="btns">
            <el-col :span="4">
                <div>
                    <el-button type="cyan" icon="el-icon-edit" size="medium" @click="handleUpdateBuild"
                        v-hasPermi="['infra:building:edit']" v-if="!buildEdit">编辑</el-button>
                    <el-button type="cyan" icon="el-icon-folder-opened" size="medium"
                        v-hasPermi="['infra:building:edit']" v-if="buildEdit" @click="submitPlanInfo">保存
                    </el-button>
                    <el-button type="cyan" icon="el-icon-folder-opened" size="medium"
                        v-hasPermi="['infra:building:edit']" v-if="buildEdit" @click="cancelPlanInfo">取消
                    </el-button>
                </div>
            </el-col>
        </div>
        <div class="floor-plan">
            <div class="select-btn">
                <el-select v-model="floor" placeholder="请选择楼层" @change="changeFloor">
                    <el-option v-for="item in allFloorList" :key="item.floor" :value="item.floor" :label="item.name">
                    </el-option>
                </el-select>
                <el-upload v-show="buildEdit && floor" accept=".jpg, .png,.jpeg" :headers="upload.headers"
                    :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
                    :before-upload="beforeFileUpload" :on-change="uploadFileChange" :on-exceed="exceed"
                    :on-success="handleUploadSuccess" :auto-upload="true" list-type="picture" :show-file-list="false">
                    <el-button size="small">
                        上传照片
                        <i class="el-icon-upload el-icon--right"></i>
                    </el-button>
                </el-upload>
            </div>
            <div class="floor" id="canvas">
                <!-- <div style="width:20px;height:20px;background:#fff;float: right;" @click="initBoxDrag()"></div> -->
                <div class="floor-img" v-if="currentPicUrl">
                    <img ref="curImg" :src="currentPicUrl" />
                </div>
                <div class="menu-right" v-if="currentPicUrl && buildEdit && floor">
                    <el-select v-model="systemId" placeholder="请选择报警系统" @change="changeSystem">
                        <el-option v-for="item in systemList" :key="item.value" :value="item.value" :label="item.label">
                        </el-option>
                    </el-select>
                    <!-- <input v-myFocus="isInputChecked" class="edit" type="text" v-model="inputStr"
                        @keyup.13="inputNewIcon()" @blur="inputNewIcon()" placeholder="新增消防设备名称" /> -->

                    <el-button class="btn-add" @click="addNewIcon()">新增设备</el-button>
                    <!-- <div class="title-list">
                    <ul>
                        <li v-for="item of titleList">{{item.text}}</li>
                        <li>自定义名称</li>
                    </ul>
                </div> -->
                </div>
                <!-- <div class="btn" v-if="showImage">
                    <el-button @click="getBoxPosition">暂存</el-button>
                </div> -->
                <!-- <div class="box editIcon" ref="7" id="10007" v-if="showImage">
                <div><img class="icon-img" src="../../../assets/image/icon_hand.png" /></div>
                <div class="text" @dblclick="editIconName()">{{editTitle}}</div>
                <input v-myFocus="isInputChecked" v-if="isInputChecked" class="edit" type="text" v-model="inputStr"
                    @blur="inputNewIcon()" @keyup.13="inputNewIcon()" />
            </div> -->
            </div>
        </div>
        <!-- 添加或修改消防设备设备对话框 -->
        <el-dialog title="自定义设备" :visible.sync="addIconOpen" width="400px" append-to-body>
            <el-form ref="form" :model="form" :rules="rules" label-width="80px">
                <el-form-item label="设备类型" prop="deviceType">
                    <el-select v-model="form.deviceType" placeholder="请选择设备类型">
                        <el-option v-for="device in deviceTypeOptions" :key="device.value" :label="device.label"
                            :value="device.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="设备归属" prop="deviceOwner">
                    <el-select v-model="form.deviceOwner" placeholder="请选择设备归属">
                        <el-option v-for="item in deviceOwnerOptions" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="设备名称" prop="deviceName">
                    <el-input v-model="form.deviceName" placeholder="请输入设备名称" />
                </el-form-item>
                <el-form-item label="设备编码" prop="deviceCode">
                    <el-input v-model="form.deviceCode" placeholder="请输入设备编码" />
                </el-form-item>
                <el-form-item label="安装位置" prop="installPos">
                    <el-input v-model="form.installPos" placeholder="请输入设备安装位置" />
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="submitAddIcon">确 定</el-button>
                <el-button @click="cancelAddIcon">取 消</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
    import { handleEvent, handleInfo } from "@/api/biz/inspect/event";
    import { getToken } from "@/utils/auth";
    import {
        updateBuildPic,
        addBuildPic,
        getBuildPic,
        getAllBuildingDeviceInfo,
        getBuildingDeviceInfo,
        submitInfraBuildDevice,
        getAllNotPointList,
        getAllPointList,
        submitDetectorBatch
    } from "@/api/infra/building";
    import { addDevice, updateDevice } from "@/api/infra/device";
    import { fabric } from "fabric";
    import $ from "jquery";
    import { dragImg } from "@/views/biz/regiondetail/drag";
    import { context } from "@/views/biz/regiondetail/context";
    import iconSrc1 from "../../../assets/image/icon_smoke.png";
    import iconSrc2 from "../../../assets/image/icon_smoke2.png";
    import iconSrc3 from "../../../assets/image/icon_hand.png";
    import iconSrc4 from "../../../assets/image/icon_voice.png";
    import iconSrc5 from "../../../assets/image/icon_wind.png";
    import iconSrc6 from "../../../assets/image/icon_fire.png";
    import iconSrc7 from "../../../assets/image/icon_radio.png";
    import iconSrc8 from "../../../assets/image/icon_edit.png";

    export default {
        name: "regionPlan",
        props: {
            uploadSuc: Boolean,
            buildingId: {
                type: Number,
                default: null,
            },
            regionId: {
                type: Number,
                default: null,
            },
            overgroundCount: {
                default: null,
            },
            undergroundCount: {
                default: null,
            },
        },
        components: {},
        data() {
            return {
                buildEdit: false,
                allFloorList: [], // 所有楼层数
                curFloor: null, //可以保存的楼层数
                floor: null,
                /*平面图相关*/
                x0: 0,
                y0: 0,
                x1: 0,
                y1: 0,
                num: 0,
                canvasObj: null, //画布
                showImage: false,
                //自定义名称
                isInputChecked: false,
                inputStr: "",
                //带图片的层
                floorPic: [],
                //当前平面图
                currentPicUrl: "",
                currentPicId: null,
                // 报警系统
                systemId: 1,
                editTitle: "自定义名称",
                systemList: [{ value: 1, label: "火灾报警系统" }],
                titleList: [
                    { id: 1, text: "烟感" },
                    { id: 2, text: "手报" },
                    { id: 3, text: "声光报警器" },
                    { id: 4, text: "消火栓" },
                    { id: 5, text: "送风口" },
                    { id: 6, text: "广播" },
                ],
                // 用户导入参数图片
                upload: {
                    // 是否显示弹出层(用户导入)
                    open: false,
                    // 弹出层标题(用户导入)
                    title: "",
                    // 是否禁用上传
                    isUploading: false,
                    // 是否更新已经存在的用户数据
                    updateSupport: 0,
                    // 设置上传的请求头部
                    headers: { Authorization: "Bearer " + getToken() },
                    // 上传的地址
                    url: process.env.VUE_APP_BASE_API + "/system/minio/upload",
                },
                ///探测器///
                loadDetector: [
                    { deviceType: 2, text: "独立烟感", src: iconSrc2, initXAxis: 920, initYAxis: 60 },
                ],// 初始化探测器样式
                preDetectorList: [], //未标注的探测器的点
                imgDetectorList: [], //已经关联图的探测器的点
                allDetectorList: [], // 当前所有探测器点位信息
                // 初始化设备点样式
                loadData: [
                    {
                        deviceType: 1,
                        text: "烟感(部件)",
                        src: iconSrc1,
                        initXAxis: 920,
                        initYAxis: 60,
                    },
                    // { deviceType: 2, text: "独立烟感", src: iconSrc2, initXAxis: 1000, initYAxis: 60 },
                    // { deviceType: 3, text: "手报", src: iconSrc23 initXAxis: 1080, initYAxis: 60 },
                    // { deviceType: 4, text: "声光报警器", src: iconSrc4, initXAxis: 1160, initYAxis: 60 },
                    // { deviceType: 5, text: "消火栓", src: iconSrc5, initXAxis: 920, initYAxis: 60 },
                    // { deviceType: 6, text: "送风口", src: iconSrc6,  initXAxis: 1000, initYAxis: 140 },
                    // { deviceType: 7, text: "广播", src: iconSrc7, initXAxis: 1080, initYAxis: 140 },
                ],
                preIconList: [], //未标注的设备点
                imgIconList: [], //已经关联图的设备点
                dialogVisible: false,
                allBoxList: [], // 当前所有设备点位信息
                addIconOpen: false, //新增设备弹框
                //新增设备信息
                form: {},
                deviceTypeOptions: [{ value: 1, label: "火灾报警系统" }],
                deviceOwnerOptions: [{ value: 1, label: "火灾报警系统" }],
                // 表单校验
                rules: {
                    deviceType: [
                        { required: true, message: "设备编号类型", trigger: "blur" },
                    ],
                    deviceOwner: [
                        { required: true, message: "设备归属不能为空", trigger: "blur" },
                    ],
                    deviceCode: [
                        { required: true, message: "设备编号不能为空", trigger: "blur" },
                    ],
                    deviceName: [
                        { required: true, message: "设备名称不能为空", trigger: "blur" },
                    ],
                },
            };
        },
        created() {
            dragImg();
            this.getAllFloor();
            this.getFloorPic();
        },
        mounted: function () { },
        watch: {
            buildingId() {
                this.resetAllData();
                this.getAllFloor();
                this.getFloorPic();
            },
            undergroundCount() {
                this.getAllFloor();
            },
            overgroundCount() {
                this.getAllFloor();
            },
            floor() {
                if (this.floor === null) {
                    this.buildEdit = false;
                }
            },
        },
        directives: {
            myFocus: {
                update(el, binding) {
                    if (binding.value) {
                        el.focus();
                    }
                },
            },
        },
        methods: {
            resetForm() {
                this.form = {
                    deviceType: null,
                    deviceOwner: null,
                    deviceCode: null,
                    deviceName: null,
                    installPos: null,
                };
            },
            getFloorPic() {
                getBuildPic(this.buildingId).then((response) => {
                    this.floorPic = response.rows;
                });
            },
            getAllFloor() {
                this.allFloorList = [];
                for (let i = this.undergroundCount; i > 0; i--) {
                    let item = { floor: -i, name: "B" + i };
                    this.allFloorList.push(item);
                }
                for (let i = 1; i <= this.overgroundCount; i++) {
                    let item = { floor: i, name: i };
                    this.allFloorList.push(item);
                }
                // this.allFloorList.forEach((item)=>{
                //     this.floorPic.forEach((temp)=>{
                //         if(temp.floor===item.floor){
                //             item=temp;
                //         }
                //     })
                // })
            },
            新增设备相关
            addNewIcon() {
                this.addIconOpen = true;
            },
            editIconName() {
                this.isInputChecked = true;
                this.inputStr = this.editTitle;
            },
            submitAddIcon() {
                this.$refs["form"].validate((valid) => {
                    addDevice(this.form).then((response) => {
                        if (response.code === 200) {
                            this.msgSuccess("新增成功");
                            this.open = false;
                            let newIcon = {
                                text: this.form.deviceName,
                                src: iconSrc7,
                                initXAxis: 920,
                                initYAxis: 220,
                            };
                            this.loadData.push(newIcon);
                            this.createBox(newIcon);
                        }
                    });
                });
            },
            cancelAddIcon() {
                // 取消按钮
                this.addIconOpen = false;
            },
            inputNewIcon() {
                this.editTitle = this.inputStr;
                this.isInputChecked = false;
                if (!this.inputStr) {
                    return;
                }
                let newIcon = {
                    text: this.inputStr,
                    src: iconSrc7,
                    initXAxis: 920,
                    initYAxis: 220,
                };
                this.loadData.push(newIcon);
                this.createBox(newIcon);
            },
            resetAllData() {
                this.floor = null;
                this.currentPicUrl = "";
                this.systemId = 1;
                this.showImage = false;
                $("div").remove(".box");
                $("div").remove(".detector");
            },
            changeSystem() { },
            // 选择楼层时查看图片
            changeFloor(params) {
                if (this.buildEdit) {
                    this.$message.warning("切换楼层前请先保存!");
                    this.floor = this.curFloor;
                    return;
                }
                this.curFloor = this.floor;
                this.showImage = true;
                let curPicArr = this.floorPic.filter((item) => {
                    return item.floor == params;
                });
                if (curPicArr.length > 0) {
                    this.currentPicUrl = curPicArr[0].picUrl;
                    this.currentPicId = curPicArr[0].id;
                } else {
                    this.currentPicUrl = "";
                }
                // 清空当前标记点
                $("div").remove(".box");
                $("div").remove(".detector");
                this.initBoxDrag();
                this.initDetectorDrag();
                this.getBuildingDeviceInfo();
                this.getAllPointList();
            },
            /*楼层图片上传*/
            exceed() { },
            preview(file) { },
            uploadFileChange() { },
            beforeFileUpload() {
                if (!this.floor) {
                    this.$message.warning("请先选择楼层");
                }
            },
            handleUploadSuccess(res, file) {
                // 如果该楼层存在图片
                if (this.currentPicUrl) {
                    let params = {
                        buildingId: this.buildingId,
                        floor: this.floor,
                        picUrl: res,
                        id: this.currentPicId,
                    };
                    updateBuildPic(params).then((response) => {
                        if (response.code === 200) {
                            this.msgSuccess("修改平面成功");
                            this.currentPicUrl = file.url;
                            this.getFloorPic();
                        }
                    });
                } else {
                    let params = {
                        buildingId: this.buildingId,
                        floor: this.floor,
                        picUrl: res,
                    };
                    //如果该楼层原先不存在图片
                    addBuildPic(params).then((response) => {
                        if (response.code === 200) {
                            this.msgSuccess("新增平面图成功");
                            this.currentPicUrl = file.url;
                            this.getFloorPic();
                        }
                    });
                }
                this.uploadSuc = false;
                this.showImage = true;
            },
            //设备相关
            //获取待标记的设备
            getPreBuildingDeviceInfo() {
                this.preIconList = [];
                getAllBuildingDeviceInfo(this.buildingId, this.floor).then((response) => {
                    if (response.code === 200) {
                        let rows = response.rows;
                        this.loadData.forEach((temp) => {
                            temp["num"] = 0;
                            rows.forEach((item) => {
                                if (item.deviceType) {
                                    temp["num"]++;
                                    let newIcon = Object.assign(item, temp);
                                    this.preIconList.push(newIcon);
                                }
                            });
                        });
                        this.preIconList.forEach((item) => {
                            this.createBox(item);
                        });
                    }
                });
            },
            //获取已经标记的设备
            getBuildingDeviceInfo() {
                this.imgIconList = [];
                getBuildingDeviceInfo(this.buildingId, this.floor).then((response) => {
                    if (response.code === 200) {
                        let rows = response.rows;
                        this.loadData.forEach((temp) => {
                            rows.forEach((item) => {
                                if (temp.deviceType) {
                                    let newIcon = Object.assign(item, temp);
                                    this.imgIconList.push(newIcon);
                                }
                            });
                        });
                        this.imgIconList.forEach((item) => {
                            this.createBox(item);
                        });
                        //隐藏在图上的文字
                        $(".box").each(function () {
                            $(this).find(".text").hide();
                            $(this).css({'background-color' : 'transparent'});
                            $(this).find(".num").hide();
                        });
                    }
                });
            },
            initBoxDrag() {
                //初始化计数器
                //区块锁定标识
                var lock = false;
                let _this = this;
                // //右键菜单参数
                // context.init({
                //     fadeSpeed: 100,
                //     filter: function ($obj) { },
                //     above: 'auto',
                //     preventDoubleContext: true,
                //     compress: false
                // });
                //创建拖拽方法
                $("#canvas").on("mousedown", ".box", function (e) {
                    if (!_this.buildEdit) {
                        return;
                    }
                    var pos = $(this).position();
                    e.currentTarget.posix = { x: e.pageX - pos.left, y: e.pageY - pos.top };
                    let now = _this.loadData.filter((item) => {
                        return item.text == e.currentTarget.childNodes[1].outerText;
                    });
                    if (now.length > 0) {
                        e.currentTarget.initPos = {
                            left: now[0].initXAxis,
                            top: now[0].initYAxis,
                        }
                    }
                    $.extend(document, { move: true, move_target: e.currentTarget });
                    e.stopPropagation();
                });
            },
            createBox(data) {
                var imgId = data.id || "";
                var deviceType = data.deviceType || "";
                var deviceSn = data.deviceSn || "";
                var guid = data.guid || "";
                var deviceName = data.text || "";
                var initXAxis = data.initXAxis || 0;
                var initYAxis = data.initYAxis || 0;
                var distanceXAxis = data.distanceXAxis || 0;
                var distanceYAxis = data.distanceYAxis || 0;
                var src = data.src || "";
                var num = data.num || "";
                let _this = this;

                //更新计数器并记录当前计数
                var curNum = this.num++;
                //创建区域块,设备用box,探测器用detecter
                if (deviceType !== 2) {
                    var pos = $("#canvas").position();
                    var box = $(
                        '<div class="box" rel="' +
                        curNum +
                        '"  id="' +
                        deviceSn +
                        '"><div class="img-bg"><img class="icon-img" id="' +
                        imgId +
                        '" src="' +
                        src +
                        '"/></div><div id="' +
                        deviceType +
                        '" class="text">' +
                        deviceName +
                        '</div><div class="num">' + num + '</div></div>'
                    )
                        .css({
                            top: distanceYAxis > 0 ? distanceYAxis : initYAxis,
                            left: distanceXAxis > 0 ? distanceXAxis : initXAxis,
                        })
                        .appendTo("#canvas");
                } else {
                    var box = $(
                        '<div class="detector" rel="' +
                        curNum +
                        '"  id="' +
                        guid +
                        '"><div class="img-bg"><img class="icon-img" id="' +
                        imgId +
                        '"  src="' +
                        src +
                        '"/></div><div class="text content" >' +
                        deviceName +
                        '</div><div class="num">' + num + '</div></div>'
                    )
                        .css({
                            top: distanceYAxis > 0 ? distanceYAxis : initYAxis,
                            left: distanceXAxis > 0 ? distanceXAxis : initXAxis,
                        })
                        .appendTo("#canvas");
                }

                // //计算文本位置
                // box.find('.content').css({
                //     marginLeft: box.find('.content').width() / 2 * -1,
                //     marginTop: box.find('.content').height() / 2 * -1
                // });
                // //创建右键菜单
                // addContext('.box[rel=' + curNum + ']', [
                //     { header: '操作' },
                //     {
                //         text: '编辑设备名称', action: function (e) {
                //             e.preventDefault();
                //             _this.$prompt('输入设备名称', '提示', {
                //                 inputPlaceholder: '输入设备名称',
                //                 confirmButtonText: '确定',
                //                 cancelButtonText: '取消',
                //                 inputErrorMessage: '输入不能为空',
                //                 inputValidator: (value) => {       // 点击按钮时,对文本框里面的值进行验证
                //                     if (!value) {
                //                         return '输入不能为空';
                //                     }
                //                 },
                //                 callback: function (action, instance) {
                //                     if (action === 'confirm') {
                //                         console.log('instace', instance)
                //                         var curCont = $('.box[rel=' + curNum + '] .content');
                //                     } else {
                //                         that.$message({
                //                             type: 'info',
                //                             message: '取消驳回'
                //                         });
                //                     }
                //                 }
                //             })
                //         }
                //     },
                //     {
                //         text: '删除区域', action: function (e) {
                //             e.preventDefault();
                //             $('.box[rel=' + curNum + ']').remove();
                //         }
                //     },
                //     { divider: true },
                // ]);
            },
            getBoxPosition() {
                this.allBoxList = [];
                let _this = this;
                $(".box").each(function () {
                    var box = {};
                    box["id"] = Number($(this).find(".icon-img").attr("id"));
                    box["deviceCode"] = $(this).attr("id");
                    // box['deviceType'] = $(this).find('.text').text();
                    box["deviceType"] = Number($(this).find(".text").attr("id"));
                    box["distanceXAxis"] = $(this).position().left;
                    box["distanceYAxis"] = $(this).position().top;
                    box["buildingId"] = _this.buildingId;
                    box["floor"] = _this.floor;
                    _this.allBoxList.push(box);
                });
            },
            //编辑
            handleUpdateBuild() {
                if (this.floor === null) {
                    this.$message.warning("请先选择楼层!");
                    return;
                }
                this.buildEdit = true;
                this.getPreBuildingDeviceInfo();
                this.getAllNotPointList();
            },
            //取消
            cancelPlanInfo() {
                this.buildEdit = false;
            },
            //保存设备和探测器
            submitPlanInfo() {
                this.buildEdit = false;
                //获取当前图片宽高以过滤再图片上的点
                let curPicWidth = this.$refs["curImg"].width;
                let curPicHeight = this.$refs["curImg"].height;
                //提交设备点位信息
                this.getBoxPosition();
                let submitBoxList = this.allBoxList.filter((item) => {
                    return (
                        item.distanceXAxis < curPicWidth && item.distanceYAxis < curPicHeight
                    );
                });

                submitInfraBuildDevice(
                    submitBoxList,
                    this.buildingId,
                    this.floor
                ).then((res) => {
                    if (res.code === 200) {
                        //删除所有的box再重新获取刚刚保存的
                        $(".box").remove();
                        this.getBuildingDeviceInfo();
                    }
                });


            },
        },
    };
</script>
<style lang="scss" scoped>
    .avatar-uploader {
        border: 1px dashed #d9d9d9;
        margin-top: 20px;
        width: 200px;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
    }

    .avatar-uploader .el-upload:hover {
        border-color: #409eff;
    }

    .avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 178px;
        height: 178px;
        line-height: 178px;
        text-align: center;
    }

    .avatar {
        width: 178px;
        height: 178px;
        display: block;
    }

    .floor-plan {
        margin: 2% auto;
        width: 1400px;

        .select-btn {
            width: 100%;
            height: 40px;
        }

        .el-select {
            float: left;
        }

        /deep/.el-upload {
            margin-left: 30px;

            button {
                height: 40px;
                background-color: rgba(255, 255, 255, 0.08);
                color: rgba(255, 255, 255, 0.6) !important;
                border-color: rgba(255, 255, 255, 0.1);
            }

            button:hover {
                color: #409eff !important;
                border-color: #409eff;
            }
        }
    }

    .floor {
        height: 500px;
        width: 100%;
        position: relative;
        top: 20px;
    }

    .floor-img {
        position: absolute;
        left: 0px;
        top: 0px;
        z-index: 9;
        border: 2px dashed #ccc;
        padding: 0px;
        background: #fff;
        width: 860px;

        img {
            width: 100%;
            max-height: 480px;
        }
    }

    .menu-right {
        width: 30%;
        float: right;
        margin-right: 5%;

        .el-select {
            width: 46%;
            float: left;
            margin-right: 5%;
        }

        .btn-add {
            width: 32%;
            background-color: rgba(255, 255, 255, 0.08);
            outline: none;
            border: 1px solid rgba(255, 255, 255, 0.08);
            height: 40px;
            padding: 10px 15px;
            font-size: 14px;
            color: rgba(255, 255, 255, 0.8);
        }
    }

    .icon-list {
        display: flex;

        .icon {
            width: 10%;

            img {
                width: 100%;
            }
        }
    }

    .transparent {
        filter: alpha(opacity=50);
        -moz-opacity: 0.5;
        -khtml-opacity: 0.5;
        opacity: 0.5;
    }

    /* 
    .box,.detector {
        width: 200px;
        height: 100px;
        cursor: move;
        position: absolute;
        top: 30px;
        left: 30px;
        z-index: 99;
    } */

    .add-icon {
        top: 240px;
        left: 860px;
        position: absolute;
    }


    /* .box .content ,.detector .content{
        position: absolute;
        left: 50%;
        top: 50%;
        z-index: 99;
        text-align: center;
        font: bold 14px/1.5em simsun;
    }

    #debug {
        position: absolute;
        right: 10px;
        top: 10px;
        z-index: 88;
        border: 1px solid #ccc;
        width: 100px;
        height: 100px;
        background: #fff;
    } */

    #toolbar {
        position: absolute;
        left: 10px;
        top: 10px;
        z-index: 88;
    }

    /deep/.box,
    /deep/.detector {
        text-align: center;
        position: absolute;
        cursor: move;
        z-index: 99;
        background-color:#273142 ;

        .img-bg {
            width: 40px;
            height: 40px;
            border-radius: 20px;
            background: rgba(255, 255, 255, 0.08);
            text-align: center;
            line-height: 54px;
            margin:0 auto;
        }

        .icon-img {
            height: 24px;
        }

        .text {
            font-size: 14px;
            color: rgba(255, 255, 255, 0.8);
            margin-top: 6px;
        }

        .num {
            width: 20px;
            height: 20px;
            border-radius: 10px;
            color: #fff;
            font-size: 14px;
            line-height: 20px;
            background-color: tomato;
            position: absolute;
            top: 0;
            right: 2px;
        }
    }

    /* /deep/.detector {
        text-align: center;
        position: absolute;
        cursor: move;
        z-index: 99;

        .icon-img {
            height: 24px;
        }

        .text {
            font-size: 14px;
            color: rgba(255, 255, 255, 0.8);
            margin-top: 6px;
        }

        .num {
            width: 16px;
            height: 16px;
            border-radius: 8px;
            color: #fff;
            font-size: 14px;
            background-color: tomato;
            position: absolute;
            bottom: 0;
            right: -10px;
        }
    } */

    /* .el-button {
        position: absolute;
        right: 18%;
        bottom: 40px;
        background-color: #409eff;
        color: #fff;
        border: none;
    } */

    .title-list {
        ul {
            list-style: none;

            li {
                width: 70px;
                float: left;
                color: rgba;
            }
        }
    }

    /deep/ .el-input--medium .el-input__inner {
        height: 40px !important;
        background: rgba(255, 255, 255, 0.08) !important;
        border: 1px !important;
        text-align: left !important;
    }

    .btns {
        width: 1400px;
        margin: 0 auto 12px auto;
    }
</style>

需要引用jquery和一个自己写的drag.js
这是drag.js

import $ from 'jquery';
export function dragImg() {
  $(document).mousemove(function (e) {
    if (!!this.move) {
      var posix = !document.move_target ? {
          'x': 0,
          'y': 0
        } : document.move_target.posix,
        initPos = !document.move_target ? {
          'left': 0,
          'top': 0
        } : document.move_target.initPos,
        callback = document.call_down || function () {
          var posTop = e.pageY - posix.y,
            posLeft = e.pageX - posix.x;
          var canvas = $(this.move_target).parent();
          if (posTop < 0) {
            posTop = 0;
          } else if (posTop > canvas.innerHeight() - $(this.move_target).height()) {
            posTop = canvas.innerHeight() - $(this.move_target).height();
          }
          if (posLeft < 0) {
            posLeft = 0;
          } else if (posLeft > canvas.innerWidth() - $(this.move_target).width()) {
            posLeft = canvas.innerWidth() - $(this.move_target).width();
          }
          // 离开图层的时候回归原位置
          if (posLeft > 836) {
            $(this.move_target).css({
              'top': initPos.top,
              'left': initPos.left
            });
            $(this.move_target).find('.text').show();
            $(this.move_target).css({'background-color' : '#273142'});
            $(this.move_target).find('.num').show();
          } else {
            $(this.move_target).css({
              'top': posTop,
              'left': posLeft
            });
            $(this.move_target).find('.text').hide();
            $(this.move_target).css({'background-color' : 'transparent'});
            $(this.move_target).find('.num').hide();
          }
        };
      callback.call(this, e, posix);
      return false;
    }
  }).mouseup(function (e) {
    if (!!this.move) {
      var callback = document.call_up || function () {
        var allBox = $(this.move_target).parent().find('.box');
        var allDetector = $(this.move_target).parent().find('.detector');
        var curBox = [];
        var _thisMove = $(this.move_target);
        var allPoints = [];
        //筛选同类型下在图上的点,并计数
        if (allBox.length > 0) {
          allPoints = allBox;
        }
        if (allDetector.length > 0) {
          allPoints = allDetector;
        }
        for (var i = 0; i < allPoints.length; i++) {
          if (_thisMove.find('.text').text() ==
            allPoints[i].childNodes[1].outerText) {
            curBox.push(allPoints[i])
          }
        }
        var num = 0;
        for (var i = 0; i < curBox.length; i++) {
          if (curBox[i].offsetLeft > 836) {
            num++;
          }
        }
        for (var i = 0; i < curBox.length; i++) {
          curBox[i].childNodes[2].innerText = num;
        }
      };
      callback.call(this, e);
      $.extend(this, {
        'move': false,
        'move_target': null,
        'call_down': false,
        'call_up': false
      });
    }
  });
}

相关标签: 神奇的css js