uniapp canvas做的刮刮乐解决蒙层能自定义图片

news2024/12/31 5:29:07

在这里插入图片描述

最近给湖南中烟做元春活动,一个月要开发4个小活动,这个是其中一个难度一般,最难的是一个类似鲤鱼跃龙门的小游戏,哎,真实为难我这个“拍黄片”的。下面是主要代码。

			<canvas :style="{'width':width+'px','height':height+'px'}" canvas-id="myCanvas" id="myCanvas"
				@touchstart="touchstart" @touchend="touchend" @touchmove="touchmove">
			</canvas>
<script>
	
	import {
		setShareConfig
	} from './share'
	
	
	export default {
		data() {
			return {
				rewardList:{},
				textBoxFont: '',
				textBoxBt: '',
				textBoxState: false,
				touchStartState:true,
				tishiState:false,
				
				clickState:false,
				
				activity: {},
				reward:{
					"reward_icon": "",
					"reward_img": ""
				},
				seckillContent: '',
				prizeBoxState: false,
				count: 0, // 初始值为10秒
				readState: false,
				myPrizeState: false,
				ctx: null,
				width: 0,
				height: 0,
				chance_count: 0, //剩余次数
				validTime: '', //有效时间
				disabled: true, // 是否禁止刮卡
				readyState: false, // 是否开始绘制
				endState: false, // 结束刮卡状态

				watermark: '', // 水印文字
				watermarkColor: '#c5c5c5', // 水印文字颜色
				watermarkSize: 14, // 水印文字大小

				title: '', // 提示文字
				titleColor: '#888', // 提示文字颜色
				titleSize: 24, // 提示文字大小

				startX: 0, // 触摸x轴位置
				startY: 0, // 触摸y轴位置
				touchSize: 40, // 触摸画笔大小
				percentage: 70, // 刮开百分之多少的时候开奖

			}
		},
		onShow() {
			this.$nextTick(() => {
				let content = uni.createSelectorQuery().select(".content");
				content.boundingClientRect((data) => {
					this.width = data.width;
					this.height = data.height;
					this.ctx = uni.createCanvasContext('myCanvas', this);
					setTimeout(e => {
						this.init();
					}, 20);
				}).exec()
			})

		},

		onLoad: function(options) {

			
		},
		methods: {
			


			convertSecToDHMS(seconds) {
				var days = Math.floor(seconds / (24 * 60 * 60));
				seconds %= (24 * 60 * 60);
				var hours = Math.floor(seconds / (60 * 60));
				seconds %= (60 * 60);
				var minutes = Math.floor(seconds / 60);
				var seconds = seconds % 60;
				if (this.res.is_end) {
					return {
						days: 0,
						hours: 0,
						minutes: 0,
						seconds: 0
					};
				}
				return {
					days: days,
					hours: hours,
					minutes: minutes,
					seconds: seconds
				};
			},











			readHide() {
				if (this.count == 0) {
					this.readState = false;
				}
			},

			convertSecToDHMS(seconds) {
				var days = Math.floor(seconds / (24 * 60 * 60));
				seconds %= (24 * 60 * 60);
				var hours = Math.floor(seconds / (60 * 60));
				seconds %= (60 * 60);
				var minutes = Math.floor(seconds / 60);
				var seconds = seconds % 60;
				if (this.res.activity.difference_time <= 0) {
					return {
						days: 0,
						hours: 0,
						minutes: 0,
						seconds: 0
					};
				}
				return {
					days: days,
					hours: hours,
					minutes: minutes,
					seconds: seconds
				};
			},

			init() {
				this.endState = false;
				this.readyState = false;
				this.ctx.clearRect(0, 0, this.width, this.height); // 清除画布上在该矩形区域内的内容(x,y,宽,高)。
				this.ctx.setFillStyle('rgba(255, 255, 255, 0.5)'); // 填充颜色
				this.ctx.fillRect(0, 0, this.width, this.height); // 填充区域(x,y,宽,高)

				/**
				 * 绘制文字水印
				 */
				var width = this.watermark.length * this.watermarkSize;
				this.ctx.save(); // 保存当前的绘图上下文。
				//this.ctx.rotate(-10 * Math.PI / 180); // 以原点为中心,原点可以用 translate方法修改。顺时针旋转当前坐标轴。多次调用rotate,旋转的角度会叠加。
				let x = 0;
				let y = 0;
				let i = 0;
         //自定义蒙层图片
				this.ctx.drawImage('../../static/jhy/ycsm/guazhi.png', 0, 0, this.width, this.height);
				this.ctx.restore(); // 恢复之前保存的绘图上下文。

				/**
				 * 绘制标题
				 */
				this.ctx.setTextAlign("center"); // 用于设置文字的对齐
				this.ctx.setTextBaseline("middle"); // 用于设置文字的水平对齐
				this.ctx.setFillStyle(this.titleColor); // 填充颜色
				this.ctx.setFontSize(this.titleSize); // 设置字体的字号
				this.ctx.fillText(this.title, this.width / 2, this.height / 2); // 填充的文本(文字,x,y)
				this.ctx.draw(); // 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。
				this.readyState = true; // 完成绘制
			},


			// 手指触摸动作开始
			touchstart(e) {
				
				

				if (this.disabled || this.endState) {
					return;
				}
				this.startX = e.touches[0].x;
				this.startY = e.touches[0].y;
			},
			// 手指触摸后移动
			touchmove(e) {
				
				// if (this.chance_count <= 0) {
				// 	return;
				// }
				
				if (this.disabled || this.endState) {
					return;
				}
				this.ctx.clearRect(this.startX, this.startY, this.touchSize, this.touchSize); // 清除画布上在该矩形区域内的内容(x,y,宽,高)。
				this.ctx.draw(true); // false:本次绘制是否接着上一次绘制,true:保留当前画布上的内容
				//记录移动点位
				this.startX = e.touches[0].x;
				this.startY = e.touches[0].y;
			},
			// 手指触摸动作结束
			touchend(e) {
				if (this.disabled || this.endState) {
					return;
				}
				// 返回一个数组,用来描述 canvas 区域隐含的像素数据,在自定义组件下,第二个参数传入自定义组件实例 this,以操作组件内 <canvas> 组件。
				uni.canvasGetImageData({
					canvasId: 'myCanvas',
					x: 0,
					y: 0,
					width: this.width,
					height: this.height,
					success: (res) => {
						console.log(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);
						if (percent >= this.percentage) {
							this.success();
						}
					},
					fail: (e) => {
						console.log(e);
					},
				}, this);
			},

			// 成功,清除所有图层
			success: function(e) {
				if (this.endState) {
					return;
				}
				this.endState = true;
				this.ctx.moveTo(0, 0); // 把路径移动到画布中的指定点,不创建线条。用 stroke() 方法来画线条。
				this.ctx.clearRect(0, 0, this.width, this.height); // 清除画布上在该矩形区域内的内容(x,y,宽,高)。
				this.ctx.stroke(); // 画出当前路径的边框。默认颜色色为黑色。
				this.ctx.draw(true);
				this.prizeBoxState = true;

			},

			// 重置
			reset() {
				this.init();
			},
			
			

		}
	}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1408747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c语言-枚举和联合体

