国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

canvas之轉盤抽獎

_ang / 764人閱讀

摘要:最近工作中重構了抽獎轉盤,給大家提供一個開發(fā)轉盤抽獎的思路需求轉盤根據獎品數(shù)量不同而有變化目錄結構由于業(yè)務需要所以開發(fā)了兩個版本抽獎,和,不過部分只能替換圖片,沒有功能邏輯。

最近工作中重構了抽獎轉盤,給大家提供一個開發(fā)轉盤抽獎的思路

需求
1、轉盤根據獎品數(shù)量不同而有變化
2、canvas
目錄結構

由于業(yè)務需要所以開發(fā)了兩個版本抽獎,dom和canvas,不過editor.js部分只能替換圖片,沒有功能邏輯。

需要注意的是此目錄隱藏了一個動態(tài)數(shù)據類(dataStore),因為集成在項目里了,所以沒有體現(xiàn)。

Spirts

精靈類生成實例,會包括基礎屬性:width、height、x、y和方法:setOpacity、drawCircular、setRotate、draw

下面是幾個重要的精靈構造器:背景、轉盤背景和每一個獎品

/*
 * 精靈核心 基類
 * */
class Spirt {
    constructor({}) {}
    // 精靈透明度調節(jié)
    setOpacity(opy, callback) {}
    // 畫圓形圖片
    drawCircular(fn) {}
    // 精靈旋轉調節(jié)
    setRotate() {}
    // 畫精靈
    draw() {}
}
// 背景
class Bg extends Spirt {
    constructor({ ...args }) {
        super({ ...args });
        if (args.height == "100%") {
            this.height = this.canvas.height;
        }
    }
}
// 轉盤背景
class Turn extends Spirt {
    constructor({ ...args }) {
        super({ ...args });
    }
    draw() {
        this.drawCircular(() => {
            super.draw();
        });
    }
}
// 每一個獎品
class Item extends Spirt {
    constructor({ ...args }, rid) {
        super({ ...args });
        this.rid = rid;
    }
    draw(angle, x, y) {
        this.setRotate(angle, () => super.draw(), x, y);
    }
}
Config

基礎數(shù)據類,包括基礎數(shù)據:轉盤分塊、角度、半徑、每一塊對應獎品、旋轉總時長、旋轉速度等

主要說一下轉盤分塊:如果符合規(guī)律,就用函數(shù)代替,如果不符合規(guī)律就用映射

let layout = {
    1: [1, 10, 1, 10, 1, 10],
    2: [1, 2, 10, 1, 2, 10],
    3: [1, 10, 2, 10, 3, 10],
    4: [2, 10, 3, 10, 4, 10, 1, 10],
    5: [2, 3, 4, 10, 5, 10, 1, 10],
    6: [2, 3, 4, 10, 5, 6, 1, 10],
    7: [3, 4, 10, 5, 6, 7, 10, 1, 2, 10],
    8: [3, 4, 10, 5, 6, 7, 8, 10, 1, 2]
};

下面為部分代碼

class Config {
    constructor(prize = new Array(3), resImg) {
        this.awards_len = prize.length >= 7 ? 10 : prize.length >= 4 ? 8 : 6;
        this.awards_angle = 360 / this.awards_len;

        this.awards_r = 320;
        this.awards_cir = 2 * Math.PI * this.awards_r;

        let nums = {
            6: 2.5,
            8: 2,
            10: 2
        };

        this.awards_item_margin = 40;
        this.award_item_size =
            this.awards_cir / this.awards_len / nums[this.awards_len];

        this.duration = 2000;

        // 獎品詳情
        this.awards = getAwards(resImg, prize.length);
    }
}
/**
 * 獲取獎品列表
 * @param {*} num
 */
function getAwards(resImg, num) {
    let arr = layout[num];
    return arr.map(rid => {
        let res = resImg[mapAwards[rid]];
        return { rid, res, className: mapAwards[rid] };
    });
}
Res

資源類主要做一些圖片初始化的操作

// 獲取游戲資源
class Res extends Resource {
    constructor(dataStore) {
        super({ dataStore });
        let { gameJson } = dataStore;

        this.res = {
            ...gameJson.staticSpirts.BG
        };

        this.dataStore = dataStore;
    }
    // 編輯頁面改變頁面圖片能力。
    setImg(data) {
        this.res[data.num].imgUrl = data.imgUrl;
        if (["BG", "TITLE", "TURNTABLE_BG", "PLAYBTN"].includes(data.num)) {
            $(`.turnTableNew_${data.num}`).css(
                "background-image",
                `url("${HOST.FILE + data.imgUrl}")`
            );
        } else {
            $(`.turnTableNew_${data.num}`).attr(
                "src",
                `${HOST.FILE + data.imgUrl}`
            );
        }
        return {
            staticSpirts: this.res
        };
    }
}
Director

