javascript結(jié)合Flexbox簡單實(shí)現(xiàn)滑動拼圖游戲
滑動拼圖就是把一張圖片分成幾等份,打亂順序(下圖),然后通過滑動拼湊成一張完整的圖片。
要實(shí)現(xiàn)一個拼圖游戲,需要考慮怎樣隨機(jī)的打亂順序,怎樣交換兩張圖片的位置,等等。但是,使用了Flexbox布局以后,這都不需要你去考慮,瀏覽器會幫你做,F(xiàn)lexbox就是這么的強(qiáng)大。關(guān)于Flexbox的介紹可以點(diǎn)擊這里。
這個游戲中要用的是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>
如果不僅限于九宮格,還要十六宮格等,上面的元素完全可以動態(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];
通過將數(shù)字打亂順序,隨機(jī)賦值給每個canvas元素的order屬性,這樣瀏覽器就自動幫你排序了。
關(guān)于代碼的其他細(xì)節(jié)就不講了,這里說一下怎樣交換兩張圖片的位置,真是出乎意料的簡單:
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>
大家做測試的時候,最好用谷歌模擬器或者手機(jī)打開,因?yàn)橹恢С忠苿佣擞|摸事件。
代碼中只實(shí)現(xiàn)了基本功能,并沒有實(shí)現(xiàn)完整功能。
- JS快速實(shí)現(xiàn)移動端拼圖游戲
- 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)簡單拼圖游戲
- 基于JS實(shí)現(xiàn)簡單滑塊拼圖游戲
- 使用js編寫實(shí)現(xiàn)拼圖游戲
相關(guān)文章
JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的幾種常用方式
這篇文章主要介紹了JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的幾種常用方式,結(jié)合實(shí)例形式對比分析了JavaScript頁面跳轉(zhuǎn)的常見實(shí)現(xiàn)技巧與相關(guān)注意事項,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11基于JS快速實(shí)現(xiàn)導(dǎo)航下拉菜單動畫效果附源碼下載
這是一個帶變形動畫特效的下拉導(dǎo)航菜單特效。該導(dǎo)航菜單在菜單項之間切換時,下拉菜單會快速的根據(jù)菜單內(nèi)容的大小來動態(tài)變形,顯示合適的下拉菜單大小,效果非常棒,對導(dǎo)航下拉菜單效果感興趣的朋友一起通過本文學(xué)習(xí)吧2016-10-10用javascript實(shí)現(xiàn)頁內(nèi)搜索的腳本代碼
用javascript實(shí)現(xiàn)頁內(nèi)搜索的腳本代碼...2007-08-08JavaScript實(shí)現(xiàn)圖片輪播的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)圖片輪播的方法,使用純javascript實(shí)現(xiàn)圖片輪播切換的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07