乐高拼图功能实现

这里写图片描述

HTML片段

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/bootstrap.css"/>
    <link rel="stylesheet" href="css/index.css"/>
    <link rel="stylesheet" href="css/toastr.min.css">

    <script src="js/other/jquery-1.11.3.js"></script>
    <script src="js/other/bootstrap.js"></script>
    <script src="js/other/drag.js"></script>
    //Fdrag.js 为自定义文件
    <script src="js/other/Fdrag.js"></script>
    <script src="js/other/toastr.js"></script>
    <!-- HTML5 Shim 和 Respond.js 用于让 IE8 支持 HTML5元素和媒体查询 -->
    <!-- 注意: 如果通过 file://  引入 Respond.js 文件,则该文件无法起效果 -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>       <![endif]-->
</head>
<body>
<div class="nav">
    <div class="col-sm-5"><img style="margin: 20px 15px 0 40px;" src="images/sia.png" alt=""><img style="margin: 20px 0 0 0;" src="images/sia-title.png" alt=""></div>
    <div class="nav-title">乐高拼图</div>
    <div class="col-sm-2 col-sm-offset-5"><img style="margin: 20px 15px 0 40px;" src="images/logo.png" alt=""></div>
</div>
<div class="content">
    <div class="col-sm-7 left-part" style="height: 100%">
        <div class="background-color exhibit shadow" style="height: 100%">
            <div class="putLego parent">
                <div class="dragContainer"></div>
                <div class="clearDrag btn btn-success">重置</div>
            </div>
        </div>
    </div>
    <div class="col-sm-5">
        <div class="row">
            <div class="background-color shadow parent">
                <div class="m2-2"></div><div class="m2-picker color-picker"><div class="c-red"></div><div class="c-yellow"></div><div class="c-green"></div><div class="c-blue"></div><div class="c-orange"></div></div>
                <div class="m2-3"></div><div class="m3-picker color-picker"><div class="c-red"></div><div class="c-yellow"></div><div class="c-green"></div><div class="c-blue"></div><div class="c-orange"></div></div>
                <div class="m2-4"></div><div class="m4-picker color-picker"><div class="c-red"></div><div class="c-yellow"></div><div class="c-green"></div><div class="c-blue"></div><div class="c-orange"></div></div>
                <div class="m2-6"></div><div class="m6-picker color-picker"><div class="c-red"></div><div class="c-yellow"></div><div class="c-green"></div><div class="c-blue"></div><div class="c-orange"></div></div>
            </div>
        </div>
        <div class="ol">
            <div>操作说明: </div>
            <div class="ol-explain">1. 在您所需要的乐高积木块右侧点选您需要的颜色</div>
            <div class="ol-explain">2. 颜色选择完毕后,在乐高积木块处 <b>点击</b> 可在乐高容器内生成</div>
            <div class="ol-explain">3. 在乐高容器内可以随意拖拽乐高积木块</div>
            <div class="ol-explain">4. 在乐高积块木上 <b>双击</b> 可旋转</div>
        </div>
        <div class="row">
            <button class="orderButton fr">确认下单</button>
        </div>
    </div>
</div>

</body>
</html>

JS

