JavaScript经典进阶:javascript – 9宫格 – 拼图

项目地址:javascript – 9宫格 – 拼图

总体思路

切图 ==》打乱顺序 ==》拖拽实现数据交换

实现过程中,遇到的问题

数据随机排序方法 Array.sort( function(){ return Math.random()-Math.random() })
Array.from(array-like):可以将类数组转换为数组
toDataURL 需要开启http服务,才会正常工作(本例用live-server
什么是h5 : 基于原生js驱动的网页解析标准,它给我们提供了一系列新的API
drawImage()方法的使用:
dataTrdataTransfer()方法的使用:
toDataURL()方法的使用:
前后端分离: 前端负责数据渲染,后端只提供数据接口
Javascript怎么比较两个数组是否相同

  • alert([]==[]) alert([]===[]) 结果都为false;
  • alert([]==[]).toString() alert([]===[]).toString() 结果为true;

元素ID就是全局变量(html5新规则)

HTML5规范文档中指出:如果一个元素符合下面两条规则中的任一条,则window对象中必须要有与之对应的一个属性,属性值就是这个对象.

  • 如果一个元素拥有ID属性,那么ID属性的属性值就会成为window对象的属性名.
  • 如果一个元素拥有name属性,那么name属性的属性值就会成为window对象的属性名.但这个元素的标签名必须是: a, applet, area, embed, form, frame, frameset, iframe, img, object,其中的一个.
<div id="foo">div>


需求分析

/*
一、切图(3选1)这里选 方法3
----方法1: ps切图
----方法2:  背景图片的position实现切图(最难的是原生js做碰撞检测)
---------方法1: 和 方法2: 布局简单,位置交换很难
----方法3:  canvas切图
-----------------方法3: 布局复杂,位置交换很简单【单纯的交换数据,性能好】
*/

/*二、交换数据(h5的数据通信机制)*/

渲染图片并打乱顺序


<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JavaScript经典进阶:实现拼图游戏title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        h2 {
            text-align: center;
            margin-top: 80px;
        }

        #canvas {
            display: none;
        }

        #game {
            max-width: 456px;
            margin: 130px auto;
            margin-top: 10px;
        }

        #game>li {
            width: 150px;
            height: 150px;
            float: left;
            list-style: none;
            margin: 1px;
        }

        #game>li img {
            width: 150px;
            height: 150px;
        }

        /*提示信息*/
        .hint {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0;
            background-color: #3C3C3C;
            opacity: .8;
            text-align: center;
            z-index: 999;
            color: white;
        }

        .hint>div {
            font-size: 20px;
            position: absolute;
            top: 20%;
            left: 50%;
            margin-left: -100px;
        }

        .hint p {
            margin: 1px 0;
        }

        .hide {
            display: none;
        }
    style>
head>

<body>
    <canvas id="canvas" width="150" height="150">cannot support canvascanvas>

    
    <ul id="game">
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
    ul>
    <div class="hint hide">
        <div>
            <p>恭喜你!你已经通过!p>
            <p>已击败 96%的人p>
            <p id="next">点击进入下一关!p>
        div>
    div>
    <script>
        //使用面向对象(组合模式)编程
        function Puzzle() { //放私有属性
            this.ctx = canvas.getContext('2d'); //画笔,canvas是一个html中的特定的canvas元素
            this.imgList = document.querySelectorAll('#game img'); 
            this.imgArr = Array.from(this.imgList);//es6 
            console.log(this.imgList);           
        }

        Puzzle.prototype = {
            init: function (url) { //初始化(进行图片的切图并导出)
                var image = new Image(); //创建游离的img元素
                /*
                new Image()和document.createElement('img');
                是一样的,创建了一个游离(未挂在到DOM中)的元素 
                */
                image.src = url; //将要处理的图片地址放入src属性
                image.onload = function() {
                    this.randomImg();//打乱顺序,再渲染
                    this.renderImg(image);                    
                }.bind(this);
            },
            //进行图片的渲染并导出
            renderImg: function (image) {
                var index = 0;
                for (var i = 0; i < 3; i++) {
                    for (j = 0; j < 3; j++) {
                        //i,j坐标图如下
                        //(0,0)(0,1)(0,2)
                        //(1,0)(1,1)(1,2)
                        //(2,0)(2,1)(2,2)
                        //所以j,i的坐标刚好和上面的9对值相反
                        this.ctx.drawImage(image, 300 * j, 300 * i, 300, 300, 0, 0, 150, 150);

                        this.imgArr[index].src = canvas.toDataURL('image/jpeg');   
                        index++;                   
                    }
                }
            },
            //图片的随机排序
            randomImg: function() {//imgList是DOM里面的类数组,没有原生js中的sort方法
                this.imgArr.sort(function() {
                    return Math.random()-Math.random();
                })
            }
        }
        var puzzle = new Puzzle();
        puzzle.init('img/jinxuanya.jpg');
    script>
body>

html>

拖拽事件 – 实现数据交换