導演類,主要操作的是轉盤動畫的邏輯
主要邏輯是:
1、addCLick: canvas添加點擊事件
2、drawStatic:畫靜態(tài)元素
3、drawZhuanPan:這個為多帶帶canvas,group內部包括畫轉盤,獎品
4、drawPlayBtn: 畫按鈕
5、當點擊抽獎按鈕執(zhí)行updatedRotate函數(shù)讓多帶帶轉盤canvas旋轉即可
6、當旋轉角度和獲取獎品角度一致時停止

class turnTable extends Director {
    constructor(dataStore) {
        let { gameManager } = dataStore;
        super(gameManager);

        // 從倉庫中獲取基礎數(shù)據,canvas和config總配置
        this.dataStore = dataStore;
        this.canvas = dataStore.canvas;
        this.config = dataStore.$gameConfig;
        
        // 當前抽獎的一些基礎數(shù)據
        this.angle = 0;
        this.isAnimate = true;
        this.lastTime = 0;
        this.num = 0;

        this.addCLick();
    }

    // 抽獎結束,需要初始化抽獎
    initGame() {
        this.state = this.START;
        this.angle = 0;
        this.num = 0;
        this.prizeId = null;
        this.isAnimate = true;
        this.turnAudio.pause();
        this.drawAllElements(this.res, this.set);
    }
    /**
     * 畫所有元素
     * @param {*} store
     * @param {*} res
     */
    drawAllElements(res, set) {
        this.res = res;
        this.set = set;
        this.drawStatic(res);
        this.drawZhuanPan(this.angle);
        this.drawPlayBtn(this.canvas, res);
    }
    /**
     * 畫靜態(tài)元素
     */
    drawStatic(res) {
        ["BG", "TITLE"].forEach(item => {
            let str = item.toLowerCase();
            str = str.replace(str[0], str[0].toUpperCase());
            let ele = new Spirts[str]({
                canvas: this.canvas,
                ...res[item]
            });
            ele.draw();
        });
    }
    // 畫轉盤
    drawZhuanPan(angle) {
        this.group = new Spirts["Group"]({
            canvas: this.canvas,
            ...this.res["TURNTABLE_BG"]
        });
        this.items = this.drawDynamic(this.group.group_canvas, this.res);
        this.group.draw(
            angle,
            +this.res["TURNTABLE_BG"].x + +this.res["TURNTABLE_BG"].width / 2,
            +this.res["TURNTABLE_BG"].y + +this.res["TURNTABLE_BG"].height / 2
        );
    }
    // 畫動態(tài)元素
    drawDynamic(canvas, res) {
        let set = this.set;
        let items = [];
        // 轉盤背景1,裝飾物
        let turnBg = new Spirts["Turn"]({
            canvas,
            img: res["TURNTABLE_BG"].img,
            width: res["TURNTABLE_BG"].width,
            height: res["TURNTABLE_BG"].height,
            x: 0,
            y: 0
        });
        turnBg.draw();
        // 轉盤背景2,盤面
        let turnPan = new Spirts["Turn"]({
            canvas,
            img: res["TURNTABLE_PAN"].img,
            width: res["TURNTABLE_PAN"].width,
            height: res["TURNTABLE_PAN"].height,
            x: (res["TURNTABLE_BG"].width - res["TURNTABLE_PAN"].width) / 2,
            y: (res["TURNTABLE_BG"].height - res["TURNTABLE_PAN"].height) / 2
        });
        turnPan.draw();

        for (let i = 0; i < set.awards_len; i++) {
            // 每一個獎品
            let item = new Spirts["Item"](
                {
                    canvas,
                    img: set.awards[i].res.img,
                    width: set.award_item_size,
                    height: set.award_item_size,
                    x: turnBg.width / 2 - set.award_item_size / 2,
                    y:
                        (turnBg.height - turnPan.height) / 2 +
                        set.awards_item_margin
                },
                set.awards[i].rid
            );
            item.draw(
                set.awards_angle / 2 + set.awards_angle * i,
                turnBg.width / 2,
                turnBg.height / 2
            );
            // 畫線
            let line = new Spirts["Item"]({
                canvas,
                img: res["LINE"].img,
                width: res["LINE"].width,
                height: res["LINE"].height,
                x: turnBg.width / 2 - res["LINE"].width / 2,
                y: (turnBg.height - turnPan.height) / 2
            });
            line.draw(
                set.awards_angle * i,
                turnBg.width / 2,
                turnBg.height / 2
            );
            // 放到items數(shù)組內,后期轉盤停止校驗用
            items.push(item);
        }
        return items;
    }
    // 畫按鈕
    drawPlayBtn(canvas, res) {
        let playBtn = new Spirts["PlayBtn"]({
            canvas,
            ...res["PLAYBTN"]
        });
        playBtn.draw();
        this.playBtn = playBtn;
    }
    // 點擊事件
    addCLick() {
        let initX,
            isClickState,
            cScale = this.config["cScale"] || 1;
        this.canvas.addEventListener(tapstart, event => {
            initX = event.targetTouches
                ? event.targetTouches[0].clientX
                : event.offsetX / cScale;
            let y = event.targetTouches
                ? event.targetTouches[0].clientY
                : event.offsetY / cScale;
            isClickState = isCheck.call(this.playBtn, initX, y);
            // 點擊回調
            if (isClickState && this.isAnimate) {
                 /**
                 * 按鈕不可點擊
                 * 初始化總時長
                 * 初始化速度
                 * 初始化當前時間
                 */
                this.isAnimate = false;
                this.set.is_animate = true;
                this.set.jumping_total_time =
                    Math.random() * 1000 + this.set.duration;
                this.set.speed = (this.set.jumping_total_time / 2000) * 10;
                this.lastTime = new Date().getTime();
                this.run();
                this.getPrize()
                    .then(res => {
                        if (!res) {
                            this.prizeId = 10;
                            return;
                        }
                        this.prizeId = +res.prizeLevel + 1;
                    })
                    .catch(_ => {
                        this.prizeId = 10;
                        this.initGame();
                        this.state = this.END;
                    });
            }
        });
    }
    updatedRotate() {
        let curTime = new Date().getTime(),
            set = this.set,
            speed = 1;
        /**
         * 轉盤停止,需要滿足一下條件
         * 1.大于總時間
         * 2.有獎品id
         * 3.速度降為1
         * 4.轉盤角度對應獎品id位置
         * 角度做了容錯處理,當前角度范圍中心位置,偏移量為5
         * 公式:通過旋轉角度計算當前獎品index
         * 通過items獎品列表計算當前獎品rid
         * rid和prizeId對比,如果結束抽獎
         */
        if (
            curTime - this.lastTime >= set.jumping_total_time &&
            this.prizeId &&
            speed == 1
        ) {
            let resultAngle = 360 - (this.angle % 360);
            let index = (resultAngle / set.awards_angle) >> 0;
            let centerAngle = set.awards_angle * (index + 0.5);
            if (
                this.items[index].rid == this.prizeId &&
                (resultAngle > centerAngle - 5) &
                    (resultAngle < centerAngle + 5)
            ) {
                this.comAudio.play();
                this.state = this.PAUSE;
            }
        }
        this.num++;
        speed = Math.max(
            set.speed -
                (18 * this.num * (set.speed - 1)) / set.jumping_total_time,
            1
        );
        this.angle += speed;
        this.drawAllElements(this.res, this.set);
    }

