首页 > 技术文章 > 拼图 canvas分割 dom拖拽 pc 移动端

wpp12345 2016-11-17 17:50 原文

参考:Canvas drag 实现拖拽拼图小游戏

参考的案例,不支持手机端。总结下实现过程中遇到的小坑。

gitHub: https://github.com/WppFrontEnd/puzzle

大概步奏分为三部分:

1. cavas 分割图片

2. 图片乱序

3. 排序图片

其中1和2都是参考了Canvas drag 实现拖拽拼图小游戏

代码主要如下:

1. cavas 分割图片

segmentImg: function(puzzleImg){
            var index =0;
            divisionNum =3; 
            var imgHeight =  puzzleImg.height;
            var imgWidth = puzzleImg.width;
            var sigelH = imgHeight/divisionNum;
            var sigelW = imgWidth/divisionNum;
            this.canvas.height = sigelH;
            this.canvas.width  = sigelW;    
            for(var i=0;i<divisionNum;i++){
                for(var j=0;j<divisionNum;j++){
                    posX = sigelW * j+(5*j);
                    posY = sigelH * i+(5*i);
                    this.context.drawImage(puzzleImg, sigelW * j, sigelH * i, sigelW, sigelH, 0, 0, sigelW, sigelH);
                    this.imgCanvasList[index].src= this.canvas.toDataURL('image/jpeg');
                    this.imgCanvasList[index].id=index;
                    index++;                    
                }
            }
        }
canvas分割图片

在分割图片的时候,遇到了一个坑: 生成的图片的大小总是300*150,而我需要的图片只是在300*150的右上角,而不是一张完整我切割的图片,大概如下:

 

虽然我知道设置canvas的大小是要写在标签上的,然后我没有想到写在style里面,html上显示的canvas是有效果的,可是生成图片的时候却依然是默认的大小。

之前是这样写的

this.canvas.style.height = sigelH;
this.canvas.style.width = sigelW;

改成这样

this.canvas.height = sigelH;
this.canvas.width = sigelW;

2. 图片乱序

sortImg: function(){
            this.imgCanvasList.sort(function(){
                return Math.random() - Math.random();
            });
        }
图片乱序

这是第二个坑:

正常的逻辑即是,先分割图片,在乱序

self.segmentImg(puzzleImg);
self.sortImg();

然而这样写并没有达到乱序的效果。

整理下逻辑:

这样就通了,但是我也发现我这样写的一个不好之处: self.sortImg();不能单独拿出来用,如果想排两次序就得执行两次排序赋值。所以还需要改进~

3. 排序图片

dragEvent: function(){
            var contain = document.getElementById('game');
            //bind dragStart function
            var imgList = contain.querySelectorAll('img');
            var that = this;
            var listLen = that.imgDomList.length;
            var originImgIndex;
            var dragImgIndex;
            

            for(var i=0, len = that.imgDomList.length; i < len; i++ ){
                var draggie = new Draggabilly(that.imgDomList[i]);
                draggie.on( 'dragStart', function( event, pointer) {
                    dragImg = event.srcElement;
                });

                draggie.on( 'dragEnd', function( event, pointer) {
                    console.log(pointer);
                    var clickX = pointer.pageX;
                    var clickY = pointer.pageY;
                    console.log(clickX+ '   '+clickY);
                    var index =0;
                    for(var i=0;i<listLen;i++){
                        var posX1 = that.imgDomList[i].offsetTop;
                        var posX2 = posX1+that.imgDomList[i].height;
                        var posY1 = that.imgDomList[i].offsetLeft;
                        var posY2 = posY1+that.imgDomList[i].width;
                        if(clickX>=posY1&&clickX<=posY2&&clickY>=posX1&&clickY<=posX2){
                            index++;
                            if(index==1){
                                originImgIndex = i;
                            }else if(index==2){
                                dragImgIndex = i;
                                index=0;
                            }
                        }
                    }
                    
                    var originImgId = that.imgDomList[originImgIndex].id;
                    var originObj = document.getElementById(originImgId);
                    var cache = {
                        'src': originObj.src,
                        'id': originObj.id
                    };
                    
                    if(!dragImgIndex){
                        originObj.style.left=0;
                        originObj.style.top=0;
                        originImgIndex="";
                        dragImgIndex="";
                    }else{
                        var endObjId = that.imgDomList[dragImgIndex].id;
                        var endObj = document.getElementById(endObjId);
                        originObj.src=endObj.src;
                        originObj.id=endObj.id;
                        endObj.src = cache.src;
                        endObj.id = cache.id;
                        originObj.style.left=0;
                        originObj.style.top=0;
                        endObj.style.left=0;
                        endObj.style.top=0;
                           originImgIndex="";
                        dragImgIndex="";
                    }
                    that.isSuccess();
                })
            }
            
        }
View Code

 排序的过程中,主要遇到两个问题:

(1) offsetTop,height,offsetLef,width 取到的值都是四舍五入的整数

解决办法: 用style.top,style.left 但是结果都带px

(2) 值引用,引用类型

例如:

好好研究一下。

 

推荐阅读