有關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{
    width: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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM