巧用canvas实现画板功能,使用画笔在图片上涂画,橡皮擦可擦除涂画,并保存

canvas 是HTML5的元素,使用JavaScript 在网页上绘制图像。

canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。

而如果想实现画笔在画板涂画画笔在图片上涂画,橡皮擦可擦除涂画,就需要两个canvas画布配合。

原理就是两个一样大小的canvas画布重叠放置,并且都绘制这个图画,这样只在上面的canvas涂画、擦除,擦除时把下层canvas内容替换上层的canvas内容,达到模仿橡皮擦效果。

下面就是具体实现代码:

1、先准备画布和工具:

<canvas id="canvas1" width="600" height="500"></canvas>
<canvas id="canvas2" width="600" height="500"></canvas>
<div class="tooltip-pen">
    <b>
        <i class="ico ico-pen" title="铅笔" onclick="changeTools('pen');"></i>
        <i class="ico ico-eraser" title="橡皮檫" onclick="changeTools('eraser');"></i>
        <i class="ico ico-save" title="保存" onclick="downloadImg();"></i>
    </b>
</div>

2、画布、工具样式,以便正常显示、使用:

<style>
    #canvas1{position: absolute;background-image: url("./image/20200108173011.jpg");z-index: 997;}
    #canvas2{position: absolute;background-image: url("./image/20200108173011.jpg");z-index: 998;}
    .tooltip-pen{position: fixed;width: 40px;height: 125px;top: 5%;left: 650px;z-index: 999;background-color: #737373;border-radius: 5px;}
    .ico{display: inline-block;width: 40px;height: 40px;}
    .ico-pen {background-image: url("./image/pencil.png");background-size: 100% 100%;background-repeat: no-repeat;background-position: top center;}
    .ico-eraser {background-image: url("./image/eraser.png");background-size: 100% 100%;background-repeat: no-repeat;background-position: top center;}
    .ico-save{background-image: url("./image/save.png");background-size: 100% 100%;background-repeat: no-repeat;background-position: top center;}
</style>

3、重点是JS控制涂画、擦除:

原理就是通过获取鼠标移动轨迹(移动位置:x坐标,y坐标),在画布上创建这段轨迹的线条。

<script>
    var canvas1 = document.getElementById("canvas1");
    var canvas2 = document.getElementById("canvas2");
    var cs2Ctx = canvas2.getContext("2d");
    var cs1Ctx = canvas1.getContext("2d");
    // --------- 画笔和橡皮擦功能实现 -------------
    var flag = false;  // 记录鼠标按下和抬起事件,标记工具是否开始工作
    var isEraser; // 判断工具是画笔还是橡皮擦
    var lineWidth = 3; // 设置工具粗细

    // 设置画笔颜色
    var theColor = "#FF0000";
    theColor.onchange = function(){
        cs2Ctx.strokeStyle = this.value;
    }
    // 切换工具
    function changeTools(tname) {
        if (tname == 'eraser') {
            isEraser = true;
            lineWidth = 30;
            $(canvas2).css({ 'cursor': "url('./image/eraser_ss.png'),default" }); // 设置橡皮擦自定义鼠标样式
        } else if (tname == 'pen') {
            isEraser = false;
            lineWidth = 3;
            $(canvas2).css({ 'cursor': 'crosshair' }); // 设置画笔系统鼠标样式(十字)
        }
    }
    // onmousedown事件
    canvas2.onmousedown=function(eva){
        var eva = eva||window.event;
        cs2Ctx.lineCap = "round";
        cs2Ctx.lineJoin = "round";
        var x = eva.offsetX;
        var y = eva.offsetY;
        cs2Ctx.beginPath();
        cs2Ctx.moveTo(x,y);
        flag = true;
        cs2Ctx.lineWidth = lineWidth;
        cs2Ctx.strokeStyle = "#FF0000";
    }
    // onmousemove事件
    canvas2.onmousemove=function(eva){
        if(flag){
            if(isEraser){
                var w = lineWidth;
                // noinspection JSAnnotator
                let pxs = cs1Ctx.getImageData(eva.offsetX-w/2, eva.offsetY-w/2, w, w);
                cs2Ctx.putImageData(pxs, eva.offsetX-w/2, eva.offsetY-w/2);
            } else{
                var eva = eva||window.event;
                var x = eva.offsetX;
                var y = eva.offsetY;
                cs2Ctx.lineTo(x,y);
                cs2Ctx.stroke();
            }
        }
    }
    // onmouseup事件
    canvas2.onmouseup = function(){
        flag = false;
        cs2Ctx.closePath();
    }
    // onmouseleave事件
    canvas2.onmouseleave = function(){
        flag = false;
        cs2Ctx.closePath();
    }
    // --------- 画笔和橡皮擦功能实现 -------------

    // 保存画布
    function downloadImg() {
        var canvas = document.getElementById('canvas1');
        var alink = document.createElement("a");
        var imgSrc = canvas.toDataURL("image/png");
        alink.href = imgSrc;
        alink.download = Date.now() + ".png";
        alink.click();
    }
</script>

4、可以把画布保存成图片:

原理就是将canvas内容转成Base64格式,作为图片下载,当然也可以把Base64存储到数据库或其他地方,以后可加载它绘制到canvas画布上。

<script>

    // 保存画布
    function downloadImg() {
        var canvas = document.getElementById('canvas2');
        var alink = document.createElement("a");
        var imgSrc = canvas.toDataURL("image/png");
        alink.href = imgSrc;
        alink.download = Date.now() + ".png";
        alink.click();
    }
</script>

5、效果如图:

以上就是巧用canvas实现画板功能,使用画笔在图片上涂画,橡皮擦可擦除涂画,并保持的实现。如有错误,请不吝指正。

 

另附:初始化画布,绘制图片代码

$(function () {
   var canvas1 = document.getElementById('canvas1');
   var ctx1 = canvas1.getContext("2d");
   var canvas2 = document.getElementById('canvas2');
   var ctx2 = canvas2.getContext("2d");
   var image = new Image();
   image.src = "./image/canvas_demo.png";
   
   image.onload = function(){
      canvas1.width = this.width;
      canvas1.height = this.height;
      ctx1.drawImage(this, 0, 0);
      
      canvas2.width = this.width;
      canvas2.height = this.height;
      ctx2.drawImage(this, 0, 0);
   }
});

 

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
实现 Canvas 上的图片标注、缩放、移动、保存历史状态、橡皮擦功能,可以通过以下步骤来完成: 1. 加载图片使用 JavaScript 中的 Image 对象加载图片,并在图片加载完成后将其绘制到 Canvas 上。 ```javascript const img = new Image(); // 创建 Image 对象 img.onload = function() { ctx.drawImage(img, 0, 0); // 将图片绘制到画布上 }; img.src = 'image.jpg'; // 设置图片路径 ``` 2. 实现标注功能。通过鼠标事件监听用户的操作,使用 Canvas 的 API 绘制标注。例如,监听鼠标点击事件,在点击位置绘制一个圆形。 ```javascript canvas.addEventListener('mousedown', function(e) { ctx.beginPath(); ctx.arc(e.offsetX, e.offsetY, 5, 0, 2 * Math.PI); ctx.fill(); }); ``` 3. 实现缩放和移动功能。通过鼠标滚轮事件监听用户的操作,使用 Canvas 的 API 实现缩放和移动。例如,监听鼠标滚轮事件,在滚轮滚动时根据滚动方向调整画布的缩放比例。 ```javascript canvas.addEventListener('wheel', function(e) { const delta = e.deltaY > 0 ? 0.1 : -0.1; const scale = Math.max(0.1, Math.min(10, currentScale + delta)); ctx.scale(scale, scale); currentScale = scale; }); ``` 4. 实现保存历史状态功能使用 JavaScript 中的数组来保存历史状态,每当用户进行操作时,将当前状态保存到数组中。撤销操作时,从数组中取出上一个状态并恢复到画布上。 ```javascript const states = []; // 保存历史状态的数组 function saveState() { states.push(canvas.toDataURL()); // 保存当前状态 } function undo() { if (states.length > 0) { const img = new Image(); img.onload = function() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空画布 ctx.drawImage(img, 0, 0); // 绘制上一个状态 }; img.src = states.pop(); // 取出上一个状态 } } ``` 5. 实现橡皮擦功能。通过监听鼠标事件,在鼠标位置绘制一个与背景相同的矩形,来模拟橡皮擦的效果。 ```javascript canvas.addEventListener('mousemove', function(e) { if (erasing) { ctx.fillStyle = '#ffffff'; // 设置橡皮擦颜色为白色 ctx.fillRect(e.offsetX - 5, e.offsetY - 5, 10, 10); // 绘制矩形 } }); ``` 完整示例代码如下: ```html <!DOCTYPE html> <html> <body> <canvas id="canvas" width="600" height="400"></canvas> <button onclick="undo()">撤销</button> <button onclick="erasing = !erasing">橡皮擦</button> <script> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); let currentScale = 1; let erasing = false; const states = []; const img = new Image(); img.onload = function() { ctx.drawImage(img, 0, 0); saveState(); }; img.src = 'image.jpg'; canvas.addEventListener('mousedown', function(e) { ctx.beginPath(); ctx.arc(e.offsetX, e.offsetY, 5, 0, 2 * Math.PI); ctx.fill(); saveState(); }); canvas.addEventListener('mousemove', function(e) { if (erasing) { ctx.fillStyle = '#ffffff'; ctx.fillRect(e.offsetX - 5, e.offsetY - 5, 10, 10); } }); canvas.addEventListener('wheel', function(e) { const delta = e.deltaY > 0 ? 0.1 : -0.1; const scale = Math.max(0.1, Math.min(10, currentScale + delta)); ctx.scale(scale, scale); currentScale = scale; }); function saveState() { states.push(canvas.toDataURL()); } function undo() { if (states.length > 1) { const img = new Image(); img.onload = function() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0); }; img.src = states[states.length - 2]; states.pop(); } } </script> </body> </html> ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值