文章目录 前言一、枚举类型1.1 枚举类型的定义1.2 枚举类型的使用1.3 枚举的优点 二、联合体类型2.1 联合体类型的定义2.2 联合体类型的特点2.3 联合体大小的计算 总结 前言 本篇文章介绍c语言中的枚举类型和联合体类型 一、枚举类型 1.1 枚举类型的定义 枚举类型和结构体类…

【C++干货铺】C++中的四种类型转换

个人主页点击直达&#xff1a;小白不是程序员 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 C语言中的类型转换 为什么C需要四种类型转化 C强制类型转换 static_cast reinterpret_cast const_cast dynamic_cast RTTI C语言中的类型转换 在C语言中&…

2023 IoTDB Summit:中核武汉核电运行技术股份有限公司主管工程师方华建《IoTDB在核电数字化转型过程的应用实践》...

12 月 3 日&#xff0c;2023 IoTDB 用户大会在北京成功举行&#xff0c;收获强烈反响。本次峰会汇集了超 20 位大咖嘉宾带来工业互联网行业、技术、应用方向的精彩议题&#xff0c;多位学术泰斗、企业代表、开发者&#xff0c;深度分享了工业物联网时序数据库 IoTDB 的技术创新…

ERP读书笔记20240125-1

ERP&#xff08;Enterprise Resource Planning&#xff0c;企业资源计划&#xff09;的发展经历了从 MRP&#xff08;Material Requirements Planning&#xff0c;物料需求计划&#xff09;到 MRP2&#xff08;Manufacturing Resources Planning&#xff0c;制造资源计划&#…

OpenCV-26 拉普拉斯算子

一、拉普拉斯算子概念及其推导 索贝尔算子是模拟一阶导数&#xff0c;一阶导数越大的地方说明变化越剧烈&#xff0c;越有可能是边缘。 但是如果我们对f&#xff08;t&#xff09;求二阶导数呢&#xff1f; 可以发现边缘处的二阶导数 0&#xff0c;因此&#xff0c;我们可以利…

跟着cherno手搓游戏引擎【10】使用glm窗口特性

修改ImGui层架构&#xff1a; 创建&#xff1a; ImGuiBuild.cpp&#xff1a;引入ImGui #include"ytpch.h" #define IMGUI_IMPL_OPENGL_LOADER_GLAD//opengl的头文件需要的定义&#xff0c;说明使用的是gald #include "backends/imgui_impl_opengl3.cpp" …

C++力扣题目56--合并区间 738--单调递增的数字 968--监控二叉树

