純CSS3大轉盤抽獎(響應式、可配置)

来源:http://www.cnblogs.com/givebest/archive/2017/01/08/6262812.html
-Advertisement-
Play Games

源於前段時候微信小程式最初火爆公測時段,把以前用 Canvas 實現的大轉盤抽獎移植成微信小程式,無奈當時小程式對 Canvas 支持不夠完善,只好降低用 CSS3 實現。雖然比不上 Canvas 繪圖的絢麗,但也總算完成了一個抽獎的 Demo,詳見: "https://github.com/giv ...



源於前段時候微信小程式最初火爆公測時段,把以前用 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;
    width: 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;
    width: 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;
    width: 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;
    width: inherit;
    height: inherit;
    z-index: 9999
}

.gb-wheel-item {
    position: absolute;
    left: 0;
    top: 0;
    width: 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;
    width: inherit;
    height: inherit;
    z-index: 99
}

.gb-wheel-litem {
    position: absolute;
    left: 14rem;
    top: 0;
    width: 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;
    width: 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;
    width: 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-width: 320px) {
    html {
        font-size: 10px
    }
}

@media only screen and (min-width: 375px) {
    html {
        font-size: 11.71875px
    }
}

@media only screen and (min-width: 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魔法譯。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、服務 AngularJS功能最基本的組件之一是服務(Service)。服務為你的應用提供基於任務的功能。服務可以被視為重覆使用的執行一個或多個相關任務的代碼塊。 AngularJS服務是單例對象,這意味著只有一個實例被創建過,服務使用AngularJS的依賴註入機制來定義和註冊。 可以把服務註入 ...
  • 目錄 背景與邊框第一部分 背景與邊框第二部分 形狀 視覺效果 字體排印 用戶體驗 結構與佈局 過渡與動畫 源碼下載 一、緩動效果 學習和利用貝塞爾曲線,預設支持ease,ease-in,ease-out,ease-in-out和linear等 還提供一個cubic-beizer自定義貝塞爾曲線的起點 ...
  • 歷經一年的等待後,小程式在2017年1月9日凌晨終於揭開神秘面紗,正式上線。 ...
  • 正則表達式 一、正則表達式定義 JavaScript 正則表達式 正則表達式(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE)使用單個字元串來描述、匹配一系列符合某個句法規則的字元串搜索模式。 搜索模式可用於文本搜索和文本替換。 簡單的說就是一個有規則的表 ...
  • 對於數據結構“樹”,想必大家都熟悉,今兒,我們就再來回顧一下數據結構中的二叉樹與樹,並用JavaScript實現它們。 ...
  • 背景 我相信很多朋友跟我一樣,初次聽到什麼Flux, Redux, Vuex,狀態管理的時候是一臉懵逼的。因為在外面之前前端大部分開發的時候,根本沒有那麼多的概念。自從ReactJS火爆後,什麼Flux, Redux,React全家桶是一套一套接踵而來。搞的很多開發者甚是頭大。所謂的ReactJS全 ...
  • 1 掘金 新標簽預設打開,每日熱門前端內容,Github熱門star數,讓你不out 2 谷歌訪問助手 你懂的 3 react developer tools react代碼調試工具,查看state和props 4 Vue.js devtools 同上 5 WEB前端助手(FeHelper)* 百度 ...
  • 0.float與margin 兩個相鄰的浮動元素,當第一個浮動元素(不論是左浮動還是右浮動)的寬度為100%時,第二個浮動元素會被擠到下麵,通過添加負margin-right值(絕對值最少等於它自身的寬度),可以使它回到第一行。 在書寫html代碼時,我們通常的習慣根據UI樣式,從左往右來寫代碼,但 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...