canvas 绘制矩形

canvas 静态

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div style="display: flex;">
        <div style="width: 500px;height: 500px;border: 1px solid red;">
            <canvas id="canva" width="100%" height="100%"></canvas>
        </div>
        <br/>
        <div style="width: 500px;height: 500px;margin-left: 50px;border: 1px solid rgb(118, 57, 231);">
            <img id="img" width="400" height="400">
        </div>
    </div>
   
    <br/>
    <div style="width: 500px;height: 500px;border: 1px solid red;">
        <canvas id="canvasRef" width="100%" height="100%"></canvas>
    </div>
    
    <script>
        /**
         * canvas画布ref
        */
        let canRef = document.getElementById('canva'); 
        let ctx = canRef.getContext('2d');  // 获取2d上下文对象
        console.log(ctx,'ctx');

        /**
         * 绘制属性
        */
        ctx.fillStyle = 'black';  // 填充颜色
        ctx.fillRect(0,0,100,100);  // 填充坐标、宽高
        
        //ctx.strokeStyle = 'black';  // 描边颜色
        //ctx.strokeRect(0,0,100,100);  // 描边坐标、宽高

        /**
         * 展示绘制图像的ref(放大/缩小)
        */
        let imgRef = document.getElementById('img');
        var imgURL = canRef.toDataURL("image/png"); // 获取图像的数据URL 默认图片格式为png,也可以自定义设置格式。
        imgRef.src = imgURL

        /**
         * 外部图像的ref(放大/缩小)
        */
        let canvasRef = document.getElementById('canvasRef');
        let context = canvasRef.getContext('2d');  // 获取2d上下文对象

        var img = new Image();
        img.src = "photo.png";
        img.onload = function() {
            context.drawImage(img,10,10); // 使用drawImage绘制到画布上面
        }
       
    </script>
</body>
</html>

canvas 绘制多个矩形

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Canvas鼠标绘制</title>
    <style>
        canvas { border:1px solid #000; }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="400" height="300"></canvas>
    <div>
        <button type="button" onclick="clearCanvas()">清除画布</button>
    </div>
    <script>
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        
        canvas.addEventListener('mousedown', startDrawing);
        canvas.addEventListener('mousemove', draw);
        canvas.addEventListener('mouseup', stopDrawing);

        let startX;
        let startY;
        let overX;
        let overY;
        let rectList = []
            
        function startDrawing(event) {
            event.preventDefault();

            startX = event.clientX - canvas.offsetLeft
            startY = event.clientY - canvas.offsetTop
        }
       
        function draw(event) {
            if (event.buttons !== 1) return; // 只有当按下左键时才开始绘制

            ctx.strokeStyle = "black"; // 线条颜色为黑色
            ctx.lineWidth = 2; // 线条宽度为2像素
            
            ctx.clearRect(0,0,canvas.width,canvas.height)
            overX = event.offsetX - startX
            overY = event.offsetY - startY

            paintRect(startX, startY, overX, overY)
            rectList.forEach(v=>paintRect(v.p1, v.p2, v.p3, v.p4))
        }

        function paintRect(startX, startY, overX, overY) {
            ctx.save() // 将当前状态压入堆栈
            ctx.beginPath() // 创建新路径
            ctx.strokeRect(startX, startY, overX, overY); // 绘制填充了指定颜色的矩形
            ctx.restore() // 弹出堆栈上的顶级状态,将上下文恢复到该状态。
        }

        function stopDrawing() { 
            ctx.closePath(); // 停止路径
            rectList.push(JSON.parse(JSON.stringify({p1:startX, p2: startY,p3: overX,p4: overY})))
            console.log(rectList,'1');
            
            canvas.addEventListener('mousemove', draw);
        }

        // function clearCanvas() {  // 全部清除
        //     ctx.clearRect(0,0,canvas.width,canvas.height)
        // }
        function clearCanvas() { // 清除上一个
            if (rectList.length > 1) {
                rectList.pop()
            }
        }
    </script>
</body>
</html>

canvas 选择形状

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>跟随鼠标绘制矩形框</title>
    <style>
        #canvas {
            border: 1px solid red;
        }
    </style>
</head>

<body>
    <canvas id="canvas" width="640" height="480"></canvas>
    <select name="mode" id="mode">
        <option value="point">标记关键点</option>
        <option value="rect">绘制矩形框</option>
    </select>
    <button id="undo" onclick="undo()">撤销</button>


    <script>
        const canvas = document.getElementById('canvas'),
            context = canvas.getContext('2d'), //取得2D上下文对象
            pointArray = [],
            history = []

        let dragging = false,
            mode = 'point',
            mousedown = null



        function Point(x, y, type) {
            this.x = x
            this.y = y
            this.type = type // 左击 1  右击 3
        }

        // 坐标转化为canvas坐标
        function windowToCanvas(x, y, type) {
            //返回元素的大小以及位置
            var bbox = canvas.getBoundingClientRect();
            // bbox 的宽度会加上 canvas 的 border 会影响精度
            return new Point(x - bbox.left * (canvas.width / bbox.width),
                y - bbox.top * (canvas.height / bbox.height), type)
        }

        function drawPoint(point) {
            context.save()
            context.fillStyle = point['type'] === 3 ? 'red' : 'green'
            context.beginPath();
            context.arc(point.x, point.y, 3, 0, Math.PI * 2, true)
            context.fill()
            context.font = "20px serif";
            context.fillText((pointArray.length).toString(), point.x - 5, point.y - 10)
            context.restore()

            pointArray.push(point)
        }

        function updateRect(point) {
            let w = Math.abs(point.x - mousedown.x)
            let h = Math.abs(point.y - mousedown.y)

            let left = point.x > mousedown.x ? mousedown.x : point.x
            let top = point.y > mousedown.y ? mousedown.y : point.y

            context.save();
            context.beginPath();
            context.rect(left, top, w, h);
            context.stroke();
            context.restore();
        }

        function showLastHistory() {
            context.putImageData(history[history.length - 1]['data'], 0, 0)
        }

        function undo() {
            if (history.length > 1) {
                history[history.length - 1]['mode'] === 'point' && pointArray.pop()
                history.pop()
                showLastHistory()
            }
        }

        function addHistoy(data) {
            history.push({
                mode,
                data: context.getImageData(0, 0, canvas.width, canvas.height)
            })
        }

        document.getElementById('mode').onchange = function(e) {
            mode = e.target.value
        }

        // 鼠标事件
        canvas.onmousedown = function(e) {
            e.preventDefault();
            mousedown = windowToCanvas(e.clientX, e.clientY, e.which)
            dragging = true
        }

        canvas.onmousemove = function(e) {
            e.preventDefault();
            if (dragging && mode === 'rect') { // 只有绘制矩形框时有效果
                showLastHistory() // 每次绘制先清除上一次
                updateRect(windowToCanvas(e.clientX, e.clientY, e.which))
            }
        }
        addHistoy() // 添加一张默认的数据
        canvas.onmouseup = function(e) {
            e.preventDefault();
            dragging = false
            mode === 'point' && drawPoint(mousedown)
            addHistoy() // 保存上一次数据

        }
        // 阻止页面的右击菜单栏
        canvas.oncontextmenu = function(e) {
            e.preventDefault()
        }
    </script>
</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值