采黎创意第1期 | 刮刮乐·好运十倍

采黎创意第1期 | 刮刮乐·好运十倍

刮刮乐大家都玩过吧,采黎也是深受其害 ,就是忍不住🤣;特别是好运十倍这一款,总给人一种中奖机率很大的感觉;今天采黎做了一款线上刮刮乐-好运十倍,供大家娱乐。

前言

定制头像2.0上线后,就想过做一个有关创意的专栏;

我自己也喜欢做一个创意、有趣、奇思妙想的项目;短短挤载程序生涯,总要留下点什么!

专栏

请先允许我介绍下我的专栏------采黎创意

顾名思义,这个专栏就是收录我自己做的创意、有趣、好玩的项目大部分是前端,因为是创意专栏,所以不定时更新,可能2天一个,也可以能半月一个,灵感总是那么转瞬即逝,我想把仅有的、缥缈的灵感保存下来。

为了不断更,我在github 新开了100个创意项目,大家可以star一下,有兴趣的小伙伴可以订阅一下专栏,跟随github。

预览效果

还是老规矩,先上链接~

🚀🚀🚀 刮刮乐-体验地址(主站) 🚀🚀🚀

🚀🚀🚀 刮刮乐-体验地址(github pages) 🚀🚀🚀

🚀🚀🚀 github项目地址(欢迎⭐) 🚀🚀🚀

喜欢话,动动小手点个star⭐哦,谢谢!

项目架构

javascript 复制代码
html | less | fabricjs | vue // html直接引用

所需素材

思路

  1. 用html还原一个未被刮奖的刮刮乐卡片,用其生成遮罩图片。
  2. 再用html做一个被刮开后的卡片。
  3. 将遮罩图绘制在canvas画布上,用擦除画笔为其实现刮刮乐功能。

开发

逻辑梳理

我梳理了以下几点

1. 初始化中奖数字

javascript 复制代码
awardNum : this.createRandomNum()

/* 获取60以内的随机数,不足2位补零 */
createRandomNum () {  
    const randomNum = Math.floor(Math.random() * 59) + 1  
    return randomNum > 9 ? randomNum : '0' + randomNum  
}

2. 初始化刮奖数字

幸运十倍总共有10行, 从下往上从1个刮奖数开始叠加,8、9、10行分别为8个刮奖数字

我们先打乱默认的奖金,然后随机初始化刮奖数字

js 复制代码
defaultNumList: [[500], [60], [60], [20], [200], ['40万'], [10], [100], [40], [500]],  
numList: [],

initNumList () {  
    this.numList = this.defaultNumList.sort(() => Math.random() - 0.5).map((row, rowIndex) => {  
        const rowTotal = rowIndex > 6 ? 8 : rowIndex + 1  

        for (let i = 0;i < rowTotal; i++) {  
        row.unshift(this.createRandomNum())  
        }  

        return row  
    }).reverse()  
},

3. 绘制画布、初始化笔刷

这里为大家介绍一下fabricjs的EraserBrush 擦除笔刷,不过fabricjs并未默认构建它,需要我们在构建项里面添加进来。

文档地址

构建地址

将这个勾选上进行打包

js 复制代码
initMask () {  
    this.canvas = new fabric.Canvas('mask', { isDrawingMode: true });  

    /* 设置画笔 */  
    this.canvas.freeDrawingBrush = new fabric.EraserBrush(this.canvas)  
    this.canvas.freeDrawingBrush.width = this.defaultSize  

    /* 绘制遮罩卡片 */  
    const backgroundImageUrl = './img/mask.png'; // 替换为你的底层图像  
    fabric.Image.fromURL(backgroundImageUrl, (img) => {  
        img.set({ selectable: false });  
        img.scaleToWidth(this.canvas.width, true)  
        this.canvas.add(img);  
        this.loading = false  
    });  
}

到这里刮刮乐的基本逻辑就都实现了,下面是页面的实现

页面

实现遮罩图片

先做一个宽高为346 * 450的卡片盒子,里面分别为头部、刮奖区域以及释义区域

html 复制代码
<div class="card">  
    <!-- 卡片头部 -->
    <div class="card-head">  
        <img src="./img/ten.png" alt="">
        <img src="./img/40.png" alt="">  
    </div>
    <!-- 刮奖区域 -->
    <div class="card-main"></div>
    <!-- 玩法释义 -->  
    <div v-if="false" class="card-desc">  
        任意一个"我的号码"与"中奖号码"相同,即可获得该对应的奖金;  
        如果刮出号码"10",即可获得该行对应奖金的10倍.  
    </div>
</div>

为卡片添加背景

less 复制代码
background: #f4f4f4 url("../img/bg.png") center no-repeat;
刮奖区域

