资讯专栏INFORMATION COLUMN

自定义上传图片拼图游戏

hsluoyz / 3415人阅读

摘要:点击格子,首先比较该格子是否与空白格子直接相邻,如果是就交换格子的和值进行换位获取空白的格子对象值互换接下来是把上传的图片设置成格子背景,通过监听的事件来获取图片文件该方法将转换成可访问的本地路径重新设置格子背景源码地址点击访问完

1. 游戏访问连接

点击跳转

2. 九宫格拼图原理

图例原理:

上图的九宫格图例,每个格子都有一个(x,y)的坐标,假如格子9是空白格子,怎么知道6和8是它的直接相邻格子呢。这时候就体现出格子坐标(x,y)的作用了, 使用公式:|(x6 - x9)| + |(y6 - y9)| = 1,将空白格子9的坐标与格子6的坐标进行对应坐标的差值的绝对值的和等于1,就证明它们是直接相邻格子,可进行移动互换。

详细原理请点击:跳转

3. 实现过程,代码分析

flex实现九宫格布局:


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2 . 现在的布局是这样子的:

3 . 分析:每个li代表一个格子,自定义属性data-x和data-y代表坐标(x, y);而样式order用于对格子进行移动排序;格子9添加id="empty"用于标识为空白格子。
4 . 因为格子的宽度是通过百分比设置的,会根据不同屏幕宽度的变化而变化;而且我们需要正方形的小格子,所以格子的高度需要js动态计算:

// 设置格子的高度、背景图片的尺寸
setChildStyle() {
  this.childWidth = window.getComputedStyle(this.oChild[0], false).width; // 获取格子宽度
  console.log(this.childWidth);
  for (let i = 0; i < this.oChild.length; i++) {
    this.oChild[i].style.height = `${this.childWidth}`;
  }
}

5 . 现在变成


6 . 现在给每个格子设置背景图片的尺寸(background-size),将格子的background-size的宽度设置成格子父节点ul的宽度,高度为auto,然后通过backgound-position进行定位,用格子的背景拼凑成一张完整的图片

setChildStyle() {
  this.childWidth = window.getComputedStyle(this.oChild[0], false).width;
  console.log(this.childWidth);
  for (let i = 0; i < this.oChild.length; i++) {
     this.oChild[i].style.height = `${this.childWidth}`;
     this.oChild[i].style.backgroundSize = `${this.ulWidth} auto`;
     this.setBgpositon(this.oChild[i]);
  }
}

7 . 其实每个格子的背景图片都是同一张,只不过是通过background-position 对背景图片进行定位,让每个格子只显示图片背景的九分之一,

// 设置背景图在格子的位置
setBgpositon(chiObj) {
  let x = chiObj.getAttribute("data-x") - 1;
  let y = chiObj.getAttribute("data-y") - 1;
  chiObj.style.backgroundPosition = `${-x*parseInt(this.childWidth)}px ${-y*parseInt(this.childWidth)}px`;
}

如下图视:

8 . 设置默认背景图片后:

// 设置格子的背景图片
setBgImg(imgUrl) {
  for (let i = 0; i < this.oChild.length - 1; i++) {
    this.oChild[i].style.backgroundImage = `url(${imgUrl})`;
  }
}

9 . 接下来把格子撸成可移动的,与空白格子直接相邻的格子都可以与空白格子换位,一开始的order样式就起作用了。点击格子,首先比较该格子是否与空白格子直接相邻,如果是就交换格子的data-x、data-y和order值进行换位:

childEvent() {
  let that = this;
  let oEmptyChild = document.getElementById("empty"); // 获取空白的格子对象
  this.oUl[0].addEventListener("click", function(ev){
    let target = ev.target;
    let targetX, targetY, targetOrder;
    let iEmptyX, iEmptyY, iEmptyOrder;
    if (target.className != "child" ) return false;
    iEmptyX = oEmptyChild.getAttribute("data-x");
    iEmptyY = oEmptyChild.getAttribute("data-y");
    iEmptyOrder = window.getComputedStyle(oEmptyChild, false).order;
    targetX = target.getAttribute("data-x");
    targetY = target.getAttribute("data-y");
    targetOrder = window.getComputedStyle(target, false).order;
    if (Math.abs(targetX - iEmptyX) + Math.abs(targetY - iEmptyY) == 1) {
      // data-x data-y order 值互换
      [iEmptyX, targetX] = [targetX, iEmptyX];
      [iEmptyY, targetY] = [targetY, iEmptyY];
      [iEmptyOrder, targetOrder] = [targetOrder, iEmptyOrder];

      oEmptyChild.setAttribute("data-x", iEmptyX);
      oEmptyChild.setAttribute("data-y", iEmptyY);
      oEmptyChild.style.order = iEmptyOrder;
      target.setAttribute("data-x", targetX);
      target.setAttribute("data-y", targetY);
      target.style.order = targetOrder;
    }
  }, false);
}

10 . 接下来是把上传的img图片设置成格子背景,通过监听input type="file"的change事件来获取图片文件files:

imgEvent() {
  let that = this;
  this.oFile.addEventListener("change", function(){
    let imgUrl = window.URL.createObjectURL(this.files[0]); // 该方法将files转换成img可访问的本地路径
    that.oImg.setAttribute("src", imgUrl);
    that.oImg.onload = function() {
      that.setBgImg(imgUrl); // 重新设置格子背景
    }
  }, false);
}

11 . 源码地址 点击访问

12 . (完)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/114256.html

相关文章

  • 定义上传图片拼图游戏

    摘要:点击格子,首先比较该格子是否与空白格子直接相邻,如果是就交换格子的和值进行换位获取空白的格子对象值互换接下来是把上传的图片设置成格子背景,通过监听的事件来获取图片文件该方法将转换成可访问的本地路径重新设置格子背景源码地址点击访问完 1. 游戏访问连接 点击跳转 2. 九宫格拼图原理 图例原理: showImg(https://segmentfault.com/img/remote/14...

    Baoyuan 评论0 收藏0
  • HTML 简单拼图游戏

    摘要:基本需求有一个固定区域,被拆分成个同等大小的碎片,拿走其中一块,靠近缺口的块可以向缺口方向移动当拼出原来的图样视为完成。左右移动很简单,序号大的序号小的即可。 先不废话,请看演示。 showImg(https://segmentfault.com/img/bVyoj2);showImg(https://segmentfault.com/img/bVyoj5); 公司要搞这么个微信活动...

    vslam 评论0 收藏0
  • HTML 简单拼图游戏

    摘要:基本需求有一个固定区域,被拆分成个同等大小的碎片,拿走其中一块,靠近缺口的块可以向缺口方向移动当拼出原来的图样视为完成。左右移动很简单,序号大的序号小的即可。 先不废话,请看演示。 showImg(https://segmentfault.com/img/bVyoj2);showImg(https://segmentfault.com/img/bVyoj5); 公司要搞这么个微信活动...

    eechen 评论0 收藏0

发表评论

0条评论

hsluoyz

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<