zoukankan      html  css  js  c++  java
  • 纯CSS3大转盘抽奖(响应式、可配置)


    源于前段时候微信小程序最初火爆公测时段,把以前用 Canvas 实现的大转盘抽奖移植成微信小程序,无奈当时小程序对 Canvas 支持不够完善,只好降低用 CSS3 实现。虽然比不上 Canvas 绘图的绚丽,但也总算完成了一个抽奖的 Demo,详见:https://github.com/givebest/wechat-turntalbe-canvas

    事后想起,CSS3 实现也并不是无有益处,比如简单、快捷、调试方便、渲染想来也是要比 Canvas 要高效的,更重要的一点是支持媒体查询,大转盘也可以做成响应式的。因此抽空整理,用纯 CSS3 实现一个大转盘抽奖 Demo 并记录下来。

    如果有类似需求并不想麻烦了解细节,可移步这里——Canvas 完整的大转盘抽奖项目(可以直接拿来用https://github.com/givebest/GB-canvas-turntable

    以下就直接贴代码了,后面有演示地址

    代码

    HTML

    <section class="gb-wheel-container" id="gbWheel">
        <div class="gb-wheel-content gb-wheel-run">
            <ul class="gb-wheel-line"></ul>
            <div class="gb-wheel-list"></div>
        </div>
        <a href="javascript:;" class="gb-wheel-btn" id="gbLottery">抽奖</a>     
    </section>
    

    JS

    (function() {
        // 奖品配置
        var awards = [
                {'index': 0, 'text': '耳机' , 'name': 'icono-headphone'},
                {'index': 1, 'text': 'iPhone' , 'name': 'icono-iphone'},
                {'index': 2, 'text': '相机' , 'name': 'icono-camera'},
                {'index': 3, 'text': '咖啡杯' , 'name': 'icono-cup'},
                {'index': 4, 'text': '日历', 'name': 'icono-calendar'},
                {'index': 5, 'text': '键盘', 'name': 'icono-keyboard'}
            ],
            len = awards.length,
            turnNum = 1 / len;  // 文字旋转 turn 值
    
        var gbWheel = $('gbWheel'),
            lineList = gbWheel.querySelector('ul.gb-wheel-line'),
            itemList = gbWheel.querySelector('.gb-wheel-list'),
            lineListHtml = [],
            itemListHtml = [];
    
        var transform = preTransform();
    
        awards.forEach(function(v, i, a) {
            // 分隔线
            lineListHtml.push('<li class="gb-wheel-litem" style="' + transform + ': rotate('+ (i * turnNum + turnNum / 2) +'turn)"></li>');
    
            // 奖项
            itemListHtml.push('<div class="gb-wheel-item">');
            itemListHtml.push('<div class="gb-wheel-icontent" style="' + transform + ': rotate('+ (i * turnNum) +'turn)">');
            itemListHtml.push('<p class="gb-wheel-iicon">');
            itemListHtml.push('<i class="'+v.name+'"></i>');
            itemListHtml.push('</p>');
            itemListHtml.push('<p class="gb-wheel-itext">');
            itemListHtml.push(v.text);
            itemListHtml.push('</p>');
            itemListHtml.push('</div>');
            itemListHtml.push('</div>');
        });           
    
        lineList.innerHTML = lineListHtml.join('');
        itemList.innerHTML = itemListHtml.join('');
    
        function $(id) {
            return document.getElementById(id);
        };
    
        // 旋转
        var i = 0;
        $('gbLottery').onclick = function() {
            i++;
            gbWheel.querySelector('.gb-wheel-content').style = transform + ': rotate('+ i * 3600 +'deg)';  
        }
    
        // transform兼容
        function preTransform() {
            var cssPrefix,
            vendors = {
              '': '',
              Webkit: 'webkit',
              Moz: '',
              O: 'o',
              ms: 'ms'
            },
            testEle = document.createElement('p'),
            cssSupport = {};
    
             // 嗅探特性
            Object.keys(vendors).some(function(vendor) {
                if (testEle.style[vendor + (vendor ? 'T' : 't') + 'ransform'] !== undefined) {
                  cssPrefix = vendor ? '-' + vendor.toLowerCase() + '-' : '';
                  return true;
                }
            });
    
          function normalizeCss(name) {
            name = name.toLowerCase();
            return cssPrefix ? cssPrefix + name : name;
          }
    
          cssSupport = {
            transform: normalizeCss('Transform'),
          }
    
          return cssSupport.transform;
        }
    }());
    

    CSS

    html {
        font-size: 10px
    }
    
    .gb-wheel-container ul,
    .gb-wheel-container li,
    .gb-wheel-container p {
        margin: 0;
        padding: 0
    }
    
    .gb-wheel-container ul,
    .gb-wheel-container li {
        list-style: none
    }
    
    .gb-wheel-container {
        margin: 0 auto;
        position: relative;
         30rem;
        height: 30rem;
        border-radius: 50%;
        box-shadow: 0 2px 3px #333, 0 0 2px #000;
        overflow: hidden
    }
    
    .gb-wheel-content {
        position: absolute;
        left: 1rem;
        top: 1rem;
        z-index: 2;
         28rem;
        height: 28rem;
        box-sizing: border-box;
        border-radius: inherit;
        background-clip: padding-box;
        background: -webkit-radial-gradient(rgba(100, 100, 100, 0.1) 15%, transparent 16%) 0 0, -webkit-radial-gradient(rgba(100, 100, 100, 0.1) 15%, transparent 16%) 8px 8px, -webkit-radial-gradient(rgba(255, 255, 255, 0.1) 15%, transparent 20%) 0 1px, -webkit-radial-gradient(rgba(255, 255, 255, 0.1) 15%, transparent 20%) 8px 9px;
        background: radial-gradient(rgba(100, 100, 100, 0.1) 15%, transparent 16%) 0 0, radial-gradient(rgba(100, 100, 100, 0.1) 15%, transparent 16%) 8px 8px, radial-gradient(rgba(255, 255, 255, 0.1) 15%, transparent 20%) 0 1px, radial-gradient(rgba(255, 255, 255, 0.1) 15%, transparent 20%) 8px 9px;
        background-color: #ffcb3f;
        background-size: 12px 14px
    }
    
    .gb-wheel-content:before {
        content: ' ';
        position: absolute;
        left: -1rem;
        top: -1rem;
        z-index: -1;
         28rem;
        height: 28rem;
        border-radius: inherit;
        border: 1rem solid #E44025;
        box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.2) inset
    }
    
    .gb-wheel-list {
        position: absolute;
        left: 0;
        top: 0;
         inherit;
        height: inherit;
        z-index: 9999
    }
    
    .gb-wheel-item {
        position: absolute;
        left: 0;
        top: 0;
         100%;
        height: 100%;
        color: #e4370e;
        font-weight: bold;
        text-shadow: 0 1px 1px rgba(255, 255, 255, 0.6)
    }
    
    .gb-wheel-icontent {
        position: relative;
        display: block;
        padding-top: 1.5rem;
        margin: 0 auto;
        text-align: center;
        -webkit-transform-origin: 50% 14rem;
        -ms-transform-origin: 50% 14rem;
        transform-origin: 50% 14rem
    }
    
    .gb-wheel-itext {
        font-size: 1.4rem;
        font-weight: lighter
    }
    
    .gb-wheel-iicon [class*=icono-] {
        color: #e4370e
    }
    
    .gb-wheel-line {
        position: absolute;
        left: 0;
        top: 0;
         inherit;
        height: inherit;
        z-index: 99
    }
    
    .gb-wheel-litem {
        position: absolute;
        left: 14rem;
        top: 0;
         1px;
        height: 14rem;
        background-color: rgba(228, 55, 14, 0.6);
        overflow: hidden;
        -webkit-transform-origin: 50% 14rem;
        -ms-transform-origin: 50% 14rem;
        transform-origin: 50% 14rem
    }
    
    .gb-wheel-btn {
        position: absolute;
        left: 11rem;
        top: 11rem;
        z-index: 400;
         8rem;
        height: 8rem;
        border-radius: 50%;
        color: #F4E9CC;
        background-color: #E44025;
        line-height: 8rem;
        text-align: center;
        font-size: 2rem;
        text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.6);
        box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6), 0 0 5px 4px rgba(0, 0, 0, 0.2) inset;
        text-decoration: none
    }
    
    a.gb-wheel-btn {
        border-bottom: none
    }
    
    .gb-wheel-btn::after {
        position: absolute;
        content: '';
        left: 2.5rem;
        top: -1rem;
         3rem;
        height: 3rem;
        background-color: #E44025;
        -webkit-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
        transform: rotate(45deg);
        box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6), 0 0 5px 4px rgba(0, 0, 0, 0.2) inset
    }
    
    .gb-wheel-btn.disabled,
    .gb-wheel-btn.disabled::after {
        pointer-events: none;
        background: #B07A7B;
        color: #ccc
    }
    
    .gb-wheel-run {
        -webkit-transition: transform 6s ease;
        transition: transform 6s ease
    }
    
    @media only screen and (min- 320px) {
        html {
            font-size: 10px
        }
    }
    
    @media only screen and (min- 375px) {
        html {
            font-size: 11.71875px
        }
    }
    
    @media only screen and (min- 480px) {
        html {
            font-size: 15px
        }
    }
    

    演示

    http://blog.givebest.cn/GB-css3-wheel.html

    项目

    https://github.com/givebest/GB-css3-wheel

    感谢

    奖品Icon来自:https://github.com/saeedalipoor/icono
    CSS3转盘背景来自:http://lea.verou.me/css3patterns/

    顺便推荐 Lea Verou(W3C CSS小组特邀专家) 的书《CSS Secrets: Better Solutions to Everyday Web Design Problems》,让你震撼,原来 CSS 还可以这样用、可以实现这么多绚丽的特效。 已有中文版《CSS揭秘》,CSS魔法译。

  • 相关阅读:
    129 01 Android 零基础入门 02 Java面向对象 06 Java单例模式 03 饿汉模式 VS 懒汉模式 02 懒汉式的代码实现
    128 01 Android 零基础入门 02 Java面向对象 06 Java单例模式 03 饿汉模式 VS 懒汉模式 01 饿汉式的代码实现
    127 01 Android 零基础入门 02 Java面向对象 06 Java单例模式 02 单例模式概述 01 单例模式的定义和作用
    126 01 Android 零基础入门 02 Java面向对象 06 Java单例模式 01 设计模式概述 01 设计模式简介
    125 01 Android 零基础入门 02 Java面向对象 05 Java继承(下)05 Java继承(下)总结 01 Java继承(下)知识点总结
    leetcode-----121. 买卖股票的最佳时机
    leetcode-----104. 二叉树的最大深度
    Json串的字段如果和类中字段不一致,如何映射、转换?
    Mybatis-Plus的Service方法使用 之 泛型方法default <V> List<V> listObjs(Function<? super Object, V> mapper)
    模糊查询
  • 原文地址:https://www.cnblogs.com/givebest/p/6262812.html
Copyright © 2011-2022 走看看