$(document).ready( function() {
    toastr.options={
        closeButton: true,
        positionClass :"toast-botton-right",
    };

    var backArr = [];
    var ss = '';
    var backInfo = '';
    var colorList = ['#E84640','#f2f650','#71DE62','#1F58E5','#FF984B'];
    var colorNum = ['0','0','0','0','0'];

    var step;
    $(window).width()>1600 ? step = 30 : step = 20;

    //用数组表示活动区域
    var space = [
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    ];

    $('.m2-picker div').click(function(){
        var index = $(".m2-picker div").index(this);
        colorPicker(2,index)
    });
    $('.m3-picker div').click(function(){
        var index = $(".m3-picker div").index(this);
        colorPicker(3,index)
    });
    $('.m4-picker div').click(function(){
        var index = $(".m4-picker div").index(this);
        colorPicker(4,index)
    });
    $('.m6-picker div').click(function(){
        var index = $(".m6-picker div").index(this);
        colorPicker(6,index)
    });
    function colorPicker(n,index) {
        $('.m2-'+n).css("background",colorList[index]);
        colorNum[(n-2)] = index;
    }

    $('.m2-2').click(function(){
        initBlock(2);
    });
    $('.m2-3').click(function(){
        initBlock(3);
    });
    $('.m2-4').click(function(){
        initBlock(4);
    });
    $('.m2-6').click(function(){
        initBlock(6);
    });
    function initBlock(n) {
        if(colorNum[(n-2)] == -1){
            toastr.warning("请先初始化颜色!");
        }else{
            var info = findEmpty(n,2);
            if(typeof(info)=="undefined"){
                toastr.warning("没有适合的地方可以放了!");
            }else{
                //添加一个元素
                addBlock('draggable', info[0]*step, info[1]*step, n, 2);
            }
        }
    }

    //添加块
    function addBlock(type, x, y, w, h) {

        var container = $('.dragContainer');
        var block = $('<div></div>');
        //为创建模块加类属性        居中                         宽长     高度
        block.addClass(type + ' parent position-absoulte w-'+w+'x h-'+h+'x');
        block.css('left', x);
        block.css('top', y);
        block.css('background', colorList[colorNum[(w-2)]]);
        block.on( 'dragStart', dragStart);
        block.on( 'dragEnd', dragEnd);
        block.on( 'dblclick', roate);
        block.draggabilly({
            containment:container,
            grid:[step,step]
        });
        block.data('draggabilly');
        block.appendTo(container);

        block.attr('w',w);
        block.attr('h',h);
        block.attr('color',colorNum[(w-2)]);

        //生成模块后将该位置 置一
        To1(x/step, y/step, w, h, colorNum[(w-2)]);

    }

    $('.clearDrag').click(function(){
        clearDrag();
    });

    //清除 页面所有模块
    function clearDrag(){
        $('.dragContainer').html("");
        space = [
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        ];
        backArr = [];
        ss = '';
    }

    var boundary = space[0].length;
    //归一
    function To1 ( x, y, w, h, color ) {

        for (var i = x ; i < (x + w); i++ ) {
          for ( var j = y ; j < (y + h); j++ ) {
            space[j][i] = 1;
          }
        }

        x = PrefixInteger(2*x + w  - boundary);
        y = PrefixInteger(boundary - h - 2*y);

        backArr.splice(0,0,[Number(color+1), x, y, w+''+h, 'X']);

        backInfo = backString(backArr);

        console.log(backInfo);
    }

    function PrefixInteger(num) {

        //位数
        var n = 2;
        var sign = ['-','0'];
        //坐标正负标志位
        var current = '';

        if( num < 0 ){
            current = sign[0];
            num *= -1;
        }else{
            current = sign[1];
        }
        num = num.toString();

        var s_length = n - num.length;
        if(num.length < n){
            for (var i= 0;i<s_length;i++){
                num = "0" + num;
            }
        }

        return current + num;
    }

    //归零
    function To0 ( x, y, w, h ) {

        for ( var q = x; q < (x + w); q++ ) {
            for ( var p = y ; p < (y + h); p++ ) {
                space[p][q] = 0;
            }
        }

        deleteArr( x, y, w, h );
    }

    function deleteArr( x, y, w, h ) {

        x = 2*x + w  - boundary;
        y = boundary - h - 2*y;

        for( var i = 0; i < backArr.length; i++ ){
            if ( backArr[i][1] == PrefixInteger(x) ){
                if ( backArr[i][2] == PrefixInteger(y) ){
                    if ( backArr[i][3] == w+''+h ){
                        backArr.splice(i,1);
                        i--;
                    }
                }
            }
        }
    }

    //旋转
    function roate( event, pointer ) {

        var a = $(this).css('left');
        var b = $(this).css('top');

        a = a.substring(0, a.length - 2)/step;
        b = b.substring(0, b.length - 2)/step;

        //当前模块长宽
        var w = Number($(event.target).attr('w'));
        var h = Number($(event.target).attr('h'));
        var color = Number($(event.target).attr('color'));

        To0( a, b, w, h);

        if( testIn( a,b, h, w ) ){

            var block = $(event.target);
            reset( block, a, b, h, w, color);
            block.removeClass('w-'+w+'x').removeClass('h-'+h+'x').addClass('w-'+h+'x').addClass('h-'+w+'x');
            block.attr('w',h).attr('h',w);

        }else{
            var info = findEmpty( h, w);

            if(typeof(info)=="undefined"){
                toastr.warning("没有适合的地方可以旋转了!");
            }else{
                var x = info[0];
                var y = info[1];

                var block = $(event.target);
                reset( block, x, y, h, w, color);
                block.removeClass('w-'+w+'x').removeClass('h-'+h+'x').addClass('w-'+h+'x').addClass('h-'+w+'x');

                block.attr('w',h).attr('h',w);
            }
        }
    }

    //将返回数组变成字符串形式
    function backString(arr) {
        ss = '';
        var l = arr.length;
        for( var k = 0; k < l; k++ ){
            ss += arr[k].join("");
        }
        return ss;
    }

    //全局变量
    var resetX, resetY;

    //拖拽开始,记住块位置
    function dragStart(event, pointer ) {

        var draggie = $(this).data('draggabilly');

        resetX = draggie.position.x/step;
        resetY = draggie.position.y/step;

        //当前模块长宽
        var w = Number($(event.target).attr('w'));
        var h = Number($(event.target).attr('h'));

        //被托起的时候就置0  防止用户只挪动一步  检测错误
        To0(resetX, resetY, w, h);

    }

    //拖拽结束
    function dragEnd( event, pointer) {
        var draggie = $(this).data('draggabilly');

        //现在位置
        var a = draggie.position.x/step;
        var b = draggie.position.y/step;

        //当前模块长宽
        var w = Number($(event.target).attr('w'));
        var h = Number($(event.target).attr('h'));
        var color = Number($(event.target).attr('color'));

        if( testIn ( a, b, w, h ) ) {

            //被移动位置 置一
            To1( a, b, w, h, color );

        }else{

            //用于复位
            var block = $(event.target);
            reset( block, resetX, resetY, w, h, color);
        }
    }

    //复位块
    function reset( block, x, y, w, h, color) {

        block.css('left', x*step);
        block.css('top', y*step);

        //被移动位置 置一
        To1( x, y, w, h, color );
    }

    //监测放置位置是否有别的元素
    function testIn ( x, y, w, h ) {

        if( y + h > space.length ){
            return false;
        }
        if( x + w > space[0].length ){
            return false;
        }

        //列出当前元素想要放置的位置
        for  ( var i = x; i < x + w; i++ ) {
            for ( var j = y; j < y + h; j++ ){
                if ( space[j][i] ) {
                    return false;
                }
            }
        }
        return true;
    }

    //寻找空位置够大的坐标点
    function findEmpty( w, h ){

        var width = space[0].length - w + 1;
        var height = space.length - h + 1;

        for( var l = 0; l < height; l++ ){
            for ( var k = 0; k < width; k++ ){
                if( space[l][k] ){
                }else{
                    if( testIn(k, l, w, h) ){
                        return [ k, l ];
                    }
                }
            }
        }
    }
});