刮奖区域是由二维数组 defaultNumList 遍历出来的,一共有10行,每行的最后一个元素为奖金。

html 复制代码
<div class="card-main">  
    <div v-for="(row, rowIndex) in numList" :key="rowIndex" class="card-main-row">  
        <div v-for="(num, numIndex) in row" :key="numIndex" class="card-main-col">  
            <template v-if="numIndex === row.length - 1">  
                <div class="gold">  
                    <span>奖金{{ cnNumList[9 - rowIndex] }}</span> 
                    <img src="./img/gold.png" alt="">  
                </div>  
            </template>  
            <template v-else>  
                <img class="money" src="./img/money.png" alt="">
            </template>  
        </div>  
    </div>  
</div>
定位元素
html 复制代码
<!-- 定位元素 -->  
<!-- 聚宝盆背景 -->  
<img class="card-pot" src="./img/pot.png" alt=""></img>  
  
<!-- 点点星星背景 -->  
<img class="card-star" src="./img/star.png" alt=""></img>  
  
<!-- 中奖号码区域 -->  
<div class="card-award">  
    <p>中奖号码</p>  
    <img src="./img/money.png">
</div>  
  
<!-- 10次机会 -->  
<div class="card-ten">  
    <p>10次</p>  
    <p>中奖机会</p>  
</div>
画布区域
html 复制代码
<!-- canvas画布 -->  
<canvas id="mask" width="346" height="450"></canvas>

css 代码看源码,不复杂。

ok,这样我们就画出了未刮奖的效果,然后利用浏览器截个屏,遮罩图就保存下来了

实现被刮开后的页面

为了刮奖效果逼真一些,大体的布局都不能动,只能相应的替换一些元素。

头部区域

头部区域的图片改为"刮奖结果"文字

html 复制代码
<!-- 卡片头部 -->  
<div class="card-head">   
    <div class="card-head-result">刮奖结果</div>  
</div>
刮奖区域

将钱币图片改为刮奖数字

ini 复制代码
<div class="num">{{ num }}</div>

将金元宝的文字"奖金一"改为具体的中奖数字

html 复制代码
<div class="gold">  
    <span>{{ num }}元</span>  
    <img src="./img/gold.png" alt="">  
</div>
中奖区域

将中奖区域的钱币改为数字

html 复制代码
<!-- 中奖号码区域 -->  
    <div class="card-award">  
    <p>中奖号码</p>  
    <div>{{ awardNum }}</div>  
</div>
隐藏10次中奖区域
html 复制代码
<!-- 10次机会 -->  
<div v-if="false" class="card-ten">  
    <p>10次</p>  
    <p>中奖机会</p>  
</div>
取消卡片背景及其他

如此,我们便得到了刮奖后的效果

优化

1. 优化刮奖笔刷

一千个读者眼中就会有一千个哈姆雷特,有的人想刮快点,有的人想慢慢来,我就是; 我加入了笔刷调节功能,供大家选择。

html 复制代码
<input v-model="defaultSize" type="range" min="5" max="40" @change="sizeChange">

笔刷默认12, 最小为5,最大为40

js 复制代码
defaultSize: 12

sizeChange () {  
    this.canvas.freeDrawingBrush.width = this.defaultSize  
}

2. 优化载入

初始化的时候绘制遮罩需要时间,这会导致有闪烁、奖项暴露的情况,我在这里做了载入动画

html 复制代码
<!--加载中-->  
<div v-if="loading" class="loading">  
    <svg viewBox="25 25 50 50" class="circular">
        <circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
    </svg>  
</div>  
  
<div v-show="!loading" class="card-wrap"></div>

这里的loading效果用的elemnet ui

js 复制代码
/* 初始化为true */
loading: true

/* 绘制完遮罩图后加载动画结束 */
initMask () {  
    this.canvas = new fabric.Canvas('mask', { isDrawingMode: true });  

    /* 绘制遮罩卡片 */  
    const backgroundImageUrl = './img/mask.png'; // 替换为你的底层图像  
    fabric.Image.fromURL(backgroundImageUrl, (img) => {  
        this.loading = false  
    });  
}

开源

100个创意项目于今天正式起航,邀诸位一起及见证。

人力终有穷尽时,有志同道合的小伙伴欢迎滴我,一起共勉!

余音

下一个创意项目还没有头绪,俗话说有一就有二,第一个创意项目已经来了,第二个还会远嘛!

期待下一个小创意吧,再会~

相关推荐
new出一个对象2 小时前
uniapp接入BMapGL百度地图
javascript·百度·uni-app
你挚爱的强哥3 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
y先森4 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy4 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189114 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿5 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡6 小时前
commitlint校验git提交信息
前端
虾球xz6 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇7 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒7 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript