• vue下canvas绘制矩形


    起因:根据项目需求本人写了一个绘制矩形的组件。
    功能:在图片中绘制矩形,根据图片大小进行自适应展示,获取图片矩形坐标。
    思路:首先定义一个固定大小的DIV,DIV标签中有监测鼠标变化的四个事件mousedown,mousemove,mouseup,mouseleave。
    第二在DIV标签内有img,canvas两个标签,一个负责图片展示,一个负责绘制矩形。
    其中img与DIV标签的大小相当,canvas是根据DIV标签position定位的以保证鼠标事件在图片上绘制矩形不会有偏差。

    以下就是组件的全部代码和实现效果展示

    <template>
        <div id="customPositionDiv">
            <div style=" 1460px; height:740px;  background-color: #c0c0c0; 
                        margin:0 auto ; display:-webkit-box; 
                        -webkit-box-align:center; -webkit-box-pack:center; ">
                <div @mousedown="mousedown" @mousemove="mousemove"
                     @mouseup="mouseup" @Mouseleave="Mouseleave" :style="imgstyle">
                    <img :src="imgSrc" :style="imgstyle">
                    <canvas ref="table" :width="canvasWidth" :height="canvasHeight" :style="canvasstyle"></canvas>
                </div>
            </div>
            <div style=" 1450px;z-index: inherit;text-align: right ;margin:10px 0 0 0">
                <span slot="footer" class="dialog-footer">
                    <el-button @click="customClose">取 消</el-button>
                    <el-button type="primary" @click="customQuery">确 定</el-button>
                </span>
            </div>
        </div>
    
    </template>
    <style lang="scss">
    
    </style>
    <script>
    
        import vue from 'vue';
    
        export default {
            name: 'canvasDraw',
            props: ['imgSrc'],
            data() {
                return {
    
                    //  customPositionShow:false, //自定义位置
                    //   showclose:false,
                    startX: '',  //画画开始的X坐标
                    startY: '',  //画画开始的Y坐标
                    endX: '',    //画画结束的X坐标
                    endY: '',    //画画结束的Y坐标
                    isMouseDownInCanvas: '', //鼠标是否按下
                    customcxt: '',      // cxt
                    customR '',    //原图与展示图片的宽度比
                    customRheight: '',   //原图与展示图片的高度比
                    imgstyle: '',        //根据图片大小自适应样式
                    canvasstyle: '',     //根据图片大小canvas自适应样式 居中显示
                    canvasWidth: '',     //根据图片大小自适应canvas宽
                    canvasHeight: '',    //根据图片大小自适应canvas高
                    DivWidth: 1460,      //最大宽度
                    DivHeight: 740,      //最大高度
                };
            },
            watch: {
                'imgSrc': function () {
                    this.show();
                },
    
            },
            mounted() {
                this.show();
            },
    
            methods: {
                //取消时返回组件调用处所需的数据
                customClose() {
                    this.customcxt.clearRect(0, 0, this.DivWidth, this.DivHeight);
                    this.$emit('custom', { 'type': 1, 'data': '' });
                },
                //确定时返回组件调用处所需的数据
                customQuery() {
                    this.customcxt.clearRect(0, 0, this.DivWidth, this.DivHeight);
                    //根据绘制进行图片裁剪
    
                    //获取矩形框Left,Width'
                    let cLeft = 0;
                    let cWidth = 0;
                    if (this.startX > this.endX) {
                        cLeft = this.endX;
                        cWidth = this.startX - this.endX;
                    } else {
                        cLeft = this.startX;
                        cWidth = this.endX - this.startX;
                    }
    
                    //获取矩形框Top,Height
                    let cTop = 0;
                    let cHeight = 0;
                    if (this.startY > this.endY) {
                        cTop = this.endY;
                        cHeight = this.startY - this.endY;
                    } else {
                        cTop = this.startY;
                        cHeight = this.endY - this.startY;
                    }
    
                    var oMark = [];
                    oMark['offsetLeft'] = parseInt(cLeft / this.customRwidth);
                    oMark['offsetTop'] = parseInt(cTop / this.customRheight);
                    oMark['offsetWidth'] = parseInt(cWidth / this.customRwidth);
                    oMark['offsetHeight'] = parseInt(cHeight / this.customRheight);
    
                    this.$emit('custom', { 'type': 2, 'data': oMark });
                },
    
                // dialog展示自定义矩形框画板,
                // 计算img与canvas标签自适应图片的大小
                show() {
                    vue.nextTick(_ => {
                        let customCanvas = this.$refs.table;// canvas显示层
                        this.customcxt = customCanvas.getContext("2d");
                        let img = new Image();
                        img.src = this.imgSrc;
                        let that = this;
                        img.onload = function () {
    
                            let canvasleft = 0;
                            let canvastop = 0;
                            let WrH = img.width / img.height;             //图片宽高比
                            let RWrH = that.DivWidth / that.DivHeight;    //放置图片DIV的宽高比
                            let aa = 0;
                            // 根据宽高比大小判断确定自适应的宽和高
                            if (RWrH > WrH) {
                                aa = that.DivHeight / img.height;
                                that.canvasHeight = that.DivHeight;
                                that.canvasWidth = img.width * aa;
                                canvasleft = (that.DivWidth - that.canvasWidth) / 2
                            } else {
                                aa = that.DivWidth / img.width;
                                that.canvasHeight = img.height * aa;
                                that.canvasWidth = that.DivWidth;
                                canvastop = (that.DivHeight - that.canvasHeight) / 2
                            }
                            that.imgstyle = ' position: relative;  ' + that.canvasWidth 
                                          + ' px; height:' + that.canvasHeight + 'px'; //img浮动定位居中显示
                            that.customRwidth = that.canvasWidth / img.width; //原图与展示图片的宽高比
                            that.customRheight = that.canvasHeight / img.height;
    
                            that.canvasstyle = 'position: absolute;left: ' + canvasleft 
                                            + '; top: ' + canvastop + ';' //canvas浮动定位
    
                        };
                    })
    
                },
                //鼠标按下时执行
                mousedown(e) {
                    this.isMouseDownInCanvas = true;
                    // 鼠标按下时开始位置与结束位置相同 
                    // 防止鼠标在画完矩形后 点击图画形成第二个图形
                    this.endX = e.offsetX;
                    this.endY = e.offsetY;
                    this.startX = e.offsetX;
                    this.startY = e.offsetY;
                    this.mousemove(e)
    
                },
                //鼠标移动式时执行
                mousemove(e) {
                    if (this.isMouseDownInCanvas) { // 当鼠标有按下操作时执行
    
                        this.endX = e.offsetX;
                        this.endY = e.offsetY;
                        let wwidth = this.endX - this.startX;
                        let wheigth = this.endY - this.startY;
    
                        // 清除指定区域的所有像素
                        this.customcxt.clearRect(0, 0, this.DivWidth, this.DivHeight);
                        this.customcxt.strokeStyle = " #00ff00"; //矩形框颜色
                        this.customcxt.lineWidth = "2";  //矩形框宽度
                        this.customcxt.strokeRect(this.startX, this.startY, wwidth, wheigth);  //绘制矩形
    
                    }
                },
                //鼠标松开时执行
                mouseup(e) {
                    this.isMouseDownInCanvas = false;
                },
    
                Mouseleave(e) {
                    this.isMouseDownInCanvas = false
                },
            },
        }
    </script>







  • 相关阅读:
    MyEclipse 常用快捷键
    javaEE基础08
    MySql卸载重新安装出现Start service没有响应的解决办法(64位)
    javaSE基础07
    为WAMP中的mysql设置密码(默认为空)
    javaSE基础06
    javaSE基础05
    vue框架构建项目流程
    阿里云或本地部署服务器(一)---nginx本地和服务器代理
    修改vue element Transfer 穿梭框里内容区的宽度
  • 原文地址:https://www.cnblogs.com/luzt/p/11534453.html
Copyright © 2020-2023  润新知