一、效果图
二、说明
1.使用mpVue编写小程序刮刮奖,底部的优惠券信息可以随时变化
2.如果有需要刮奖涂层可以是一个图片,也可以是纯色背景,依据coating变量是否为空来控制选项。
3.如果刮奖涂层是一个图片,在绘制的时候需要注意网络图片不能直接绘制,需要缓存到本地(wx.downloadfile),用本地地址进行绘制,wx.download花费时间,会导致优惠券内容先显示出来,然后涂层才覆盖其上,用couponShow变量(boolean)来控制整个内容显隐,只有当wx.download结束后内容才出现。
4.获取canvas的宽高,利用了以下方式:
wx.createSelectorQuery().select('#scratchCanvas').boundingClientRect(function (rect) {
this.width = parseInt(res.width)// 获取canvas宽度;
this.height = parseInt(res.height)// 获取canvas高度
})
<template>
<div class="page" v-if="couponShow">
<!--优惠券信息-->
<div class="scratch">
<div class="coupon-inform">
<div class="inform-left">
<div><span class="coupon-price">10</span>元</div>
<div >满100可用</div>
</div>
<div class="inform-right">
<div class="coupon-name">促销券</div>
<div class="fitProdDis">全场适用</div>
<div class="use-date">使用期限:2019.3.1-2019.6.30</div>
</div>
</div>
</div>
<!--涂层-->
<canvas canvas-id="luck" id="scratchCanvas" class="scratchCanvas" style="width:350px ; height: 150px;" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd"></canvas>
</div>
</template>
初始化全局变量有两种方法:
方法一:在data中定义,在onLoad中初始化
方法二: 在constructor方法中初始,简单明了
<script>
export default {
data () {
return {
width: '', // canvas宽度
height: '', // canvas高度
canvasId: 'luck', // canvasId
maskColor: '#c3c', // 没有刮奖涂层图片时,纯色涂层颜色
size: 8, //
r: '', // 焦点大小
area: '', // 刮掉面积
scale: 0.7, // 刮奖涂层全部消失比例
totalArea: '', // 画布总面积
coating: 'https://misc.aotu.io/pfan123/wx/placeholder.png', // 刮刮奖涂层
couponShow:false // 如果有刮奖涂层图片,downloadFile花费时间导致优惠券内容先展示出来,用变量控制显隐可解决
}
},
async onLoad () {
// 初始化画布宽高
wx.createSelectorQuery().select('#scratchCanvas').boundingClientRect(function (rect) {
this.width = parseInt(res.width)// 获取canvas宽度;
this.height = parseInt(res.height)// 获取canvas高度
})
// 焦点大小半径
this.r = this.size * 3
// 焦点面积
this.area = this.r * this.r
// 画布总面积
this.totalArea = this.width * this.height
this.init()
},
onShow () {
},
methods: {
/**
* 初始化变量,方法二,
* 比较简便、简单明了
* @author xiaoxiaoxian
* @date 2019/3/4
* @param page
* @param opts
*/
constructor(page,opts){
opts = opts || {};
this.page = page;
this.canvasId = opts.canvasId || 'luck';
this.width = opts.width || 300;
this.height = opts.height || 150;
this.maskColor = opts.maskColor || '#c3c';
this.size = opts.size || 8;
this.r = this.size * 3;
this.area = this.r * this.r;
this.scale = opts.scale || 0.70;
this.totalArea = this.width * this.height;
this.init();
},
/**
* 调用绘制画布函数
* @author xiaoxiaoxian
* @date 2019/3/4
* @param
* @param
*/
init(){
this.show = false;
this.clearPoints = [];
this.ctx = wx.createCanvasContext(this.canvasId, this);
this.drawMask();
this.bindTouch();
},
/**
* 绘制画布,
* 如果刮奖涂层图片不为空,绘制图片,为空设置颜色
* @author xiaoxiaoxian
* @date 2019/3/4
*/
drawMask(){
let that = this
if (this.coating !== '') {
wx.downloadFile({
url: this.coating,
success: res => {
this.couponShow = true
console.log(res.tempFilePath)
that.ctx.drawImage(res.tempFilePath, 0, 0, that.width, that.height);
that.ctx.draw();
}
})
} else {
this.couponShow = true
that.ctx.setFillStyle(that.maskColor);
that.ctx.fillRect(0, 0, that.width, that.height);
that.ctx.draw();
}
},
/**
* 擦拭
* @author xiaoxiaoxian
* @date 2019/3/4
*/
eraser(e,bool){
let len = this.clearPoints.length;
let count = 0
let x = e.touches[0].x,
y = e.touches[0].y;
let x1 = x - this.size;
let y1 = y - this.size;
if(bool){
this.clearPoints.push({
x1: x1,
y1: y1,
x2: x1 + this.r,
y2: y1 + this.r
})
}
for (let val of this.clearPoints){
if(val.x1 > x || val.y1 > y || val.x2 < x || val.y2 < y){
count++;
}else{
break;
}
}
if(len === count){
this.clearPoints.push({
x1: x1,
y1: y1,
x2: x1 + this.r,
y2: y1 + this.r
})
}
if (this.clearPoints.length && this.r * this.r * this.clearPoints.length > this.scale * this.totalArea){
this.show = true;
}
this.ctx.clearRect(x1, y1, this.r, this.r);
this.ctx.draw(true);
},
/**
* 触摸函数
* @author xiaoxiaoxian
* @date 2019/3/4
*/
bindTouch(){
const _this = this;
_this.onTouchStart = function(e){
_this.eraser(e,true);
}
_this.onTouchMove = function (e) {
_this.eraser(e);
}
_this.onTouchEnd = function (e) {
if(_this.show){
_this.ctx.clearRect(0, 0, _this.width, _this.height);
_this.ctx.draw();
}
}
}
}
}
</script>
<style scoped>
.page{
width: 100%;
}
.scratchCanvas{
width: 350px;
height: 150px;
margin-right: auto;
margin-left: auto;
}
.scratch{
background-color: #8799a3;
width: 100%;
height: 200px;
padding-top: 20px;
position: absolute;
}
.coupon-inform {
width: 300px;
margin-left: auto;
margin-right: auto;
display: flex;
background-image:url("https://graph.baidu.com/resource/102ce5edbe2786e5b581a01551680938.jpg") ;
background-size: 100%;
}
.inform-left {
font-size: 12px;
color: #FF2E36;
text-align: center;
line-height: 25px;
width: 30%;
padding-top:20px;
font-family: 'HelveticaNeue-Medium';
}
.coupon-price {
font-size: 30px;
color: #FF2E36;
}
.inform-right {
font-size: 14px;
color: #000000;
margin-left:8%;
width:62%;
padding-top:10px;
}
.use-date {
font-size: 12px;
color: #717171;
line-height: 25px;
}
.coupon-name {
font-weight: 600;
line-height: 30px;
}
</style>
参考文章:https://blog.csdn.net/m0_38082783/article/details/79458895