采黎创意第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个创意项目于今天正式起航,邀诸位一起及见证。

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

余音

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

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

相关推荐
10年前端老司机1 小时前
什么!纯前端也能识别图片中的文案、还支持100多个国家的语言
前端·javascript·vue.js
摸鱼仙人~1 小时前
React 性能优化实战指南:从理论到实践的完整攻略
前端·react.js·性能优化
程序员阿超的博客2 小时前
React动态渲染:如何用map循环渲染一个列表(List)
前端·react.js·前端框架
magic 2452 小时前
模拟 AJAX 提交 form 表单及请求头设置详解
前端·javascript·ajax
小小小小宇7 小时前
前端 Service Worker
前端
只喜欢赚钱的棉花没有糖7 小时前
http的缓存问题
前端·javascript·http
小小小小宇8 小时前
请求竞态问题统一封装
前端
loriloy8 小时前
前端资源帖
前端
源码超级联盟8 小时前
display的block和inline-block有什么区别
前端
GISer_Jing8 小时前
前端构建工具(Webpack\Vite\esbuild\Rspack)拆包能力深度解析
前端·webpack·node.js