前端那些事之原生js实现九宫格转盘

本文介绍如何使用原生JavaScript实现一个九宫格转盘抽奖效果,包括HTML和CSS布局、JavaScript逻辑处理及动画效果实现。

原生js实现九宫格转盘

知识点:js的闭包和原型

1:html和css

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>九宫格大转盘的实现</title>
    <style>
        body, div, ul, li, img {
            margin: 0 auto;
            padding: 0px;
        }

        ul, li {
            list-style: none;
        }

        body {
            background: #ff5757;
        }

        .lottery {
            width: 640px;
            height: 640px;
            overflow: hidden;
            background: rgba(0, 0, 0, 0.5);
        }

        .lottery li {
            float: left;
            width: 178px;
            height: 178px;
            padding: 5px;
            margin-left: 20px;
            margin-top: 20px;
            position: relative;
            overflow: hidden;
            background: #fff;
        }

        .lottery li .img {
            width: 178px;
            height: 178px;
            transform: translateY(-200px) rotateX(360deg);
            transition: all 1s;
        }

        .lottery li.active .img {
            transform: translateY(0px) rotateX(0deg);
        }

        .lottery li .blur {
            position: absolute;
            left: 5px;
            top: 5px;
            width: 178px;
            height: 178px;
            background: url(./img/card.png) center center no-repeat;
            background-size: 100% 100%; /*让图片100%显示*/
            transition: all 1s;
        }
        .lottery li.active .blur {
            transform: translateY(-200px) rotateX(360deg);
        }
        .lottery li.lottery-position{
            animation:lotterSlide .1s 30 both;
        }
        @keyframes lotterSlide{
            50%{
                background:#fff;
            }
            100%{
                background:#f00;
            }
        }
    </style>
</head>
<body>
<div class="lottery">
    <ul id="lotteryList">
        <li class="list0">
            <img src="img/0.png" class="img"/>
            <div class="blur"></div>
        </li>
        <li class="list1">
            <img src="img/1.png" class="img"/>
            <div class="blur"></div>
        </li>
        <li class="list2">
            <img src="img/2.png" class="img"/>
            <div class="blur"></div>
        </li>
        <li class="list7">
            <img src="img/3.png" class="img"/>
            <div class="blur"></div>
        </li>
        <li>
            <img src="img/card.png" class="img"/>
            <div class="blur"></div>
        </li>
        <li class="list3">
            <img src="img/4.png" class="img"/>
            <div class="blur"></div>
        </li>
        <li class="list6">
            <img src="img/5.png" class="img"/>
            <div class="blur"></div>
        </li>
        <li class="list5">
            <img src="img/6.png" class="img"/>
            <div class="blur"></div>
        </li>
        <li class="list4">
            <img src="img/7.png" class="img"/>
            <div class="blur"></div>
        </li>
    </ul>
</div>
<script src="js/award.js"></script>
<script>
    //调用
    award.init({
        lotteryLi: document.getElementById("lotteryList").children,
        awardUrl:"award.json",
        arr: [0, 1, 2, 3, 4, 5, 6, 7]
    })
</script>
</body>
</html>

2.js部分

//实现步骤
/*前提是有布局
 开发并不复杂,关键在于基础
 1、传入参数并接收
 2、初始化点击事件
 点击 -
 3、从服务器获取抽奖位置
 4、随机分配显示位置,这里需要注意:点击位置的金额必须是从服务器获取的金额
 5、翻牌
 */
