用 JavaScript 和 C3 實現一個轉盤小遊戲

本文主要介紹如何使用原生javascript和Css3來實現一個在各大移動應用中常常出現的轉盤遊戲,因爲改實現能夠有不一樣方式,若是熟悉canvas的話也能夠用canvas實現,本文采用js和css實現主要考慮到複雜度較小性能較好,因此若是有更好的方案,也能夠隨時和我交流。javascript

前言

本文技術路線採用和上篇文章教你用200行代碼寫一個愛豆拼拼樂H5小遊戲(附源碼)一樣的技術,即均使用本人本身寫的dom庫去簡化dom操做,具體須要掌握的知識點有:css

  • css3 背景漸變,transform,transition
  • less循環的使用
  • javascript基本隨機算法
  • 文檔片斷 documentFragment的使用

因爲文章沒有過高深的技術,關鍵是思路,因此接下來開始咱們的實現介紹。前端

效果圖

實現思路

實現思路分兩部分,第一部分是用css繪製轉盤背景,第二部分是經過js實現轉盤的轉動以及轉動隨機性的實現。vue

1. 繪製轉盤背景

咱們採用背景漸變的方式去實現條紋交替的扇形,原理就是經過繪製一個半圓,並在半圓里加漸變來實現,以下圖:java

實現將方形變成半圓的css咱們經過border-radius來實現:

width: 150px;
    height: 300px;
    border-radius: 0 150px 150px 0;
複製代碼

咱們再經過css的線性漸變,這樣本基本上能夠實現一個小的扇形區域:react

漸變的代碼以下:

background-image: linear-gradient(120deg, #f6d365, #f6d365 75px, transparent 75px);
複製代碼

實現了一個扇形,咱們天然能夠經過計算,好比咱們扇形弧度爲30deg,那麼咱們須要12個扇形便可組成一個圓,爲了方便,咱們使用less的循環來實現:css3

.loop(@n) when (@n >= 0) {
    .loop(@n - 1);
    .piece-@{n} {
        transform: rotate(-30deg * (@n + 1));
    } 
}
複製代碼

還有一個細節是,咱們須要改變變換的中心點,讓每一個扇形都以一箇中心點渲染,這樣才能夠組成一個完整的圓:算法

transform-origin: left center;
複製代碼

完整的css大體以下:vuex

.piece-wrap {
    position: relative;
    width: 300px;
    height: 300px;
    margin: 100px auto  auto 173px;
    transform-origin: left center;
    transition: transform 16s cubic-bezier(0,.47,.31,1.03);
    .piece {
        position: absolute;
        left: 0;
        top: 0;
        width: 150px;
        height: 300px;
        border-radius: 0 150px 150px 0;
        transform-origin: left center;
        span {
            margin-left: 16px;
            margin-top: 20px;
            display: inline-block;
            color: #fff;
        }
        &:nth-child(2n) {
            background-image: linear-gradient(120deg, #f6d365, #f6d365 75px, transparent 75px);
        }
        &:nth-child(2n+1) {
            background-image: linear-gradient(120deg, #ff5858, #ff5858 75px, transparent 75px);
        }
    }

    .loop(@n) when (@n >= 0) {
        .loop(@n - 1);
        .piece-@{n} {
            transform: rotate(-30deg * (@n + 1));
        } 
    }

    .loop(11);
}
複製代碼

2.javascript實現轉盤邏輯

因爲轉盤的轉動是隨機的,因此咱們須要每次點擊開始按鈕都要隨機生成一個角度,可是仔細分析一些平臺會發現轉盤每次都至少轉動n圈後纔會滿滿開始停下,因此咱們會給轉盤一個初始的角度,好比720deg,1080deg,這樣能保證轉盤至少轉動n圈才停下來。vue-cli

另外一個注意點是咱們要如何經過轉動角度知道轉盤停下來後的位置?這裏處於性能問題,咱們儘可能不操做dom,經過數據控制,咱們能夠經過每次隨機後獲得的角度和單位扇形區域的弧度來計算停下來的位置,公式以下:

totalRadis = initRadis + radis * n + radis/2

totalRadis爲轉動的角度,initRadis爲初始化角度,radis爲扇形的角度,radis/2是中獎的範圍,這裏主要用來定位用的,n是隨機數,接下來我將解釋n的做用。

那麼怎麼實現隨機角度呢?咱們通常會想經過寫個隨機函數去作,不過這裏有一種新的思路,就是經過隨機生成中獎的位置來實現隨機角度,因爲個人扇形爲30度,一共有12個扇形獎品區,因此索引爲0-11。所以,上面講到的n,就是咱們的隨機索引,咱們只須要寫個生成指定範圍的隨機數就能夠了。

瞭解了以上知識,咱們開始準備初始化數據:

// 轉盤抽獎數據
    var wards = ['1元', '2元', '3元', '5元', '再來', 
     '算法', '0.5元', '0.1元', '0.2元', '0.6元',
     '0.5元', '來'];
複製代碼

渲染獎品數據,這裏咱們用了DocumentFragment,雖然對簡單渲染沒有必要,可是後期可能會頗有用:

// 渲染dom
var fragment = document.createDocumentFragment();
for(var i=0, len = wards.length; i < len; i++) {
    var piece = document.createElement('div');
    piece.className = 'piece piece-' + i;
    piece.innerHTML = '<span>' + wards[i] + '</span>';
    fragment.appendChild(piece);
}

$('#piece_wrap')[0].appendChild(fragment);
複製代碼

生成指定範圍的隨機數的方法:

// 生成從 start到end的隨機數
function randomArr(start, end) {
    return Math.round(start + Math.random()* (end - start))
}
複製代碼

當咱們點擊開始按鈕時,我將經過改變轉盤的transform來讓其運動起來:

// 轉動邏輯
    var radis = 30,  // 每一個扇形區域的度數
            n = randomArr(0, 360/radis),  // 計算隨機中獎的位置
    initRadis = 720,   // 初始轉動的角度
         time = 16 * 1000,    // 轉動時間 
         once = true,    // 限制一個轉動週期只能點擊一次
   totalRadis = initRadis + radis * n + radis/2;  // 轉動角度計算公式
$('.start').on('click', function(){
    if(once) {
        once = false;
        $('#piece_wrap').css({
            'transform':'rotate(' + totalRadis + 'deg)',
            'transition': 'transform 16s cubic-bezier(0,.47,.31,1.03)'
        });
        setTimeout(function(){
            once = true;
            alert('恭喜你抽中了' + wards[n] + '!');
            $('#piece_wrap').css({
                'transform':'rotate(' + 0 + 'deg)',
                'transition': 'none'
            });
        }, time)
    }
        
    })
複製代碼

核心代碼就這些,怎麼樣,是否是很簡單呢?若是想體驗實際案例效果和技術交流,或者感覺更多原創h5遊戲demo,能夠關注下方公衆號體驗哦

更多推薦

相關文章
相關標籤/搜索