参考: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();
})
} }

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

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

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

(2) 值引用,引用类型

例如:

好好研究一下。

拼图 canvas分割 dom拖拽 pc 移动端的更多相关文章

  1. canvas drag 实现拖拽拼图小游戏

    博主一直心心念念想做一个小游戏-  前端时间终于做了一个小游戏,直到现在才来总结,哈哈- 以后要勤奋点更新博客! 实现原理 1.如何切图? 用之前的方法就是使用photoshop将图片切成相应大小的图 ...

  2. 如何实现Canvas图像的拖拽、点击等操作

    上一篇Canvas的博文写完后,有位朋友希望能对Canvas绘制出来的图像进行点击.拖拽等操作,因为Canvas绘制出的图像能很好的美化.好像是想做炉石什么的游戏,我也没玩过. Canvas在我的理解 ...

  3. canvas实现鼠标拖拽矩形移动改变大小

    项目的一个新需求,动态生成矩形框,鼠标点击拖动改变矩形框的位置,并可以调整大小. 之前做过一个小demo,需求类似,但是在canvas内只有一个矩形框,拖动移动,当时记得是用isPointInPath ...

  4. dom 拖拽回放

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  5. dom 拖拽div

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  6. HTML5 -canvas拖拽、移动 绘制图片可操作移动,拖动

    关于canvas 的基础知识就不多说了,可以进这个网址学习 http://www.w3school.com.cn/html5/html_5_canvas.asp 对于canvas 和 SVG 其实一开 ...

  7. 使用UGUI实现拖拽功能(拼图小游戏)

    实现方式 1.引入UGUI自带的事件系统 UnityEngine.EventSystems 2.为我们的类添加接口 IBeginDragHandler, IDragHandler, IEndDragH ...

  8. canvas 拖拽实现

    Canvas 依赖分辨率 不支持事件处理器 弱的文本渲染能力 能够以 .png 或 .jpg 格式保存结果图像 最适合图像密集型的游戏,其中的许多对象会被频繁重绘 SVG 不依赖分辨率 支持事件处理器 ...

  9. javascript小实例,PC网页里的拖拽

    几年前,我参与设计开发一个房产网的项目,我负责前端工作,由于项目经理要求比较高,参考了很多房产类网站比较优秀的功能,想把别人比较优秀的设计和想法集合到一起,那时的设计稿和功能实现,简直就是改了又改,今 ...

随机推荐

  1. jquery.validate[.unobtrusive]和Bootstrap实现tooltip错误提示

    类似的文章园子里已有,请看这里,个人感觉稍显复杂,日前也打算写一个简单的给项目用,一些关键点记录于此.最终效果如下: 后端使用Asp.net mvc5,前端框架有:jquery.validate.jq ...

  2. NHibernate系列文章二十:NHibernate关系之一对一(附程序下载)

    摘要 NHibernate一对一关系虽然不经常碰到,但是在对于数据库结构优化的时候,经常会碰到一对一关系.比如,产品详细信息比较多的时候,可以把产品详细信息放到另一张表里面,Product主表只记录产 ...

  3. 14.S5PV210串行通信编程实战

    1.整个程序流程分析(1)整个串口通信相关程序包含2部分:uart_init负责初始化串口,uart_putc负责发送一个字节2.串口控制器初始化关键步骤(1)初始化串口的Tx和Rx引脚所对应的GPI ...

  4. arcgis基于地形数据的坡度分析

    高程.坡度和坡向是小班中非常重要的因子,坡度对水土保持规划设计具有决定性的作用,是土地利用规划和治理措施配置首先要考虑的因素.如何利用地形数据对坡度进行分析呢,本文即将揭晓. 软件准备: locasp ...

  5. maven项目管理构建

    准备工作 在eclipse配置maven之前需要我们做好准备工作,如下: 1. 安装jdk 2. 已安装好 maven,将maven配置成功 3. 下载Eclipse,解压缩安装完成,建立工作空间.  ...

  6. 机器学习系列------1. GBDT算法的原理

    GBDT算法是一种监督学习算法.监督学习算法需要解决如下两个问题: 1.损失函数尽可能的小,这样使得目标函数能够尽可能的符合样本 2.正则化函数对训练结果进行惩罚,避免过拟合,这样在预测的时候才能够准 ...

  7. sql语句_分页查询

    1.查询数据库中存在某一列名的表 use [db] go SELECT name FROM sysobjects WHERE id IN (SELECT id FROM syscolumns WHER ...

  8. Winform窗体关闭时判断是否关闭

    在窗体的关闭事件FormClosing中进行判断,FormClosing事件每当用户关闭窗体时,在窗体已关闭并指定关闭原因前发生. private void Form1_FormClosing(obj ...

  9. SQL指南-SELECT语句

    SELECT 语句 SELECT 语句用于从表中筛选数据.列表结果存储于一个结果表中(称作result-set) 语法 SELECT column_name(s)FROM table_name 注意: ...

  10. highchart 动态刷新(可用于制作股票时时走势)

    最近项目中要求获取时时的cpu动态图,利用 highchart 可以轻松实现该功能,效果可在此地址查看:动态效果 代码如下: 页面 js 引用: <script src="你项目js的 ...