zoukankan      html  css  js  c++  java
  • 有关Canvas的一点小事--鼠标绘图

    1、  如何根据鼠标位置获取canvas上对应位置的x,y。

    2、  canvas的图糊了,设置宽和高的方式不对。

    3、鼠标绘图代码

     

             之前听说过canvas这个元素,但是实际上并没有深入了解过。不过日前有个项目一是使用canvas显示dicom格式的医疗影像,一是利用canvas元素生成图像压缩包,将之前对canvas隐隐约约的好奇心被无限放大,那就尝试做一个用鼠标绘制图像的画布吧。这不难,网上一搜都是教程,然而……很多事情好像并不像想象的美好。

     

             要做的很简单,mousedown的时候设置开始作画的标签,开始作画后就开始捕捉mousemove的轨迹来作画,mouseup的时候停止(后面附完整代码)。

     

    1、  如何根据鼠标位置获取canvas上对应位置的x,y

    然而,无论使用offsetX,offsetY还是clientX-canvas.width,clientY-canvas.height都获取不到对应的x,y,我甚至找不到鼠标落下的点和鼠标位置的任何关系。我知道这应该跟canvas的拉伸有关,之前就有遇到过需要调整canvas大小后图像出问题的问题,然而网上很多代码都是直接使用这两个值,都是大忽悠,但是我对canvas没有一点了解,完全不知道如何转换,幸亏后来找到合适的方法。

                                var c=document.getElementById("myCanvas");
    
                                 var ctx=c.getContext("2d");
    
                                 //********尝试获得对应位置的x,y
    
                                 c.addEventListener('click',function(event){
    
                                           var event = event||window.event;
    
                                           var bbox = c.getBoundingClientRect();
    
                                           var x = event.offsetX * (c.width / bbox.width);
    
                                           var y = event.offsetY * (c.height / bbox.height); 

                           ctx.beginPath(); ctx.arc(x,y,
    10,0,2*Math.PI); ctx.stroke(); });

    2、  图糊了,如何设置宽和高。

    一开始我是把canvas当作普通元素处理,那么设置宽和高不就是,:

    #myCanvas{
        800px;
      height:600px;
    }

    然后图糊了,下图不太明显,但是在网页中的确不能看。

     

     

    然后我就知道了canvas要设置的是像素值,不是简单的宽和高,设置方法有下面两种:

    <1>行内设置属性

    <canvas id="myCanvas" width="800" height="500"></canvas>

    <2>js设置属性

    var c=document.getElementById("myCanvas");

    var ctx=c.getContext("2d");

    c.width=800;

    c.height=600;

     

    3、鼠标绘图代码

    <!DOCTYPE html>  
    <html lang="zh-cn">  
        <head>  
            <meta charset="UTF-8"/>  
            <script src='js/jquery-3.3.1.min.js'></script>
            <style>
                body{
                    background:black;
                    text-align:center;
                }
                #myCanvas{
                    margin:10px auto;
                    background:white;
                }
                
            </style>
        </head>  
        <body> 
            <canvas id="myCanvas"></canvas>
            
            <script type="text/javascript"> 
                $(document).ready(function(){
                    var c=document.getElementById("myCanvas");
                    var ctx=c.getContext("2d");
                    c.width=800;
                    c.height=600;
                    
                    var tempx = -1, tempy = -1;
                    function painting(event){
                        var event = event||window.event;
                        
                        /*获取宽和高*/
                        var bbox = c.getBoundingClientRect();
                        var x = event.offsetX * (c.width / bbox.width);
                        var y = event.offsetY * (c.height / bbox.height);    
                        
                        /*画线*/
                        ctx.beginPath();
                        ctx.moveTo(tempx, tempy);
                        ctx.lineTo(x, y);
                        ctx.stroke();
                        ctx.closePath();
                        /*存值*/
                        tempx = x;
                        tempy = y;
                    }
                    c.onmousedown = function(event){
                        var event = event||window.event;
                        var bbox = c.getBoundingClientRect();
                        /*存初值*/    
                        tempx=event.offsetX * (c.width / bbox.width);
                        tempy=event.offsetY * (c.height / bbox.height);            
                        /*开始作画*/
                        c.onmousemove = painting;
                    };
                    c.onmouseup = function(event){
                        c.onmousemove = null;
                    };
                
                });
                /*********
                
                **********/
            
            </script>  
        </body>  
    </html>  

    还可以做:
      1、shift绘制图像直线,根据shiftKey绘制,下有实现,不过不太灵敏,不够符合理想的状态
      2、橡皮擦,和清除全部图像,使用
      context.clearRect(0, 0, canvas.width, canvas.height);
      3、画圆画矩形,拖动会更改大小,这个涉及的细节更多了
        圆形:
          ctx.beginPath();
          ctx.arc(95,50,40,0,2*Math.PI);
          ctx.stroke();
        矩形:
          ctx.fillRect(0,0,150,75);
      4、设置颜色选择、更改画笔粗细(可以使用正方形代替线,不过好像不太对劲)
          ctx.fillStyle="#FF0000";
      5、添加文字
          ctx.font="30px Arial";
          ctx.fillText("Hello World",10,50);
       6、历史画笔,返回恢复
          保存好进行过的操作
       7、保存下载图片
          下文再进行讨论
      这些事件要考虑的细节问题太多,就懒得写代码调整尝试了,下面是添加了shift操作并做了一些优化的代码

    <!DOCTYPE html>  
    <html lang="zh-cn">  
        <head>  
            <meta charset="UTF-8"/>  
            <script src='js/jquery-3.3.1.min.js'></script>
            <style>
                body{
                    background:black;
                    text-align:center;
                }
                #myCanvas{
                    margin:10px auto;
                    background:white;
                }
                
            </style>
        </head>  
        <body> 
            <canvas id="myCanvas"></canvas>
            
            <script type="text/javascript"> 
                $(document).ready(function(){
                    var c=document.getElementById("myCanvas");
                    var ctx=c.getContext("2d");
                    c.width=800;
                    c.height=600;
                    
                    var tempx = -1, tempy = -1;
                    var shiftline=-1.0,shiftx=-1,shifty=-1;/*shift画直线,因为x,y太快捕捉不到角度,另起一个shiftx,shifty来储存*/
                    //*******用鼠标画线
                    function paintingLine(event){
                        var event = event||window.event;
                        
                        //*******获取宽和高
                        var bbox = c.getBoundingClientRect();
                        var x = event.offsetX * (c.width / bbox.width);
                        var y = event.offsetY * (c.height / bbox.height);    
                        //********shift
                        var shiftKey = event.shiftKey;
                        if(shiftKey==true){
                            if(shiftline==-1.0){
                                if(shiftx==-1){
                                    shiftx = tempx;
                                    shifty = tempy;
                                }
                                if(timer==3){
                                    if(x-shiftx==0){
                                        shiftline = -2.0;
                                    }
                                    else{
                                        shiftline = (y-shifty)*1.0/(x-shiftx);
                                    }
                                    
                                }
                                timer = timer+1;
                                
                            }
                            else{
                                if(shiftline==-2.0){
                                    x = 0;
                                }
                                else{
                                    y = shifty+(x-shiftx) * shiftline;
                                }
                            }
                            
                        }
                        else{
                            shiftline = -1.0;
                            shiftx = -1;
                            shifty = -1;
                            timer = 0;
                        }
                        //**********画线
                        ctx.beginPath();
                        ctx.moveTo(tempx, tempy);
                        ctx.lineTo(x, y);
                        ctx.stroke();
                        ctx.closePath();
                        //**********存值
                        tempx = x;
                        tempy = y;
                    }
                    //******按下鼠标开始画线
                    c.onmousedown = function(event){
                        var event = event||window.event;
                        var bbox = c.getBoundingClientRect();
                        //*********存初值
                        tempx=event.offsetX * (c.width / bbox.width);
                        tempy=event.offsetY * (c.height / bbox.height);            
                        //*******开始作画
                        c.onmousemove = paintingLine;
                    };
                    //**********松开鼠标键停止作画
                    c.onmouseup = function(event){
                        c.onmousemove = null;
                        shiftline = -1.0;
                        shiftx = -1;
                        shifty = -1;
                        timer = 0;
                    };
                    //**********离开界面停止作画
                    c.onmouseout = function(event){
                        c.onmousemove = null;
                        shiftline = -1.0;
                        shiftx = -1;
                        shifty = -1;
                        timer = 0;
                    };
                
                });
                /*********
                还可以做:
                1、shift绘制图像直线,根据shiftKey绘制,上面有实现,不过不太灵敏,不够符合理想的状态
                2、橡皮擦,和清除全部图像,使用
                    context.clearRect(0, 0, canvas.width, canvas.height);
                3、画圆画矩形,拖动会更改大小,这个涉及的细节更多了
                圆形:
                    ctx.beginPath();
                    ctx.arc(95,50,40,0,2*Math.PI);
                    ctx.stroke();
                矩形:
                    ctx.fillRect(0,0,150,75);
                4、设置颜色选择、更改画笔粗细(可以使用正方形代替线,不过好像不太对劲)
                    ctx.fillStyle="#FF0000";
                5、添加文字
                    ctx.font="30px Arial";
                    ctx.fillText("Hello World",10,50);
                6、历史画笔,返回恢复
                    保存好进行过的操作
                7、保存下载图片
                    下文再进行讨论
                这些事件要考虑的细节问题太多,就懒得写代码调整尝试了
                **********/
            
            </script>  
        </body>  
    </html>  
    前端鼠标绘图代码

    参考:

    获取鼠标位置和canvas的对应xy:https://blog.csdn.net/u010513756/article/details/47363743

     

     

    当你深入了解,你就会发现世界如此广袤,而你对世界的了解则是如此浅薄,请永远保持谦卑的态度。
  • 相关阅读:
    对组件库对再次封装
    cube-ui修改按钮颜色
    移动端框架
    mac环境变量
    Promise {<pending>
    MAC升级node及npm
    create-react-app项目中的eslint
    查看删除分支
    git分支的相关问题
    centos7系统下安装php-fpm并配置nginx支持并开启网站gzip压缩
  • 原文地址:https://www.cnblogs.com/liwxmyself/p/10266052.html
Copyright © 2011-2022 走看看