vue中实现图片划线标注功能组件

该文章已生成可运行项目,
<div class="home">
  <canvas ref="canvas" :width="width" :height="height" @mousedown="initMouseDown"></canvas>
</div>
<script>
export default {
props: {
            //宽度
            width: {
                type: Number,
                default: 500
            },
            //高度
            height: {
                type: Number,
                default: 300
            },
            //背景图
            bgImage: {
                type: String,
                default: '/apps/CQHB/0.1.0/lib/images/a.jpg'
            },
            //线条颜色
            linColor: {
                type: String,
                default: '#498fd9'
            },
            //线条宽度
            linWidth: {
                type: Number,
                default: 1
            },
            // 线条指定文字
            // lineText: {
            //     type: String,
            //     default: '001LTF'
            // },
            //线条文字大小和字体
            lineTextSize: {
                type: String,
                default: '10px Arial'
            },
            //线条文本颜色
            lineTextColor: {
                type: String,
                default: '#ffff'
            },
            //文本背景颜色
            linTextBgColor: {
                type: String,
                default: '#498fd9'
            }
            // fromX: {
            //        type: String,
            //     default: ''
            // },
            // fromY: {
            //        type: String,
            //     default: ''
            // },
            // toX: {
            //        type: String,
            //     default: ''
            // },
            // toY: {
            //        type: String,
            //     default: ''
            // }
        },
        data() {
            return {
                context: null,
                startX: 0,
                startY: 0,
                drawing: false,
                lineText: '',
                backgroundImage: new Image() // 创建 Image 对象
            };
        },
        watch: {},
        mounted() {
            let obj = this.$parent.formflag;
            this.lineText = obj.sealPointNo;
            this.canvas = this.$refs.canvas;
            this.context = this.canvas.getContext('2d');
            // 设置背景图
            this.backgroundImage.src = this.bgImage; // 替换为你的背景图路径
            this.backgroundImage.onload = () => {
                this.drawBackground(); // 图片加载完成后绘制背景
                //如果有坐标位置信息  进行画线
                if (this.context && this.lineText && obj.fromX && obj.fromY && obj.toX && obj.toY) {
                    this.drawArrow(this.context, obj.fromX, obj.fromY, obj.toX, obj.toY);
                }
            };
        },
        methods: {
            //鼠标点下
            initMouseDown(event) {
                if (!this.$parent.imgLabel) return;
                this.startX = event.offsetX;
                this.startY = event.offsetY;
                this.drawing = true;
                document.addEventListener('mousemove', this.drawArrowOnMove);
                document.addEventListener('mouseup', this.stopDrawing);
            },
            //绘制背景图
            drawBackground() {
                this.context.drawImage(this.backgroundImage, 0, 0, this.canvas.width, this.canvas.height);
            },
            //鼠标移动
            drawArrowOnMove(event) {
                if (!this.drawing) return;
                const rect = this.canvas.getBoundingClientRect();
                const endX = event.clientX - rect.left;
                const endY = event.clientY - rect.top;
                // 清除整个画布,然后重新绘制背景图和箭头
                this.drawBackground();
                this.drawArrow(this.context, this.startX, this.startY, endX, endY);
            },
            //停止绘制
            stopDrawing() {
                this.drawing = false;
                document.removeEventListener('mousemove', this.drawArrowOnMove);
                document.removeEventListener('mouseup', this.stopDrawing);
            },
            //绘制线条&&箭头
            drawArrow(ctx, fromX, fromY, toX, toY, theta = 30, headlen = 10, width = this.linWidth, color = this.linColor) {
                const angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI;
                const angle1 = ((angle + theta) * Math.PI) / 180;
                const angle2 = ((angle - theta) * Math.PI) / 180;
                const topX = headlen * Math.cos(angle1);
                const topY = headlen * Math.sin(angle1);
                const botX = headlen * Math.cos(angle2);
                const botY = headlen * Math.sin(angle2);
                ctx.beginPath();
                // 绘制起点实心心圆
                ctx.fillStyle = 'red';
                ctx.strokeStyle = this.linColor; // 设置圆的线条颜色
                ctx.lineWidth = 0.5; // 设置圆的线条宽度
                ctx.arc(fromX, fromY, 2, 0, 2 * Math.PI); // 创建圆弧路径
                ctx.stroke(); // 使用stroke()方法绘制空心圆
                ctx.fill();
                //绘制线条
                ctx.moveTo(fromX, fromY);
                ctx.lineTo(toX, toY);
                // 绘制箭头
                // let arrowX = fromX - topX,
                //     arrowY = fromY - topY;
                // arrowX = toX + topX;
                // arrowY = toY + topY;
                // ctx.moveTo(arrowX, arrowY);
                // ctx.lineTo(toX, toY);
                // arrowX = toX + botX;
                // arrowY = toY + botY;
                // ctx.lineTo(arrowX, arrowY);
                //绘制文本背景颜色
                ctx.fillStyle = this.linTextBgColor; // 矩形背景颜色
                ctx.fillRect(toX - 2, toY, 42, 14); // 创建一个矩形背景
                // 绘制文本
                ctx.fillStyle = this.lineTextColor; //设置文本颜色
                ctx.font = this.lineTextSize; //设置字体大小和类型
                ctx.fillText(this.lineText, Number(toX) + 2, Number(toY) + 10); //在指定位置绘制文本+6防止线条挡住文字
                ctx.strokeStyle = color;
                ctx.lineWidth = width;
                ctx.stroke();
                let point = {
                    fromX,
                    fromY,
                    toX,
                    toY
                };
                this.$emit('on-change', point);
            }
        }
}
}
</script>
<style lang="less" scoped>
.canvasBox {
  width: 100%;
  margin-top: 10px;
  display: flex;
  justify-content: space-around;

  canvas {
    margin: 0 auto;
  }
}
</style>

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值