首页 web前端 js教程 javascript结合Flexbox简单实现滑动拼图游戏_javascript技巧

javascript结合Flexbox简单实现滑动拼图游戏_javascript技巧

May 16, 2016 pm 03:15 PM
flexbox

滑动拼图就是把一张图片分成几等份,打乱顺序(下图),然后通过滑动拼凑成一张完整的图片。

要实现一个拼图游戏,需要考虑怎样随机的打乱顺序,怎样交换两张图片的位置,等等。但是,使用了Flexbox布局以后,这都不需要你去考虑,浏览器会帮你做,Flexbox就是这么的强大。关于Flexbox的介绍可以点击这里。
这个游戏中要用的是Flexbox布局的order属性,order属性可以用来控制Flex项目的顺序。
这里我用九个canvas元素来把图片分成九等分,也可以用其他方法,比如背景图片定位:

<div class="wrap">
  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>
</div>
登录后复制

如果不仅限于九宫格,还要十六宫格等,上面的元素完全可以动态生成。
下面是生成打乱顺序的九张图代码:

var drawImage = function (url) {
  return new Promise(function (resolve, reject) {
    var img = new Image();
    img.onload = function () {
      resolve(img);
    };
    img.src = url;
  })
};

drawImage("2.jpg").then(function (img) {
  var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  var random = arr.sort(function() {return Math.random() > 0.5});
  [].forEach.call(document.querySelectorAll("canvas"), function (item, i) {
    item.width = $(".wrap").clientWidth / 3;
    item.height = $(".wrap").clientHeight / 3;
    item.style.order = random[i];
    var ctx = item.getContext("2d");
    ctx.drawImage(img, img.width * (i % 3) / 3, img.height * Math.floor(i / 3) / 3, img.width / 3, img.height / 3, 0, 0, item.width, item.height);
  });
});

登录后复制

上面的关键代码是:

item.style.order = random[i];
登录后复制

通过将数字打乱顺序,随机赋值给每个canvas元素的order属性,这样浏览器就自动帮你排序了。
关于代码的其他细节就不讲了,这里说一下怎样交换两张图片的位置,真是出乎意料的简单:

var order1 = item.style.order;
var order2 = target.style.order;
登录后复制

只需要交换双方的order属性值就可以了。