56. 合并区间 力扣题目链接(opens new window) 给出一个区间的集合&#xff0c;请合并所有重叠的区间。 示例 1: 输入: intervals [[1,3],[2,6],[8,10],[15,18]]输出: [[1,6],[8,10],[15,18]]解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. 示例 2: 输入: interv…

Netty的解码器和编码器

链路图 一个完整的RPC请求中&#xff0c;netty对请求数据和响应数据的处理流程如下图所示 网络线路中传输的都是二进制数据&#xff0c;之后netty将二进制数据解码乘POJO对象&#xff0c;让客户端或者服务端程序处理。 解码的工具称为解码器&#xff0c;是一个入站处理器InBo…

分布式应用程序设计项目管理

1. 项目的定义 项目是一种特定的、新颖的行动&#xff0c;目的是以有条不紊、逐步的方式构建一个尚未存在确切对应物的未来现实。它是对精心制定的需求的回应&#xff0c;旨在满足业主的需要。项目包括一个可能是物理或智力的目标&#xff0c;并且需要使用给定的资源来执行一系…

Gold-YOLO(NeurIPS 2023)论文与代码解析

paper&#xff1a;Gold-YOLO: Efficient Object Detector via Gather-and-Distribute Mechanism official implementation&#xff1a;https://github.com/huawei-noah/Efficient-Computing/tree/master/Detection/Gold-YOLO 存在的问题 在过去几年里&#xff0c;YOLO系列已经…

某马头条——day10

热文章数据查询 分布式任务调度xxl-job 概述 环境搭建 docker化部署 docker run -p 3306:3306 --name mysql57 \ -v /opt/mysql/conf:/etc/mysql \ -v /opt/mysql/logs:/var/log/mysql \ -v /opt/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORDroot\ -d mysql:5.7 dock…

uniapp开发过程一些小坑

问题1、uniapp使用scroll-view的:scroll-into-view“lastChatData“跳到某个元素id时候&#xff0c;在app上不生效&#xff0c;小程序没问题 使用this.$nextTick或者 setTimeout(()>{that.lastChatData 元素id },500) 进行延后处理就可以了。 问题2&#xff1a;uniapp开…

NE8实现HTTP Upgrade和HTTP CONNECT代理服务器

看到一个文章[Go] 不到 100 行代码实现一个支持 CONNECT 动词的 HTTP 服务器 在NET8中如何实现 创建项目为MiniApi 编辑Program.cs文件。 var builder WebApplication.CreateSlimBuilder(args);var app builder.Build();// 将HTTP请求通过协议升级机制转为远程TCP请求&…

02 分解质因子

一、数n的质因子分解 题目描述&#xff1a; 输入一个数n&#xff08;n<10^6&#xff09;,将数n分解质因数&#xff0c;并按照质因数从小到大的顺序输出每个质因数的底数和指数。 输入 5 输出 5 1 输入 10 输出 2 1 5 1 朴素解法&#xff1a; 首先求出1~n的所有质数…

༺༽༾ཊ—Unity之-02-简单工厂模式—ཏ༿༼༻

首先我们打开一个项目 在这个初始界面我们需要做一些准备工作 建基础通用包 创建一个Plane 重置后 缩放100倍 加一个颜色 任务&#xff1a;使用【简单工厂模式】生成四种不同怪物 【按不同路径移动】 首先资源商店下载四个怪物模型 接下来我们选取四个怪物作为预制体并分别起名…

Git 入门精讲

我们为什么要学习git&#xff1f; 就当下的发展而言&#xff0c;只要你从事开发就一定会接触git。作为最强大的分布式版本控制器&#xff0c;git 与 svn 有着本质上的区别。 Git是一种分布式版本控制系统&#xff0c;每个开发者都可以在本地维护完整的代码库&#xff0c;可以离…

第21课 在Android Native开发中架起java与c++互通的桥梁

在开始本节课&#xff0c;我尝试把项目拷贝到另一台电脑上以便继续工作&#xff0c;但出现了大量的“could not be resolved”问题&#xff0c;尝试包含新的include路径也无法解决该问题&#xff0c;最后删除了项目的Native Support&#xff0c;然后重新添加Native Support才解…

HarmonyOS鸿蒙学习基础篇 - Text文本组件

该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 Text文本组件是可以显示一段文本的组件。该组件从API Version 7开始支持&#xff0c;从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 子组件 可…

【时间序列篇】基于LSTM的序列分类-Pytorch实现 part2 自有数据集构建

系列文章目录 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part1 案例复现 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part2 自有数据集构建 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用 在一个人体姿态估计的任务中&#xff0c;需要用深度学习模型…

上门服务小程序|预约上门服务系统开发有哪些功能?

在现代快节奏的生活中&#xff0c;压力和疲劳常常困扰着我们。为了缓解这种状况&#xff0c;越来越多的人选择去按摩店进行放松。然而&#xff0c;繁忙的工作和家庭责任往往让我们无法抽出时间去按摩店。在这种情况下&#xff0c;上门按摩服务应运而生。而随着科技的发展&#…