Angular4 自制华容道拼图(可以升级难度、关卡、更换图片)

前端工程师新手一枚,之前一直做些小设计,以及静态页面的编写工作。刚刚接触 Angular 没有多久,四个月前对于 js 也只是会写 alert 之流,现在进步算是很大,下面是自制的华容道拼图(可以升级难度、关卡、更换图片,查看完整大图),希望大神临幸,千万别拍砖。

图片背景是用根据宽度,列数算好的公式用css写上去的,所以不同的列数,背景图片的比例不同,写着非常麻烦,但是又找不到简单方法,所以我只写到了第六关,希望有大神指点~~

第三关: 四列/15块儿


HTML:

<div class="gigContent">
    <div class="paddingv10 borderb bg-white">
        <span class="paddingr30">Section: {{colomnData.barrier}}</span>
        <span class="paddingr30">Step: {{step}}</span>
        <button (click)="resetFn()" class="flexWidth">Reset</button>
        <button (click)="changePicFn()" class="flexWidth">Change Picture</button>
        <button (click)="ifViewPic = true" class="flexWidth">View big picture</button>
    </div>
    <ul class="gigItem" [ngStyle]="getColumnWidth()">
        <li *ngFor="let puzzle of puzzles; let i = index" (click)="moveBoxFn(i)" [ngClass]="{'empty': puzzle == '', 'full': puzzle != ''}" [ngStyle]="getPicPosition(puzzle)">
        </li>
    </ul>
</div>

<div class="mask" *ngIf="ifViewPic">
    <img src="../../assets/images/pic{{imgRandom}}.jpg" style="width: 500px;" />
    <br/>
    <button (click)="ifViewPic = false" class="flexWidth">Close</button>
</div>

  

CSS:

.mainContent {
    width: 1000px;
    box-sizing: border-box;
}
.gigContent {
    width: 100%;
    min-height: 500px;
    text-align: center;
}
.gigContent .gigItem{
    margin: 20px auto 0;
}
.gigContent .gigItem li {
    list-style-type: none;
    width: 100px;
    height: 100px;
    float: left;
    line-height: 100px;
    text-align: center;
    color: #dedede;
    font-size: 26px;
    font-weight: bolder;
    box-sizing: border-box;
    border: solid 1px #dedede;
}
.gigContent .gigItem li.full {
    background-repeat: no-repeat;
    background-color: orange;
}
.gigContent .gigItem li.empty {
    background-image: none!important;
    border: none;
}
.gigContent .gigItem li.full:hover {
    cursor: pointer;
    box-shadow: 0px 0px 10px #fff;
}
.gigContent .gigItem:before, .gigContent .gigItem:after {
    content: '';
    display: block;
    clear: both;
}
.mask {
    font-size: 26px;
    color: orange;
    font-weight: bolder;
    text-align: center;
    padding-top: 100px;
}

TS:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component ({
    templateUrl: './gigsaw.component.html',
    styleUrls: ['./gigsaw.component.css']

})

export class GigsawComponent implements OnInit {
    private puzzles: Array<any>;  // 随机生成的乱序数组
    private positionArr: Array<any>; // 每点击一块儿,会生成其上下左右位置的数组
    private emptyBox: any; // 空白小块儿
    private boxMovable: boolean = false; // 图片是否可以移动
    private isSuccessful: boolean = false; // 是否过关
    private step: number = 0; // 移动步数
    private colomnData: any = { barrier: 3, colomNum: 4, totalNum: 15 }; // 关卡数、列数、小块儿总数
    private imgRandom: number; // 随机选择图片
    private ifViewPic: boolean = false; // 是否查看大图
    
    constructor(private router: Router){}
    
    ngOnInit(){
        this.resetFn();
        this.changePicFn();
    }

    resetFn(){
        let puzzlesRandom = [];
        // 根据关卡数,生成相应的数组
        for(let i = 1; i <= this.colomnData.totalNum; i++){
            puzzlesRandom.push(i);
        }
        // 将数组打乱
        this.puzzles = puzzlesRandom.sort(() => {
            return Math.random() - 0.5;
        });
        // 将空白块儿加入
        this.puzzles.push('');
        this.step = 0;
    }

    changePicFn(){
        this.imgRandom = Math.round( Math.random() * 4 + 1);
    }