完整代码

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
  <meta content="yes" name="apple-mobile-web-app-capable" />
  <meta content="black" name="apple-mobile-web-app-status-bar-style" />
  <meta content="telephone=no" name="format-detection" />
  <title></title>
  <style>
    html, body {
      height: 100%;
    }
    body {
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
    .wrap {
      display: flex;
      flex-wrap: wrap;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
    .wrap canvas {
      width: 33.3333%;
      height: 33.3333%;
      border: 1px solid red;
      box-sizing: border-box;
    }
  </style>
</head>
<body>
<div class="wrap">
  <canvas data-value="1"></canvas>
  <canvas data-value="2"></canvas>
  <canvas data-value="3"></canvas>
  <canvas data-value="4"></canvas>
  <canvas data-value="5"></canvas>
  <canvas data-value="6"></canvas>
  <canvas data-value="7"></canvas>
  <canvas data-value="8"></canvas>
  <canvas data-value="9"></canvas>
</div>
<script>
  var $ = function (el) {
    return document.querySelector(el);
  };
  var touchMove, touchEnd;
  var drawImage = function (url) {
    return new Promise(function (resolve, reject) {
      var img = new Image();
      img.onload = function () {
        resolve(img);
      };
      img.src = url;
    })
  };
  drawImage("2.jpg").then(function (img) {
    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    var random = arr.sort(function() {return Math.random() > 0.5});
    [].forEach.call(document.querySelectorAll("canvas"), function (item, i) {
      item.width = $(".wrap").clientWidth / 3;
      item.height = $(".wrap").clientHeight / 3;
      item.style.order = random[i];
      var ctx = item.getContext("2d");
      ctx.drawImage(img, img.width * (i % 3) / 3, img.height * Math.floor(i / 3) / 3, img.width / 3, img.height / 3, 0, 0, item.width, item.height);
    });
  });
  document.addEventListener("touchstart", function (e) {
    var target = e.target;
    if (e.target.tagName.toLowerCase() !== "canvas") {
      return;
    }
    var ctx = target.getContext("2d");
    var image = ctx.getImageData(0, 0, target.width, target.height);
    var obj = target.cloneNode(true);
    obj.getContext("2d").putImageData(image, 0, 0);
    var top = target.getBoundingClientRect().top, left = target.getBoundingClientRect().left;
    obj.style.cssText = "position: absolute; top: " + top + "px; left: " + left + "px";
    document.body.appendChild(obj);
    var point = {"x": e.touches[0].pageX, "y": e.touches[0].pageY};
    document.addEventListener("touchmove", touchMove = function (e) {
      obj.style.cssText = "position: absolute; top:" + (e.touches[0].pageY - point.y + top) + "px; left: " + (e.touches[0].pageX - point.x + left) + "px";
    });
    document.addEventListener("touchend", touchEnd = function (e) {
      var pos = {"x": e.changedTouches[0].pageX, "y": e.changedTouches[0].pageY};
      [].forEach.call(document.querySelectorAll(".wrap canvas"), function (item, i) {
        var offset = item.getBoundingClientRect();
        if (pos.x > offset.left && pos.x < (offset.left + item.width) && pos.y > offset.top && pos.y < (offset.top + item.height)) {
          var order1 = item.style.order;
          var order2 = target.style.order;
          if (obj.parentNode) {
            document.body.removeChild(obj);
          }
          item.style.order = order2;
          target.style.order = order1;
        }
      });
      document.removeEventListener("touchmove", touchMove);
      document.removeEventListener("touchend", touchEnd);
    })
  })
</script>
</body>
</html>
登录后复制

大家做测试的时候,最好用谷歌模拟器或者手机打开,因为只支持移动端触摸事件。

代码中只实现了基本功能,并没有实现完整功能。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
2 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

H5中position属性的灵活运用技巧 H5中position属性的灵活运用技巧 Dec 27, 2023 pm 01:05 PM

H5中如何灵活运用position属性在H5开发中,经常会涉及到元素的定位和布局问题。这时候,CSS的position属性就会发挥作用。position属性可以控制元素在页面中的定位方式,包括相对定位(relative)、绝对定位(absolute)、固定定位(fixed)和粘附定位(sticky)。本文将详细介绍在H5开发中如何灵活运用position属性

CSS 布局属性优化技巧:position sticky 和 flexbox CSS 布局属性优化技巧:position sticky 和 flexbox Oct 20, 2023 pm 03:15 PM

CSS布局属性优化技巧:positionsticky和flexbox在网页开发中,布局是一个非常重要的方面。良好的布局结构可以提高用户体验,使页面更加美观和易于导航。而CSS布局属性则是实现这一目标的关键。在本文中,我将介绍两种常用的CSS布局属性优化技巧:positionsticky和flexbox,并提供具体的代码示例。一、positions

HTML教程:如何使用Flexbox进行自适应等高等宽等间距布局 HTML教程:如何使用Flexbox进行自适应等高等宽等间距布局 Oct 27, 2023 pm 05:51 PM

HTML教程:如何使用Flexbox进行自适应等高等宽等间距布局,需要具体代码示例引言:在现代网页设计中,布局是一个非常关键的因素。对于需要展示大量内容的页面来说,如何合理地安排元素的位置和大小,以实现良好的可视性和易用性,是一个重要的问题。Flexbox(弹性盒布局)就是一个非常强大的工具,通过它可以轻松实现各种灵活的布局需求。本文将详细介绍Flexbox

HTML教程:如何使用Flexbox进行垂直等高布局 HTML教程:如何使用Flexbox进行垂直等高布局 Oct 16, 2023 am 09:12 AM

HTML教程:如何使用Flexbox进行垂直等高布局在Web开发中,布局一直是一个重要的问题。特别是在需要实现垂直等高布局时,传统的CSS布局方法往往会遇到一些困难。而使用Flexbox布局可以轻松解决这个问题。本教程将详细介绍如何使用Flexbox进行垂直等高布局,并提供具体的代码示例。Flexbox是CSS3中的新特性,可以用于创建灵活的、响应式的布局。

HTML教程:如何使用Flexbox进行自适应等高布局 HTML教程:如何使用Flexbox进行自适应等高布局 Oct 21, 2023 am 10:00 AM

HTML教程:如何使用Flexbox进行自适应等高布局,需要具体代码示例引言:在网页设计与开发中,实现自适应等高布局是一项常见的需求。传统的CSS布局方法往往在处理等高布局时面临一些困难,而Flexbox布局则为我们提供了一种简单且强大的解决方案。本文将介绍Flexbox布局的基本概念和常见用法,并给出具体的代码示例,帮助读者快速掌握使用Flexbox实现自

如何使用CSS3的flexbox技术,实现网页内容的平均分配? 如何使用CSS3的flexbox技术,实现网页内容的平均分配? Sep 11, 2023 am 11:33 AM

如何使用CSS3的flexbox技术,实现网页内容的平均分配?随着网页设计的发展,人们对于网页布局的要求越来越高。为了实现网页内容的平均分配,CSS3的flexbox技术成为了一个非常有效的解决方案。本文将介绍如何使用flexbox技术来实现网页内容的平均分配,并给出一些实用的示例。一、什么是flexbox技术flexbox(弹性布局)是CSS3中新增加的一

HTML教程:如何使用Flexbox进行平均分配布局 HTML教程:如何使用Flexbox进行平均分配布局 Oct 16, 2023 am 09:31 AM

HTML教程:如何使用Flexbox进行平均分配布局引言:在网页设计中,经常需要对元素进行布局。传统的布局方法存在一些局限性,而Flexbox(弹性盒子布局)是一种能够提供更灵活、更强大的布局方式。本文将介绍如何使用Flexbox来实现平均分配布局,同时给出具体的代码示例。一、Flexbox简介Flexbox是CSS3中引入的一种弹性盒子布局模型,它可以让元

HTML教程:如何使用Flexbox进行可伸缩等高等宽等间距自适应布局 HTML教程:如何使用Flexbox进行可伸缩等高等宽等间距自适应布局 Oct 19, 2023 am 10:22 AM

HTML教程:如何使用Flexbox进行可伸缩等高等宽等间距自适应布局,需要具体代码示例一、什么是Flexbox布局Flexbox是CSS3中引入的一种新布局模式,可以实现灵活的盒子模型布局。它是FlexibleBox的缩写,意为弹性布局。Flexbox布局可以根据容器的大小自动调整元素的位置和尺寸,实现各种灵活的排列方式。二、如何使用Flexbox布局创

See all articles