CSS

/*乐高界面*/
.nav{
    height: 80px;
}
.content{
    height: calc( 100% - 80px);
    padding: 20px;
}
.ol{
    color: #fff;
    margin: 40px;
    font-size: 1.3em;
}
.ol-explain{
    font-size: 1.2em;
    line-height: 1.8em;
    color: #ff9900;
}
.background-color{
    background: url("../images/shadow.png");
    background-size: 100% 100%;
    border-radius: 5px;
    padding: 10px 20px;
    overflow: hidden;
}
.putLego{
    height: 100%;
}
.productType{
    position: absolute;
    right:0;
    top:0
}
#letter{
    width:100%;
    height:50px;
    outline: none;
    border: none;
    background: transparent;
}
.c-num::-webkit-inner-spin-button {
    -webkit-appearance: none;
}
.c-num::-webkit-outer-spin-button {
    -webkit-appearance: none;   /* 有无看不出差别 */
}
.c-num{
    background: rgba(200,200,200,.4);
    outline: none;
    border: none;
    width: 80px;
    text-align: center;
    margin: 15px 20px;
}
.btn-green{
    background: #43B6B2;
}
.custom>div:not(:first-child){
    margin-top: 15px;
}
.rate{
    margin-top:30px;
}


.clearDrag{
    position: absolute;
    bottom: 22px;
    right: 65px;
}