    checkMovableFn(index: number){ // 查看所点击图片是否可以移动
        // 获取所点击图片位置以及上下左右坐标        
        this.positionArr = [
            { name: 'curNum', value: this.puzzles[index], position: index },
            { name: 'topNum', value: this.puzzles[index - this.colomnData.colomNum], position: index - this.colomnData.colomNum },
            { name: 'btmNum', value: this.puzzles[index + this.colomnData.colomNum], position: index + this.colomnData.colomNum },
            { name: 'lftNum', value: this.puzzles[index - 1], position: index - 1 },
            { name: 'ritNum', value: this.puzzles[index + 1], position: index + 1 }
        ]
        // 如果所点击的图片不是空白块儿,将value为空的一项赋值给emptyBox
        if(this.puzzles[index] != ''){
            this.emptyBox = this.positionArr.filter(function (k, v) { return k.value == '' })[0];
            // 如果emptyBox有值,则表示周围有空白块,可以移动
            if(this.emptyBox != undefined){
                this.boxMovable = true;
            }
        }
    }

    moveBoxFn(index: number){
        // 移动小块儿,将被点击小块儿的值赋值给空白块儿,将被点击小块儿设置为空
        this.boxMovable = false;
        this.checkMovableFn(index);
        if(this.boxMovable) {
            this.puzzles[this.emptyBox.position] = this.puzzles[index];
            this.puzzles[index] = '';
            this.step++;
        }
        setTimeout(() => {
            this.isSuccessfulFn();
        }, 100);
    }

    
    
    isSuccessfulFn(){
        for(let i = 1; i <= this.colomnData.totalNum; i++) {
            if(this.puzzles[i-1] != i) {
                this.isSuccessful = false;
                return;
            }
        }
        this.isSuccessful = true;
        if(this.isSuccessful){
            let temConfirm = confirm('Conguratulations! You win! \n Would you like to go to next section?')
            if(temConfirm){
                this.getNextSectionFn();
            } else {
                this.router.navigate(['/home']);
            }
        }
    }

    getNextSectionFn(){ // 进入下一关
        this.colomnData.barrier = this.colomnData.barrier + 1;
        this.colomnData.colomNum = (this.colomnData.barrier + 1) ;
        this.colomnData.totalNum = this.colomnData.colomNum * this.colomnData.colomNum - 1;
        if(this.colomnData.barrier >= 6) {
            alert('Congaratulations! You pass all the sections!')
            this.router.navigate(['/home']);
        }
        this.resetFn();
        this.changePicFn();
    }
    
    getColumnWidth(){ // 根据列数设置外层盒子的宽度
        return { width: this.colomnData.colomNum * 100 + 'px' };
    }
    getPicPosition(index: number){ // 根据列数调整背景图片的位置!!! 好难
        let posX, posY;
        for(let n = 0; n < this.colomnData.colomNum; n++) {
            if (index == this.colomnData.colomNum*n) {
                posX = '100%';
            } else if (index == this.colomnData.colomNum * n + 1){ 
                posX = '0%';
            }  
            else if (index == this.colomnData.colomNum * n + 2) { 
                posX = 100/(this.colomnData.colomNum - 1) + '%';

            } else if (index == this.colomnData.colomNum * n + 3) { 
                posX = 100/(this.colomnData.colomNum - 1) * 2 + '%';

            } else if (index == this.colomnData.colomNum * n + 4) { 
                posX = 100/(this.colomnData.colomNum - 1) * 3 + '%';
                
            } else if (index == this.colomnData.colomNum * n + 5) { 
                posX = 100/(this.colomnData.colomNum - 1) * 4 + '%';
            }
        }
       
        if (index <= this.colomnData.colomNum) {
            posY = '0%';
        } else if (index > this.colomnData.colomNum && index <= this.colomnData.colomNum * 2){
            posY = 100/(this.colomnData.colomNum - 1) + '%';
        } else if (index > this.colomnData.colomNum * 2 && index <= this.colomnData.colomNum * 3) {
            posY = 100/(this.colomnData.colomNum - 1) * 2 + '%';
        } else if (index > this.colomnData.colomNum * 3 && index <= this.colomnData.colomNum * 4) {
            posY = 100/(this.colomnData.colomNum - 1) * 3 + '%';
        } else if (index > this.colomnData.colomNum * 4 && index <= this.colomnData.colomNum * 5) {
            posY = 100/(this.colomnData.colomNum - 1) * 4 + '%';
        } else if (index > this.colomnData.colomNum * (this.colomnData.colomNum - 1) 
                && index < this.colomnData.colomNum * this.colomnData.colomNum ){
            posY = '100%';
        }

        return { backgroundPositionX: posX, backgroundPositionY: posY, 
                 backgroundSize: this.colomnData.colomNum * 100 + 'px', 
                 backgroundImage: 'url(\"../../assets/images/pic' + this.imgRandom + '.jpg\")'  };
    }
}

  

猜你喜欢

转载自www.cnblogs.com/junyuan-frontend/p/angular_gigsaw.html