web-africa-h5/components/ay-lottery/blow.vue

319 lines
6.4 KiB
Vue
Raw Normal View History

2025-03-21 14:49:01 +08:00
<template>
<view>
<view :id="canvasId" class="box-ly-b" style="position: relative;">
<view :style="{width: width+'rpx', height : height+'rpx'}">
<view class="blow" v-if="is_show" :style="{width: width+'rpx', height : height+'rpx'}" style="position: absolute;">
<view class="box-ly-b" :style="{background: themeColor }">
<view class="result" :style="[{'font-size':txtFontSize+'rpx'},{color: txtColor }]">
<text>{{result_txt}}</text>
</view>
</view>
</view>
<canvas style="position: absolute;" :style="{width: width+'rpx', height : height+'rpx'}" :disable-scroll="true"
@touchstart="touchstart" @touchend="touchend" @touchmove="touchmove" :canvas-id="canvasId"></canvas>
</view>
</view>
</view>
</template>
<script>
let ctx = null;
export default {
props: {
is_show: { //防止画布画好前闪烁
type: Boolean,
default: false
},
result_txt: {
type: String,
default: '结果',
},
themeColor: {
type: String,
default: '#33CCCC',
},
txtColor: {
type: String,
default: '#FFFFFF',
},
txtFontSize: {
type: Number,
default: 50,
},
canvasId: {
type: String,
default: 'blow',
},
height: {
type: Number,
default: 200
},
width: {
type: Number,
default: 300
},
percentage: { //刮开百分之多少的时候开奖
type: Number,
default: 45
},
touchSize: { //触摸画笔大小
type: Number,
default: 20
},
fillColor: { //未刮开图层时的填充色
type: String,
default: '#ddd'
},
watermark: { //水印文字
type: String,
default: '刮一刮'
},
watermarkColor: { //水印文字颜色
type: String,
default: '#c5c5c5'
},
watermarkSize: { //水印文字大小
type: Number,
default: 14
},
title: { //提示文字
type: String,
default: '刮一刮开奖'
},
titleColor: { //提示文字颜色
type: String,
default: '#888'
},
titleSize: { //提示文字大小
type: Number,
default: 24
},
disabled: { //是否禁止刮卡
type: Boolean,
default: false
},
init_show: { //是否初始化
type : Boolean ,
default : false
},
},
data() {
return {
startX: null,
startY: null,
computing: false,
complete: false,
reset: false,
ready: false,
storePoints: []
};
},
watch:{
init_show(e){
if(e){
this.initBlow();
}
},
},
mounted() {
ctx = uni.createCanvasContext(this.canvasId, this);
this.initBlow();
},
methods: {
initBlow: function() {
this.computing = false;
this.complete = false;
this.reset = false;
this.ready = false;
ctx.clearRect(0, 0, this.width, this.height);
//绘制画布
ctx.setFillStyle(this.fillColor);
ctx.fillRect(0, 0, this.width, this.height);
this.ready = true;
//绘制文字水印
this.fillWatermark();
//绘制标题
this.fillTitle();
ctx.draw();
setTimeout(res => {
let data = {
};
this.$emit('init', data);
}, 50)
},
/**
* 绘制文字水印
*/
fillWatermark: function(e) {
if (!this.watermark) {
return;
}
var width = this.watermark.length * this.watermarkSize;
ctx.save();
ctx.rotate(-10 * Math.PI / 180);
let x = 0;
let y = 0;
let i = 0;
while ((x <= this.width * 5 || y <= this.height * 5) && i < 300) {
ctx.setFillStyle(this.watermarkColor);
ctx.setFontSize(this.watermarkSize);
ctx.fillText(this.watermark, x, y);
x += width + width * 1.6;
if (x > this.width && y <= this.height) {
x = -Math.random() * 100;
y += this.watermarkSize * 3;
}
i++;
}
ctx.restore();
},
/**
* 绘制标题
*/
fillTitle: function(e) {
if (!this.title) {
return;
}
ctx.setTextAlign("center");
ctx.setTextBaseline("middle");
ctx.setFillStyle(this.titleColor);
ctx.setFontSize(this.titleSize);
ctx.fillText(this.title, this.width / 2 / 2, this.height / 2 / 2); //因单位是rpx故再除以2
},
touchstart: function(e) {
if (this.disabled) {
return;
}
this.startX = e.touches[0].x;
this.startY = e.touches[0].y;
},
touchend: function(e) {
this.getFilledPercentage();
},
touchmove: function(e) {
if (this.complete || this.disabled) {
return;
}
// ctx.globalCompositeOperation = 'destination-out';
ctx.moveTo(this.startX, this.startY);
// ctx.beginPath();
// ctx.arc(this.startX, this.startY, 20, 0, Math.PI * 20);
// ctx.fill();
ctx.clearRect(this.startX, this.startY, this.touchSize, this.touchSize);
ctx.draw(true);
//记录移动点位
this.startX = e.touches[0].x;
this.startY = e.touches[0].y;
},
getFilledPercentage: function(e) {
if (this.computing) {
return;
}
this.computing = true;
uni.canvasGetImageData({
canvasId: this.canvasId,
x: 0,
y: 0,
width: this.width,
height: this.height,
success: (res) => {
let pixels = res.data;
let transPixels = [];
for (let i = 0; i < pixels.length; i += 4) {
if (pixels[i + 3] < 128) {
transPixels.push(pixels[i + 3]);
}
}
//var percent = (transPixels.length / (pixels.length / 4) * 100).toFixed(2);
var percent = (transPixels.length / (pixels.length/2) * 100).toFixed(2);
if (percent >= this.percentage) {
this.success();
}
this.computing = false;
console.log(percent)
},
fail: function(e) {
console.log(e);
},
}, this);
},
success: function(e) {
this.complete = true;
if (this.reset) {
return;
}
this.reset = true;
ctx.moveTo(0, 0);
ctx.clearRect(0, 0, this.width, this.height);
ctx.stroke();
ctx.draw(true);
this.$emit("complete", {});
},
}
}
</script>
<style lang="scss">
.blow {
background-size: contain;
margin: 0rpx auto;
box-sizing: border-box;
position: relative;
overflow: hidden;
.box-ly-b {
width: 100%;
height: 100%;
// background: #aaaa7f;
border-radius: 10rpx;
position: relative;
overflow: hidden;
.result {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
// font-size: 50rpx;
// color: #FFFFFF;
}
}
}
.box-ly-b {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 100%;
}
</style>