vue下canvas繪制矩形


起因:根據項目需求本人寫了一個繪制矩形的組件。
功能:在圖片中繪制矩形,根據圖片大小進行自適應展示,獲取圖片矩形坐標。
思路:首先定義一個固定大小的DIV,DIV標簽中有監測鼠標變化的四個事件mousedown,mousemove,mouseup,mouseleave。
第二在DIV標簽內有img,canvas兩個標簽,一個負責圖片展示,一個負責繪制矩形。
其中img與DIV標簽的大小相當,canvas是根據DIV標簽position定位的以保證鼠標事件在圖片上繪制矩形不會有偏差。

以下就是組件的全部代碼和實現效果展示

<template>
    <div id="customPositionDiv">
        <div style="width: 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="width: 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
                customRwidth: '',    //原圖與展示圖片的寬度比
                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;  width:' + 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>

 

 









免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM