实现拖拽圆点框处图片内容,并获取坐标

2019-08-15  本文已影响0人  ThemisHoo

功能如下,拖拽图中四个圆点,框出图片中身份证,并实时输出四个点相对于原图坐标位置。
(四点连线为不规则矩形)


实现拖拽圆点框处图片内容,并获取坐标

实现关键步骤

一.用canvas画出原图,并记录缩放比例
        let img = new Image()
        img.src = imgUrl
        img.onload = () => {
            this.setState({
                scale_width: img.width/800,
                scale_height: img.height/400
            })
            
            let c = document.getElementById('canvas')
            let ctx = c.getContext('2d')
            ctx.clearRect(0, 0, c.width, c.height) //清空画布
            ctx.drawImage(img, 0, 0, 800, 400) //绘制图片
二.画出四个点,实现拖动方法,记录拖动位置
<div
    className='left_bottom round'
    draggable
    onDragStart={(e)=>{this.dragStart('leftBottom', e)}}
    onDragEnd={(e)=>{this.dragEnd('leftBottom', e)}}></div>

// 拖拽开始
    dragStart = (position, e) => {
       // e.clientX 为拖动初始位置
 }
// 拖拽结束
    dragEnd = (position, e) => {
        // e.clientX 为拖动终止位置
        // 记录拖动位置, 重新渲染画布
    }
三.用canvas将四个点连线
 ctx.beginPath()
        ctx.moveTo(左上坐标)
        ctx.lineTo(右上坐标)
        ctx.lineTo(右下坐标)
        ctx.lineTo(左下坐标)
        ctx.lineTo(闭合)
        ctx.strokeStyle = 'red'
        ctx.stroke()
完整代码
export default class MarkPosition extends BaseComponent {
    constructor(props) {
        super(props);

        this.state = {
            imgUrl: Test,
            scale_width: 1,
            scale_height: 1, // 宽高比 初始值为1
            startX: 0,
            startY: 0, // 被移动点的初始位置 
            leftTop: [-5, -5],
            rightTop: [795, -5],
            leftBottom: [-5, 395],
            rightBottom: [795, 395],
        }
    }
    componentDidMount() {
        // 初始化 画布   画出图片和四个点开始位置
        this.drawImg()
    }
    // 第一步、将图片用canvas画出来
    drawImg = () => {
        const { imgUrl } = this.state
        let img = new Image()
        img.src = imgUrl
        img.onload = () => {
            this.setState({
                scale_width: img.width/800,
                scale_height: img.height/400
            })
            this.drawPoint(img)
        }
    }

    // 画四个位置点
    drawPoint = (img) => {
        const { leftTop, leftBottom, rightTop, rightBottom } = this.state

        // 第二步、画出图片 并缩放
        let c = document.getElementById('canvas')
        let ctx = c.getContext('2d')
        ctx.clearRect(0, 0, c.width, c.height) //清空画布
        ctx.drawImage(img, 0, 0, 800, 400) //绘制图片

        ctx.beginPath()
        ctx.moveTo(leftTop[0] + 5, leftTop[1] + 5)
        ctx.lineTo(rightTop[0] + 5, rightTop[1] + 5)
        ctx.lineTo(rightBottom[0] + 5, rightBottom[1] + 5)
        ctx.lineTo(leftBottom[0] + 5, leftBottom[1] + 5)
        ctx.lineTo(leftTop[0] + 5, leftTop[1] + 5)
        ctx.strokeStyle = 'red'
        ctx.stroke()
    }

    // 拖拽开始
    dragStart = (position, e) => {
        this.setState({
            startX: e.clientX,
            startY: e.clientY
        })
        
    }

    // 拖拽结束
    dragEnd = (position, e) => {
        const { startX, startY, leftTop, leftBottom, rightTop, rightBottom } = this.state
        console.log(startX, startY, leftTop, leftBottom, rightTop, rightBottom)
        let x = e.clientX - startX
        let y = e.clientY - startY // 计算 X Y 偏移量
        let width = 795
        let height = 395 // 元素宽高 减去 圆点半径

        // 处理四个点不能超过自己所在区域 
        if (position === 'leftTop') {
            x = leftTop[0] + Math.min(x, width);
            x = x > width / 2 ? x = width / 2 : x;
            y = leftTop[1] + Math.min(y, height);
            y = y > height / 2 ? y = height / 2 : y;
        }
        if (position === 'rightTop') {
            x = rightTop[0] + Math.max(x, -width);
            x = x < width / 2 ? x = width / 2 : x;
            y = rightTop[1] + Math.min(y, height);
            y = y > height / 2 ? y = height / 2 : y;
        }
        if (position === 'rightBottom') {
            x = rightBottom[0] + Math.max(x, -width);
            x = x < width / 2 ? x = width / 2 : x;
            y = rightBottom[1] + Math.max(y, -height);
            y = y < height / 2 ? y = height / 2 : y;
            
        }
        if (position === 'leftBottom') {
            x = leftBottom[0] + Math.min(x, width);
            x = x > width / 2 ? x = width / 2 : x;
            y = leftBottom[1] + Math.max(y, -height);
            y = y < height / 2 ? y = height / 2 : y;
        }

         // 限制四个点不能超过画布
         x = x < -5 ? -5 : x;
         y = y < -5 ? -5 : y;
         x = x > width ? width : x;
         y = y > height ? height : y;
         this.setState({
            [position]: [x, y]
        })
        
        // 给元素定位
        e.target.style.left = `${x}px`
        e.target.style.top = `${y}px`
        this.drawImg()
    }

    render() {
        const { leftTop, leftBottom, rightTop, rightBottom } = this.state
        return (
            <div className="process-content markposition-content">
                        <div className='markPic'>
                            <div
                                className='left_top round'
                                draggable
                                onDragStart={(e)=>{this.dragStart('leftTop', e)}}
                                onDragEnd={(e)=>{this.dragEnd('leftTop', e)}}></div>
                            <div
                                className='right_top round'
                                draggable
                                onDragStart={(e)=>{this.dragStart('rightTop', e)}}
                                onDragEnd={(e)=>{this.dragEnd('rightTop', e)}}></div>
                            <div
                                className='right_bottom round'
                                draggable
                                onDragStart={(e)=>{this.dragStart('rightBottom', e)}}
                                onDragEnd={(e)=>{this.dragEnd('rightBottom', e)}}></div>
                            <div
                                className='left_bottom round'
                                draggable
                                onDragStart={(e)=>{this.dragStart('leftBottom', e)}}
                                onDragEnd={(e)=>{this.dragEnd('leftBottom', e)}}></div>
                            <canvas id="canvas" width="800" height="400"></canvas>
                        </div>
                        <Row>
                            <Col span={6} className='posxy'>左上 X:{leftTop[0]} Y:{leftTop[1]}</Col>
                            <Col span={6} className='posxy'>右上 X:{rightTop[0]} Y:{rightTop[1]}</Col>
                            <Col span={6} className='posxy'>右下 X:{rightBottom[0]} Y:{rightBottom[1]}</Col>
                            <Col span={6} className='posxy'>左下 X:{leftBottom[0]} Y:{leftBottom[1]}</Col>
                        </Row>
            </div>
        )
    }
}

上一篇下一篇

猜你喜欢

热点阅读