    // 渲染畫布
    render() {
        switch (this.state) {
            case this.START:
                this.updatedRotate();
                break;
            case this.ERROR:
                break;
            case this.PAUSE:
                this.state = this.END;
                setTimeout(() => {
                    this.showResult();
                    this.initGame();
                }, 1000);
                break;
            case this.END:
                // 打開指定頁面
                break;
        }
    }
}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106906.html

相關文章

  • HTML5 Canvas圓盤抽獎應用DEMO

    摘要:圓盤抽獎應用頁面圓盤抽獎應用演示抱歉瀏覽器不支持。 HTML5 Canvas圓盤抽獎應用DEMO html頁面 HTML5 Canvas圓盤抽獎應用DEMO演示 抱歉!瀏覽器不支持。 抱歉!瀏覽器不支持。 抱歉!瀏覽器...

    sunsmell 評論0 收藏0
  • HTML5 Canvas圓盤抽獎應用DEMO

    摘要:圓盤抽獎應用頁面圓盤抽獎應用演示抱歉瀏覽器不支持。 HTML5 Canvas圓盤抽獎應用DEMO html頁面 HTML5 Canvas圓盤抽獎應用DEMO演示 抱歉!瀏覽器不支持。 抱歉!瀏覽器不支持。 抱歉!瀏覽器...

    anyway 評論0 收藏0
  • HTML5 Canvas圓盤抽獎應用DEMO

    摘要:圓盤抽獎應用頁面圓盤抽獎應用演示抱歉瀏覽器不支持。 HTML5 Canvas圓盤抽獎應用DEMO html頁面 HTML5 Canvas圓盤抽獎應用DEMO演示 抱歉!瀏覽器不支持。 抱歉!瀏覽器不支持。 抱歉!瀏覽器...

    dinfer 評論0 收藏0
  • 轉盤抽獎腳本自己擼

    摘要:效果需求很多場景都需要做各種活動,抽獎最是司空見慣了,跑馬燈的,轉盤的,下面先花幾分鐘擼出一個轉盤的吧,當然網上至少有一打的可供參考。但是我們只差一個定時器循環(huán)了接下里實現(xiàn)這個主循環(huán),不斷更新值就可以了。 demo 效果 需求 很多場景都需要做各種活動,抽獎最是司空見慣了,跑馬燈的,轉盤的,下面先花幾分鐘擼出一個轉盤的吧,當然網上至少有一打的 demo 可供參考。真的只需要一點點時間而...

    趙春朋 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<