<!DOCTYPE html>
<html>
<style>
    * {
        padding: 0;
        margin: 0;
    }

    #draw-canvas {
        display: block;
        margin: 0px auto;
    }
</style>

<body style="width:600px;height:400px">
    <canvas id="draw-canvas" width="100%" height="400px" style="border:1px solid #d3d3d3;">
        Your browser does not support the HTML5 canvas tag.
    </canvas>
    <!-- <button id="up">增大</button><button id="down">减小</button><button id="cancel">撤销</button><button
        id="clear">清空</button> -->
</body>
<script>
       var  x,y,w,h;
        class DrawRectangle {
            constructor(id, options) {
                this.canvas = document.getElementById(id); //canvas标签
                this.ctx = this.canvas.getContext('2d');
                this.currentR = null;  //单前点击的矩形框
                this.startX = 0;  //开始X坐标
                this.startY = 0;   //开始Y坐标
                this.endX = 0;    // 结束X坐标
                this.endY = 0;   // 结束Y坐标
                this.layers = options && options.layers || [];   //图层
                this.optype = 0; //op操作类型 0 无操作 1 画矩形框 2 拖动矩形框
                this.scale = 1;   //放大倍数
                this.scaleStep = 1.05;   //
                this.flag = false;  //是否点击鼠标的标志
                this.type = 0;     //鼠标移动类型
                this.topDistance = 0;     //
                this.leftDistance = 0;     //
                this.ratew = 1;
                this.rateh = 1;
                this.config = {
                    width: 600,
                    height: 400,
                    dashedColor: 'red',    //虚线颜色
                    solidColor: 'red',    //实线颜色
                    src: null,  //图片的路径
                }
                if (options) {
                    for (const key in options) {
                        this.config[key] = options[key]
                    }
                }
                this.setImageBackground(this.config.src);
                this.canvas.onmouseleave = ()=>
                {
                    this.canvas.onmousedown = null;
                    this.canvas.onmousemove = null;
                    this.canvas.onmouseup = null;
                }
                this.canvas.onmouseenter = ()=>
                {
                    this.canvas.onmousedown = this.mousedown.bind(this);
                    this.canvas.onmousemove = this.mousemove.bind(this);
                    document.onmouseup = this.mouseup.bind(this);
                }
            }

            init(cvw, cvh, imgw, imgh) {
                var item = this.layers[1];
                this.ratew = cvw / imgw;
                this.rateh = cvh / imgh;
                this.ctx.beginPath();
                this.startX = (item.x1) * this.ratew;
                this.startY = (item.y1) * this.rateh;
                this.endX = (item.x1) * this.ratew + (item.width) * this.ratew;
                this.endY = (item.y1) * this.ratew + (item.height) * this.rateh;
                this.ctx.rect(this.startX, this.startY, (item.width) * this.ratew, (item.height) * this.rateh);
                // this.ctx.rect(item.x1, item.y1, item.width, item.height);
                this.ctx.strokeStyle = item.strokeStyle;
                this.layers.splice(0, 1, this.fixPosition({
                    x1: Math.ceil(this.startX),
                    y1: Math.ceil(this.startY),
                    x2: Math.ceil(this.endX),
                    y2: Math.ceil(this.endY),
                    strokeStyle: this.config.solidColor,
                    type: this.type
                }));
                this.ctx.stroke();
                parent.document.getElementById('objectxy').value=Math.ceil(this.startX * this.ratew)+","+Math.ceil(this.startY * this.rateh)
                    +","+Math.ceil((this.endX-this.startX) * this.ratew)+","+Math.ceil((this.endY-this.startY) * this.rateh);
            }

            //设置图片为canvas的背景
            setImageBackground(src) {
                const img = new Image();
                img.src = src;
                img.onload = ()=>
                {
                    let
                        actImgW = img.width,
                        actImgH = img.height,
                        imgW = actImgW,
                        imgH = actImgH,
                        rate = 1,
                        left = 0,
                        top = 0,
                        canvasW = 600,
                        canvasH = 400;
                    //因为canvas画布的宽高固定，所以通过判断图片的宽高来进行缩放处理
                    if (actImgW > canvasW || actImgH > canvasH) {
                        if (actImgW / actImgH >= canvasW / canvasH) {
                            imgW = canvasW;
                            rate = actImgW / canvasW;
                            imgH = actImgH / rate;
                            top = (canvasH - imgH) / 2;
                        } else {
                            imgH = canvasH;
                            rate = actImgH / canvasH;
                            imgW = actImgW / rate;
                            left = (canvasW - imgW) / 2;
                        }
                    } else {
                        left = (canvasW - imgW) / 2;
                        top = (canvasH - imgH) / 2;
                    }
                    //this.ctx.drawImage(img, left, top, imgW, imgH);
                    //if (img.labelVos)
                    //drawRect(this.ctx, img, left, top, rate);
                    const _this = this;
                    //img.onload = ()=> {
                    _this.canvas.width = imgW;
                    _this.canvas.height = imgH;
                    _this.config.width = actImgW;
                    _this.config.height = actImgH;
                    _this.canvas.style.backgroundImage = "url(" + img.src + ")";
                    _this.canvas.style.backgroundSize = `${imgW}px ${imgH}px`;
                    _this.init(imgW, imgH, actImgW, actImgH);
                    // }


                }
            }

            //左侧拉伸展
            resizeLeft(rect) {
                this.canvas.style.cursor = "w-resize";
                if (this.flag && this.optype == 0) {
                    this.optype = 3;
                }
                if (this.flag && this.optype == 3) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.x1 = this.endX;
                    this.currentR.width = this.currentR.x2 - this.currentR.x1
                }
            }

            //上边框拉伸
            resizeTop(rect) {
                this.canvas.style.cursor = "s-resize";
                if (this.flag && this.optype == 0) {
                    this.optype = 4;
                }
                if (this.flag && this.optype == 4) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.y1 = this.endY;
                    this.currentR.height = this.currentR.y2 - this.currentR.y1;
                }
            }

            resizeWidth(rect) {
                this.canvas.style.cursor = "w-resize";
                if (this.flag && this.optype == 0) {
                    this.optype = 5;
                }
                if (this.flag && this.optype == 5) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.x2 = this.endX;
                    this.currentR.width = this.currentR.x2 - this.currentR.x1
                }
            }

            resizeHeight(rect) {
                this.canvas.style.cursor = "s-resize";
                if (this.flag && this.optype == 0) {
                    this.optype = 6;
                }
                if (this.flag && this.optype == 6) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.y2 = this.endY;
                    this.currentR.height = this.currentR.y2 - this.currentR.y1;
                }
            }

            resizeLT(rect) {
                this.canvas.style.cursor = "se-resize";
                if (this.flag && this.optype == 0) {
                    this.optype = 7;
                }
                if (this.flag && this.optype == 7) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.x1 = this.endX;
                    this.currentR.y1 = this.endY;
                    this.currentR.height = this.currentR.y2 - this.currentR.y1;
                    this.currentR.width = this.currentR.x2 - this.currentR.x1;
                }
            }

            resizeWH(rect) {
                this.canvas.style.cursor = "se-resize";
                if (this.flag && this.optype == 0) {
                    this.optype = 8;
                }
                if (this.flag && this.optype == 8) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.x2 = this.endX;
                    this.currentR.y2 = this.endY;
                    this.currentR.height = this.currentR.y2 - this.currentR.y1;
                    this.currentR.width = this.currentR.x2 - this.currentR.x1;
                }
            }

            resizeLH(rect) {
                this.canvas.style.cursor = "ne-resize";
                if (this.flag && this.optype == 0) {
                    this.optype = 9;
                }
                if (this.flag && this.optype == 9) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.x1 = this.endX;
                    this.currentR.y2 = this.endY;
                    this.currentR.height = this.currentR.y2 - this.currentR.y1;
                    this.currentR.width = this.currentR.x2 - this.currentR.x1;
                }
            }

            resizeWT(rect) {
                this.canvas.style.cursor = "ne-resize";
                if (this.flag && this.optype == 0) {
                    this.optype = 10;
                }
                if (this.flag && this.optype == 10) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.x2 = this.endX;
                    this.currentR.y1 = this.endY;
                    this.currentR.height = this.currentR.y2 - this.currentR.y1
                    this.currentR.width = this.currentR.x2 - this.currentR.x1
                }
            }

            reshow(x, y, changesmall) {
                let allNotIn = 1;
                let item = this.layers[0];
                this.ctx.beginPath();
                console.log(item.x1);
                this.ctx.rect(item.x1, item.y1, item.width, item.height);
                this.ctx.strokeStyle = item.strokeStyle;
                if (this.ctx.isPointInPath(x * this.scale, y * this.scale)) {
                    this.render(item);
                    allNotIn = 0;
                }
                this.ctx.stroke();
                if (this.flag && allNotIn && this.optype < 3) {
                    this.optype = 1;
                }
            }

            render(rect) {
                this.canvas.style.cursor = "move";
                if (this.flag && this.optype == 0) {
                    this.optype = 2;
                }
                if (this.flag && this.optype == 2) {
                    if (!this.currentR) {
                        this.currentR = rect
                    }
                    this.currentR.x2 += this.endX - this.leftDistance - this.currentR.x1;
                    this.currentR.x1 += this.endX - this.leftDistance - this.currentR.x1;
                    this.currentR.y2 += this.endY - this.topDistance - this.currentR.y1;
                    this.currentR.y1 += this.endY - this.topDistance - this.currentR.y1;
                }
            }

            isPointInRetc(x, y) {
                let len = this.layers.length;
                for (let i = 0; i < len; i++) {
                    if (this.layers[i].x1 < x && x < this.layers[i].x2 && this.layers[i].y1 < y && y < this.layers[i].y2) {
                        return this.layers[i];
                    }
                }
            }

            fixPosition(position) {
                if (position.x1 > position.x2) {
                    let x = position.x1;
                    position.x1 = position.x2;
                    position.x2 = x;
                }
                if (position.y1 > position.y2) {
                    let y = position.y1;
                    position.y1 = position.y2;
                    position.y2 = y;
                }
                position.width = position.x2 - position.x1
                position.height = position.y2 - position.y1
                return position
            }

            mousedown(e) {
                // if ($("#changewidthnot").val() == "1") {
                    this.startX = (e.pageX - this.canvas.offsetLeft) / this.scale;
                    this.startY = (e.pageY - this.canvas.offsetTop) / this.scale;
                    this.currentR = this.isPointInRetc(this.startX, this.startY);
                    if (this.currentR) {
                        this.leftDistance = this.startX - this.currentR.x1;
                        this.topDistance = this.startY - this.currentR.y1;
                    }
                    this.ctx.strokeRect(this.endX, this.endY, 0, 0);
                    this.ctx.strokeStyle = this.config.dashedColor;
                    this.flag = 1;
                }
            // }

            mousemove(e) {
                // if ($("#changewidthnot").val() == "1") {
                    this.endX = (e.pageX - this.canvas.offsetLeft) / this.scale;
                    this.endY = (e.pageY - this.canvas.offsetTop) / this.scale;
                    // console.log(`mousemove`, this.endX, this.endY);
                    this.ctx.save();
                    this.ctx.setLineDash([5])
                    this.canvas.style.cursor = "crosshair";
                    this.ctx.clearRect(0, 0, this.config.width, this.config.height);
                    if (this.flag && this.optype == 1) {
                        this.ctx.strokeRect(this.startX, this.startY, this.endX - this.startX, this.endY - this.startY);

                    }
                    this.ctx.restore();
                    this.reshow(this.endX, this.endY, "1");
                }
            // }

            mouseup(e) {
                // if ($("#changewidthnot").val() == "1") {
                    if (this.optype == 1) {
                        this.layers.splice(0, 1, this.fixPosition({
                            x1: this.startX,
                            y1: this.startY,
                            x2: this.endX,
                            y2: this.endY,
                            strokeStyle: this.config.solidColor,
                            type: this.type
                        }))
                        var ratew = this.config.width / this.canvas.width;
                        var rateh = this.config.height / this.canvas.height;

                        this.layers.splice(1, 1, this.fixPosition({
                            x1: Math.ceil(this.startX * ratew),
                            y1: Math.ceil(this.startY * rateh),
                            x2: Math.ceil(this.endX * ratew),
                            y2: Math.ceil(this.endY * rateh),
                            strokeStyle: this.config.solidColor,
                            type: this.type
                        }));
                        parent.document.getElementById('objectxy').value=Math.ceil(this.startX * this.ratew)+","+Math.ceil(this.startY * this.rateh)
                            +","+Math.ceil((this.endX-this.startX) * this.ratew)+","+Math.ceil((this.endY-this.startY) * this.rateh);

                    } else if (this.optype >= 3) {
                        this.fixPosition(this.currentR);
                    }
                    this.currentR = null;
                    this.flag = 0;
                    this.reshow(this.endX, this.endY);
                    this.optype = 0;
                // }
            }
        }
        init();
        function  init() {
            var  objectxywh=parent.document.getElementById('objectxy').value;
            if(""!=objectxywh && undefined!=objectxywh){
                pointvalue=objectxywh.split(',');
                if(pointvalue.length==4) {
                    x = parseInt(pointvalue[0]);
                    y = parseInt(pointvalue[1]);
                    w=parseInt(pointvalue[2]);
                    h=parseInt(pointvalue[3]);
                }

            }

        }


        draw = new DrawRectangle('draw-canvas', {
            src:'http://zjh189.ncpoi.cc:7180/download/202108/16/33050300001327599605/33050300001327599605_20210816_231137723.jpg',
            layers: [{},
                {
                    "x1":x,
                    "y1": y,
                    "x2": x+w,
                    "y2": y+h,
                    "width": w,
                    "height": h,
                    "strokeStyle": "red",
                    "type": 0
                }
            ]
        });
</script>

</html>