(function (window, undefind) {
    "use strict";
//         构造涵数
    function Award() {
    }
    //prototype:追加方法或原型,init是自定义的,但是名字尽量语义化
    //opts就是传入的参数,简称为形参
    Award.prototype.init = function (opts) {//实例化参数
        /*
         是否可点
         点击的是第几个
         */
        this.isClick = true;//是否可点击,默认为可点
        this.number = 0;//点击的数量
        this.position;//点击的位置
        this.opts = {
            "lotteryLi": "",
            "awardUrl": "",
            "arr": [0, 1, 2, 3, 4, 5, 6, 7]
        };
        this.opts = this.extend(this.opts, opts);
        //在jquery中是有extend复制参数的
        this.bindeEvent();
    }
    //extend方法的实现
    Award.prototype.extend = function () {//把传过来的参数复制
        var args = arguments;//通过arguments指导传入的个数
        if (args.length < 2) {
            return;//如果少于两个参数就不操作
        }
        var temp = this.cloneObj(args[0]);
        for (var i = 1; i < args.length; i++) {
            for (var n in args[i]) {
                temp[n] = args[i][n];
            }
        }
        console.log(temp);
        return temp;
    }
//克隆方法的实现
    Award.prototype.cloneObj = function (oldObj) {
        if (typeof(oldObj) != 'object' || oldObj == null) {
            return oldObj;
        }
        var newObj = {};
        for (var i in oldObj) {
            newObj[i] = this.cloneObj(oldObj[i]);
        }
        return newObj;
    }
//绑定事件
    Award.prototype.bindeEvent = function () {//初始化点击事件
        var _this = this;//区分当前对象
        for (var i = 0; i < _this.opts.lotteryLi.length; i++) {
            _this.opts.lotteryLi[i].onclick = function () {
                var currClass = this.className;
                if (this.className == "") {//点击中间
                    alert("不要点击中间");
                } else if (currClass.indexOf("active") < 0) {//没有选中
                    _this.number = Number(currClass.replace("list", "").trim())//Number转义为数字类型
                    _this.opts.arr = _this.opts.arr.sort(function () {
                        return 0.5 - Math.random();
                    });
                    _this.awardPosition();//中间金额
                } else {
                    alert("您已经抽过奖");
                }
            }
        }
    }
    //中间金额
    Award.prototype.awardPosition = function () {
        var _this = this;
        //获取位置需要从服务器获取
        /*
         ajax有五个步骤
         0:创建
         1:打开
         2:发送
         3:响应数据
         4:完成
         */
        var xhr = new XMLHttpRequest();//IE:ActiveXObject创建
        xhr.onreadystatechange = function () {//检测状态,当状态改变则返回
            if (xhr.status == 200) {//200是页码,200表示正常,404找不到页面
                if (xhr.readyState == 4) {//4表示加载完成
                    var data = JSON.parse(xhr.responseText);
                    _this.position = data.position;//保存从服务器获取的金额
                    //为了显示点击位置就是从服务器获取的中奖金额,必须把数组里面的中奖金额剔除,然后增加到第一个位置
                    for (var m = 0; m < _this.opts.arr.length; m++) {
                        if (_this.opts.arr[m] == _this.position) {
                            _this.opts.arr.splice(m, 1);
                            break;
                        }
                    }
                    _this.opts.arr.splice(0, 0, _this.position);
                    _this.lotterySlide();//显示翻转动画
                    _this.isClick = false;//禁止可点
                    return;//结束
                }
            }
        }
        xhr.open("post", _this.opts.awardUrl, true);//post/get,url,true/false打开
        xhr.setRequestHeader("Content-Type", "application/www-x-form-urlencoded");//设置请求头部
        xhr.send(null);//这里传入参数,可以为空
    }
    //改变图片的位置
    Award.prototype.lotterySlide = function () {//改变图片显示
        var _this = this;//区分对象区域
        var nums = 0;
        var awardNums = this.opts.arr.length;//由于是组件,所以获取个数
        var lottery = window.setInterval(function () {//通过定时器延迟显示
            if (document.getElementsByClassName("active").length > (awardNums - 1)) {
                document.getElementsByClassName("list" + _this.number % awardNums)[0].className = "list" + _this.number % awardNums + " active lottery-position"
                clearInterval(lottery);
            } else {
                //这里分为两个步骤,一个改变图片,一个拉开图片
                document.getElementsByClassName("list" + _this.number % awardNums)[0].children[0].setAttribute("src", "img/" + _this.opts.arr[nums] + ".png");
                document.getElementsByClassName("list" + _this.number % awardNums)[0].className = "list" + _this.number % awardNums + " active";
                nums += 1;
                _this.number += 1;
            }
        }, 200);
    }
    var awrad = new Award();
    window["award"] = awrad;
}(window));

 

转载于:https://my.oschina.net/yongxinke/blog/851985

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值