javascript結(jié)合Flexbox簡(jiǎn)單實(shí)現(xiàn)滑動(dòng)拼圖游戲
滑動(dòng)拼圖就是把一張圖片分成幾等份,打亂順序(下圖),然后通過(guò)滑動(dòng)拼湊成一張完整的圖片。

要實(shí)現(xiàn)一個(gè)拼圖游戲,需要考慮怎樣隨機(jī)的打亂順序,怎樣交換兩張圖片的位置,等等。但是,使用了Flexbox布局以后,這都不需要你去考慮,瀏覽器會(huì)幫你做,F(xiàn)lexbox就是這么的強(qiáng)大。關(guān)于Flexbox的介紹可以點(diǎn)擊這里。
這個(gè)游戲中要用的是Flexbox布局的order屬性,order屬性可以用來(lái)控制Flex項(xiàng)目的順序。
這里我用九個(gè)canvas元素來(lái)把圖片分成九等分,也可以用其他方法,比如背景圖片定位:
<div class="wrap"> <canvas></canvas> <canvas></canvas> <canvas></canvas> <canvas></canvas> <canvas></canvas> <canvas></canvas> <canvas></canvas> <canvas></canvas> <canvas></canvas> </div>
如果不僅限于九宮格,還要十六宮格等,上面的元素完全可以動(dòng)態(tài)生成。
下面是生成打亂順序的九張圖代碼:
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);
});
});
上面的關(guān)鍵代碼是:
item.style.order = random[i];
通過(guò)將數(shù)字打亂順序,隨機(jī)賦值給每個(gè)canvas元素的order屬性,這樣瀏覽器就自動(dòng)幫你排序了。
關(guān)于代碼的其他細(xì)節(jié)就不講了,這里說(shuō)一下怎樣交換兩張圖片的位置,真是出乎意料的簡(jiǎn)單:
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>
大家做測(cè)試的時(shí)候,最好用谷歌模擬器或者手機(jī)打開(kāi),因?yàn)橹恢С忠苿?dòng)端觸摸事件。
代碼中只實(shí)現(xiàn)了基本功能,并沒(méi)有實(shí)現(xiàn)完整功能。
- JS快速實(shí)現(xiàn)移動(dòng)端拼圖游戲
- JS 拼圖游戲 面向?qū)ο螅⑨屚暾?/a>
- js+html5實(shí)現(xiàn)可在手機(jī)上玩的拼圖游戲
- JS實(shí)現(xiàn)拼圖游戲
- jQuery+vue.js實(shí)現(xiàn)的九宮格拼圖游戲完整實(shí)例【附源碼下載】
- 基于javascript制作經(jīng)典傳統(tǒng)的拼圖游戲
- 基于Vue.js實(shí)現(xiàn)數(shù)字拼圖游戲
- 利用原生的JavaScript實(shí)現(xiàn)簡(jiǎn)單拼圖游戲
- 基于JS實(shí)現(xiàn)簡(jiǎn)單滑塊拼圖游戲
- 使用js編寫(xiě)實(shí)現(xiàn)拼圖游戲
相關(guān)文章
javascript面向?qū)ο笾蚕沓蓡T屬性與方法及prototype關(guān)鍵字用法
這篇文章主要介紹了javascript面向?qū)ο笾蚕沓蓡T屬性與方法及prototype關(guān)鍵字用法,實(shí)例分析了prototype關(guān)鍵字在共享成員屬性與方法中的原理與使用技巧,需要的朋友可以參考下2015-01-01
基于JS實(shí)現(xiàn)禁止查看源碼及獲取鍵盤(pán)的按鍵值
這篇文章主要介紹了基于JS實(shí)現(xiàn)禁止查看源碼及獲取鍵盤(pán)的按鍵值,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
JavaScript undefined及null區(qū)別實(shí)例解析
這篇文章主要介紹了JavaScript undefined及null區(qū)別實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
layui中的tab控件點(diǎn)擊切換觸發(fā)事件
這篇文章主要介紹了layui中的tab控件點(diǎn)擊切換觸發(fā)事件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
在layui下對(duì)元素進(jìn)行事件綁定的實(shí)例
今天小編就為大家分享一篇在layui下對(duì)元素進(jìn)行事件綁定的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09

