如何實現Canvas圖像的拖拽、點擊等操作


上一篇Canvas的博文寫完后,有位朋友希望能對Canvas繪制出來的圖像進行點擊、拖拽等操作,因為Canvas繪制出的圖像能很好的美化。好像是想做爐石什么的游戲,我也沒玩過。

Canvas在我的理解中就好像在一張畫布上繪制圖像,它只能看到卻“摸”不到,那要如何進行操作呢。我不知道網上是怎么做的,這里用自己的想法做了個DEMO分享給大家。

思路:

雖然Canvas不能拖拽,但div可以拖拽,那怎么把二者結合起來呢。初步想法是將一個與Canvas圖像大小差不多的div覆蓋在其上,在拖拽div時將獲取的光標坐標修正后傳給Canvas繪制函數並刷新圖像的位置。

既然要覆蓋,先做些准備工作:

1.將div與Canvas畫布均position:absolute,否則無法重疊。

2.將div的z-index值設置大點,保證其在Canvas畫面之上。

准備工作完成后,我們先來看div的拖拽:

    var divObj=document.getElementById("cover");
    var moveFlag=false;

        divObj.onmousedown=function(e){
        moveFlag=true;
        var clickEvent=window.event||e;
        var mwidth=clickEvent.clientX-divObj.offsetLeft;
        var mheight=clickEvent.clientY-divObj.offsetTop;
        document.onmousemove=function(e){
            var moveEvent=window.event||e;
            if(moveFlag){
                divObj.style.left=moveEvent.clientX-mwidth+"px";
                divObj.style.top=moveEvent.clientY-mheight+"px";
                divObj.onmouseup=function(){
                    moveFlag=false;
                }
            }
        }
    };

來解讀下這段代碼:首先獲取div對象,設置拖拽標志moveFlage,當onmousedown時為true表示可以拖動,當onmouseup時為false表示不能拖動了。

      var clickEvent=window.event||e;
      var mwidth=clickEvent.clientX-divObj.offsetLeft;
      var mheight=clickEvent.clientY-divObj.offsetTop;

這三行代碼是為了修正光標位置。當點擊時,記錄下光標在div上的位置。mwidth和mheight表示光標落點相對於div左邊和上邊的距離。如果不加修正:

這就是不加修正的結果,當光標點下時,div的坐標即左上角會與光標坐標一致。

修正后:

點擊時光標總會“粘”在div某點上。

接下來繪制圖片:

首先定義全局變量X和Y,它們是為了實時更新圖像的繪制坐標。

 var ctx=document.getElementById("myCanvas").getContext("2d");
 var img=document.getElementById("myImg");
    function drawImg(){
        ctx.clearRect(0,0,1000,500);
        ctx.beginPath();
        ctx.drawImage(img,X,Y);
        ctx.closePath();
        ctx.stroke();
    }

    window.onload=function(){
        setInterval(drawImg,1);
    }

獲取“畫筆”,獲取圖片對象。這里setInterval循環執行繪制圖片的函數,以刷新圖片的位置,setInterval的間隔值越小,拖拽起來越“流暢”。

同時別忘了clearRect,當圖片移動到下一個位置時,清除上一個位置的圖片,參數為Canvas畫布的坐標和尺寸。

在拖拽時將修正后的光標坐標傳給X、Y:

 X=moveEvent.clientX-mwidth;
 Y=moveEvent.clientY-mheight;

最后加上div和圖像的活動范圍:

if(moveEvent.clientX<=mwidth){
        divObj.style.left=0+"px";
        X=0;
}
if(parseInt(divObj.style.left)+divObj.offsetWidth >=1000){
        divObj.style.left=1000 - divObj.offsetWidth+"px";
        X=1000 - divObj.offsetWidth;
}
if(moveEvent.clientY<=mheight){
        divObj.style.top=0+"px";
        Y=0;
}
if(parseInt(divObj.style.top)+divObj.offsetHeight>=500){
       divObj.style.top=500-divObj.offsetHeight+"px";
       Y=500-divObj.offsetHeight;
}

這個就看個人的要求了,注意是要同時限定div和圖片的活動范圍。1000與500為本例的畫布大小,如果是在整個頁面里活動就換成innerWidth或innerHeight。

徹底隱藏div看看效果:

最后說下點擊事件,這里要注意的是在拖拽的過程中onmousedown與onmouseup二者就構成了一個click過程,但我們不希望在拖拽結束后觸發點擊事件。

這里有個比較簡單的辦法,定義一個clickFlag默認為false,當onmousedown時設為true,若進行了onmousemove事件時設為false。

在最后onmouseup時判斷clickFlag的值,為true時才觸發點擊事件。也就是說當你按下鼠標時,只有不發現移動,松開鼠標時才會觸發點擊事件。

 

整理后的JS代碼:

//    繪制圖片坐標
    var X=0;
    var Y=0;
//    js部分
    var divObj=document.getElementById("cover");
    var moveFlag=false;
//區別moueseup與click的標志
    var clickFlag=false;
//    拖拽函數
    divObj.onmousedown=function(e){
        moveFlag=true;
        clickFlag=true;
        var clickEvent=window.event||e;
        var mwidth=clickEvent.clientX-divObj.offsetLeft;
        var mheight=clickEvent.clientY-divObj.offsetTop;
        document.onmousemove=function(e){
            clickFlag=false;
            var moveEvent=window.event||e;
            if(moveFlag){
                divObj.style.left=moveEvent.clientX-mwidth+"px";
                divObj.style.top=moveEvent.clientY-mheight+"px";
////              將鼠標坐標傳給Canvas中的圖像
                X=moveEvent.clientX-mwidth;
                Y=moveEvent.clientY-mheight;
////              下面四個條件為限制div以及圖像的活動邊界
                if(moveEvent.clientX<=mwidth){
                    divObj.style.left=0+"px";
                    X=0;
                }
                if(parseInt(divObj.style.left)+divObj.offsetWidth >=1000){
                    divObj.style.left=1000 - divObj.offsetWidth+"px";
                    X=1000 - divObj.offsetWidth;
                }
                if(moveEvent.clientY<=mheight){
                    divObj.style.top=0+"px";
                    Y=0;
                }
                if(parseInt(divObj.style.top)+divObj.offsetHeight>=500){
                    divObj.style.top=500-divObj.offsetHeight+"px";
                    Y=500-divObj.offsetHeight;
                }
                divObj.onmouseup=function(){
                    moveFlag=false;
                    if(clickFlag){
                        alert("點擊生效");
                    }
                }
            }
        }
    };

本例到此結束,更多功能大家有興趣可以自己開發,感謝您的瀏覽,也感謝每個對我這菜鳥提意見的人。


免責聲明!

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



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