<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JavaScript经典进阶:实现拼图游戏title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        h2 {
            text-align: center;
            margin-top: 80px;
        }

        #canvas {
            display: none;
        }

        #game {
            max-width: 456px;
            margin: 130px auto;
            margin-top: 10px;
        }

        #game>li {
            width: 150px;
            height: 150px;
            float: left;
            list-style: none;
            margin: 1px;
        }

        #game>li img {
            width: 150px;
            height: 150px;
        }

        /*提示信息*/
        .hint {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0;
            background-color: #3C3C3C;
            opacity: .8;
            text-align: center;
            z-index: 999;
            color: white;
        }

        .hint>div {
            font-size: 20px;
            position: absolute;
            top: 20%;
            left: 50%;
            margin-left: -100px;
        }

        .hint p {
            margin: 1px 0;
        }

        .hide {
            display: none;
        }
    style>
head>

<body>
    <canvas id="canvas" width="150" height="150">cannot support canvascanvas>


    <ul id="game">
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
        <li><img src="" alt="" draggable="true">li>
    ul>
    <div class="hint hide">
        <div>
            <p>恭喜您!顺利通关!p>
            <p>已击败全国 99% 的人p>
            <p id="next">点击进入下一关!p>
        div>
    div>
    <script>
        (function() {//注册一个事件处理函数,拼图 正确的完成后,显示指定元素的内容,点击后关闭此内容
            var hideElement = document.getElementsByClassName('hide')[0];
            hideElement.addEventListener('click', function() {
                hideElement.style.display = 'none';
                location.reload();
            },false)
        })();
        //使用面向对象(组合模式)编程
        function Puzzle() { //放私有属性
            this.ctx = canvas.getContext('2d'); //画笔,canvas是一个html中的特定的canvas元素
            this.imgList = document.querySelectorAll('#game img');
            this.imgArr = Array.from(this.imgList); //es6         
        }

        Puzzle.prototype = {
            init: function (url) { //初始化(进行图片的切图并导出)
                var image = new Image(); //创建游离的img元素
                /*
                new Image()和document.createElement('img');
                是一样的,创建了一个游离(未挂在到DOM中)的元素 
                */
                image.src = url; //将要处理的图片地址放入src属性
                image.onload = function () {
                    this.randomImg(); //打乱顺序,再渲染
                    this.renderImg(image);
                    this.dragEvent();
                }.bind(this);

            },
            //进行图片的渲染并导出
            renderImg: function (image) {
                var index = 0;
                for (var i = 0; i < 3; i++) {
                    for (j = 0; j < 3; j++) {
                        //i,j坐标图如下
                        //(0,0)(0,1)(0,2)
                        //(1,0)(1,1)(1,2)
                        //(2,0)(2,1)(2,2)
                        //所以j,i的坐标刚好和上面的9对值相反
                        this.ctx.drawImage(image, 300 * j, 300 * i, 300, 300, 0, 0, 150, 150);

                        this.imgArr[index].src = canvas.toDataURL('image/jpeg');
                        this.imgArr[index].id = index;
                        index++;
                    }
                }
            },
            //图片的随机排序
            randomImg: function () { //imgList是DOM里面的类数组,没有原生js中的sort方法
                this.imgArr.sort(function () {
                    return Math.random() - Math.random();
                })
            },

            //拖拽事件
            dragEvent: function () {
                //事件代理
                var container = document.getElementById('game');

                container.addEventListener('dragover', function (e) {
                    e.preventDefault(); //如果没有调用这个阻止函数,则目标元素在 dragstart 后,元素无法拖动
                }, false);

                container.addEventListener('dragstart', function (e) {
                    var target = e.target;
                    if (target.tagName.toLowerCase() == 'img') {
                        e.dataTransfer.setData('id', target.id);
                    }
                }, false); //false表示--事件冒泡为否

                container.addEventListener('drop', function (e) {

                    var target = e.target; //drop事件触发的是鼠标 拖拽后释放 所指的元素
                    if (target.tagName.toLowerCase() == 'img') {
                        var originObj = document.getElementById(e.dataTransfer.getData('id'));
                        var endObj = target;
                        [originObj.src, endObj.src] = [endObj.src, originObj.src];
                        [originObj.id, endObj.id] = [endObj.id, originObj.id];
                        //两行代码实现数据交换,不要太爽  
                        var newImgArr = document.querySelectorAll('#game img');
                        var idArr = [];
                        for (i = 0; i < 9; i++) {
                            idArr.push(newImgArr[i].id);
                        }
                        console.log(idArr.toString());
                        if (idArr.toString() == [0, 1, 2, 3, 4, 5, 6, 7, 8].toString()) {
                            document.getElementsByClassName('hide')[0].style.display = 'block';
                        }
                    }
                }, false);
            }
        }
        var puzzle = new Puzzle();
        puzzle.init('img/jinxuanya.jpg');
    script>
body>

html>

你可能感兴趣的:(前端实战)