vue实现canvas画布建立图片,坐标建立,可进行拖拽,鼠标中心点位缩放,标记点位等功能

直接上源码

<!--  -->
<template>
    <div class="canvas-box" ref="canvasBox">
        <img ref="bitmap" :src="imageurl" style="display: none;" />
        <canvas ref="mycanvas" :width="canvaswidth" :height="canvasheight" style="transition:all .3s"
            @mousedown="onmousedown" @mouseup="onmouseup" @mousemove="onmousemove" @mousewheel="onmousewheel"></canvas>
    </div>
</template>

<script>
import { reactive, toRefs } from 'vue'
export default {
    props: {
        imageurl: {
            Type: String,
            default: ""
        },
        tablelist: {
            Type: Array,
            default: []
        }
    },
    data() {
        return {
            canvaswidth: 1497,
            canvasheight: 828,
            mycanvas: null,
            canvasinfo: {
                initialzoom: 1,
                //每次增加多少倍
                everyzoom: 0.1,
                //图片初始位置
                imginitx: 0,
                imginity: 0,
                offset: {
                    x: 0,
                    y: 0
                },
                //鼠标进入离开拖动状态标记
                mousestatus: 0
            },
            imageinfo: {
                width: 0,
                height: 0
            },
            imageinitzoom: 0,
            img: null,
            //记录坐标原点位置
            origin: {
                x: 0,
                y: 0
            }
        }
    },
    created() {
    },
    mounted() {
        this.mycanvas = this.$refs.mycanvas.getContext('2d');

        this.loadImage();
    },
    methods: {
        //加载图片在canvas上
        loadImage() {
            let _this = this;
            _this.bitmap = _this.$refs.bitmap;
            _this.img = _this.bitmap;
            _this.bitmap.onload = (res) => {
                //先计算原图初始宽高,赋值图片适应图层缩放比例
                _this.calculation(res);
                //图片加载完成后绘制在canvas上面
                _this.drawImage();
            };
        },
        //开始绘制canvas
        drawImage() {
            this.mycanvas.clearRect(0, 0, this.canvaswidth, this.canvasheight);
            this.mycanvas.drawImage(this.img, this.canvasinfo.imginitx, this.canvasinfo.imginity, this.imageinfo.width / this.imageinitzoom * this.canvasinfo.initialzoom, this.imageinfo.height / this.imageinitzoom * this.canvasinfo.initialzoom);
            debugger;
            this.addpoint();
        },

        addpoint() {
            let _this = this;
            let iconimg = new Image();
            iconimg.src = require('@/assets/broadcast/111.png');
            iconimg.onload = (res) => {
                for (let i = 0; i < _this.tablelist.length; i++) {
                    // 将x,y坐标转化为相对图层坐标
                    let iconx = _this.tablelist[i].devPx  / (_this.imageinitzoom/this.canvasinfo.initialzoom) + _this.canvasinfo.imginitx;
                    let icony = (_this.origin.y - _this.tablelist[i].devPy) / (_this.imageinitzoom/this.canvasinfo.initialzoom) + _this.canvasinfo.imginity;
                    _this.mycanvas.drawImage(iconimg, iconx-res.target.width/2, icony-res.target.height/2, res.target.width, res.target.height);
                }
            };
            iconimg.onerror = (res) => {
                debugger;
            }
        },

        //计算要建立的坐标原点,并计算图片相对于图层缩小倍数
        calculation(res) {
            if (res.target.height > this.canvasheight) {
                this.imageinitzoom = res.target.height / this.canvasheight;
            } else {
                this.imageinitzoom = res.target.width / this.canvaswidth;
            }
            if (this.imageinitzoom < this.canvasinfo.initialzoom) {
                this.imageinitzoom = this.canvasinfo.initialzoom;
            }
            this.imageinfo.width = res.target.width;
            this.imageinfo.height = res.target.height;
            this.origin.x = this.canvasinfo.imginitx;  //原点坐标x为相对left的偏移量
            this.origin.y = res.target.height + this.canvasinfo.imginity;  //原点坐标y为图片的高度+相对top的偏移量   
        },
        /** 记录画面鼠标的位置 */
        getMousePosition(e) {
            return {
                x: e.offsetX,
                y: e.offsetY
            }
        },
        //鼠标按下操作
        onmousedown(e) {
            this.canvasinfo.mousestatus = 1 // 记录鼠标进入1状态
            this.canvasinfo.offset = this.getMousePosition(e) // 记录鼠标的坐标点
        },
        onmouseup(e) {
            this.canvasinfo.mousestatus = 0 // 记录鼠标进入1状态
        },
        onmousemove(e) {
            console.log("x:" + Math.floor((e.offsetX - this.canvasinfo.imginitx) * this.imageinitzoom / this.canvasinfo.initialzoom) + "------ y:" + Math.floor(this.origin.y - ((e.offsetY - this.canvasinfo.imginity) * this.imageinitzoom / this.canvasinfo.initialzoom)));
            if (this.canvasinfo.mousestatus === 1) {
                this.canvasinfo.imginitx += (e.offsetX - this.canvasinfo.offset.x);
                this.canvasinfo.imginity += (e.offsetY - this.canvasinfo.offset.y);
                this.canvasinfo.offset = this.getMousePosition(e)
                this.drawImage();
            }
        },
        onmousewheel(e) {
            //计算偏移量来进行缩放,如果鼠标位置不动,e.offsetX要保持不变
            let changex = (e.offsetX - this.canvasinfo.imginitx) / this.canvasinfo.initialzoom * this.canvasinfo.everyzoom;
            let changey = (e.offsetY - this.canvasinfo.imginity) / this.canvasinfo.initialzoom * this.canvasinfo.everyzoom;
            this.canvasinfo.offset = this.getMousePosition(e)
            if (e.wheelDelta > 0) {
                this.canvasinfo.initialzoom += this.canvasinfo.everyzoom;
                this.canvasinfo.imginitx -= changex;
                this.canvasinfo.imginity -= changey;

            } else {
                if (parseInt(this.canvasinfo.initialzoom * 100) / 100 > this.canvasinfo.everyzoom) {
                    this.canvasinfo.initialzoom -= this.canvasinfo.everyzoom;
                    this.canvasinfo.imginitx += changex;
                    this.canvasinfo.imginity += changey;
                }
            }
            this.drawImage();
        }
    },
};
</script>
<style ref="stylecscc/scss" lang="scss" scoped>
.canvas-box {
    background: #03333f;
}
</style>

仅供学习使用

Logo

前往低代码交流专区

更多推荐