.draggable{
    border-radius: 10px;
    float: left;
    border:2px solid #000;
    opacity: 0.7;
}

.draggable.is-dragging{ opacity: 0.7; z-index: 999; }

.m2-2,.m2-3,.m2-4,.m2-6{
    float: left;
    margin: 9px 0 9px 20px;
    border-radius: 5px;
    border: 2px solid #000;
    background: #e84640;
}
.m2-2{
    width:60px;
    height:60px;
}
.m2-3{
    width:90px;
    height:60px;
}
.m2-4{
    width:120px;
    height:60px;
}
.m2-6{
    width:180px;
    height:60px;
}

.dragContainer {
    border: 5px solid #F90;
    height: 730px;
    width: 731px;
    position: relative;
    background: url("../images/bg24.png");
    background-size: 100% 100%;
}
.w-2x{
    width:60px;
}
.w-3x{
    width:90px;
}
.w-4x{
    width:120px;
}
.w-6x{
    width:180px;
}
.h-2x{
    height:60px;
}
.h-3x{
    height:90px;
}
.h-4x{
    height:120px;
}
.h-6x{
    height:180px;
}

@media (max-width:1600px) {
    .dragContainer {
        border: 5px solid #F90;
        height: 490px;
        width: 491px;
        position: relative;
    }
    .w-2x{
         width:40px;
     }
    .w-3x{
        width:60px;
    }
    .w-4x{
        width:80px;
    }
    .w-6x{
        width:120px;
    }
    .h-2x{
         height:40px;
     }
    .h-3x{
        height:60px;
    }
    .h-4x{
        height:80px;
    }
    .h-6x{
        height:120px;
    }
}
.color-picker{
    width:12px;
    height:60px;
    float: left;
}
.c-red,.c-yellow,.c-blue,.c-green,.c-orange{
    width: 12px;
    height:20px;
}
.c-red{
    background: #E84640;
}
.c-yellow{
    background: #f2f650;
}
.c-blue{
    background: #1F58E5;
}
.c-green{
    background: #71DE62;
    display: none;
}
.c-orange{
    background: #FF984B;
    display: none;
}
.btn-style,.btn-style-s{
    background: #43B6B2;
    border-radius: 3px;
    cursor: pointer;
}
.btn-style{
    padding: 10px 45px;
    font-size: 1.3em;
}
.btn-style-s{
    padding: 5px 20px;
}
.lead-pic{
    height: 40px;
}
.btn-style:hover,.btn-style-s:hover,.btn-green:hover{
    background: #2f6e6a;
    color: #d8d8d8;
}
.orderButton{
    width: 100px;
    height: 40px;
    background: url("../images/order-button.png");
    background-size: 100% 100%;
    border: none;
    color: #fff;
    outline: none;
    cursor: pointer;
}
.orderButton:active{
    background: url("../images/order-click.png");
}
发布了38 篇原创文章 · 获赞 5 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_39423672/article/details/79694633