js实现红包雨功能(canvas,react,ts),包括图片不规则旋转、大小、转速、掉落速度控制、屏幕最大红包数量控制等功能
介绍
- 本文功能由canvas实现红包雨功能(
index.tsx) - 本文为react的ts版。如有其他版本需求可评论区
- 观赏地址,需过墙
import React, { Component } from 'react';
// import './index.css';
import moneyx from '@/assets/images/RedEnvelopeRain/ball1.png';
import money1 from '@/assets/images/RedEnvelopeRain/money1.webp';
import money2 from '@/assets/images/pointCon/机器人.png';
import money3 from '@/assets/images/pointCon/无人机.png';
import {loadImage,positionX,randomRange,
} from './utils';
type minMax = [number, number];
const config = {// speed value areaspeedLimit: [1, 4] as minMax,// display quantitydensity: [5, 15] as minMax,imgInfo: {// image widthw: 50,// image heighth: 50,// image rotate value arearandomLimit: [0.5, 1] as minMax,},// image number max shownumberMaxLimit: 200,
};
const { speedLimit, imgInfo, numberMaxLimit, density } = config;export default class CanvasCom extends Component {// ratio = null;ctx: any = null;wid = 0;hei = 0;packedArr: ReturnType<typeof this.createPack>[] = [];// display quantitydensity = {min: density[0],max: density[1],};clearTime: any = null;img: any = [];loadingImageArr = [money1, moneyx, money2, money3]componentDidMount() {this.loadingImg();}loadingImg() {Promise.all(this.loadingImageArr.map(v => loadImage(v))).then((res) => {this.img = res;this.wid = window.innerWidth;this.hei = window.innerHeight;this.initCanvas();this.start();});}getPixelRatio = (context: any) => {const backingStore =context.backingStorePixelRatio ||context.webkitBackingStorePixelRatio ||context.mozBackingStorePixelRatio ||context.msBackingStorePixelRatio ||context.oBackingStorePixelRatio ||context.backingStorePixelRatio ||1;return (window.devicePixelRatio || 1) / backingStore;};initCanvas() {const canvas: HTMLCanvasElement | any = document.getElementById('canvas');canvas.width = this.wid;canvas.height = this.hei;if (canvas.getContext) {// 判断是否有此方法,如果有才能进入this.ctx = canvas.getContext('2d');// this.ratio = this.getPixelRatio(this.ctx);}}createPack() {const imgRandom = randomRange(...imgInfo.randomLimit);return {x: positionX(),y: 0,img: this.img[Math.floor(randomRange(0, this.loadingImageArr.length ))],// rotaterotate: randomRange(-45, 45),direction: Math.random(),speed: randomRange(...speedLimit),// rotate speedround: 0,roundSpeed: randomRange(1, 2),imgInfo: {w: imgInfo.w * imgRandom,h: imgInfo.h * imgRandom,},};}pushPackArr = () => {const { max, min } = this.density;const random = Math.floor(Math.random() * (max - min) + min);this.packedArr.push(...new Array(random).fill('').map(() => this.createPack()));this.clearTime = setTimeout(() => {if (this.packedArr.length > numberMaxLimit)return clearTimeout(this.clearTime);this.pushPackArr();}, 300);};drawPacked = () => {this.ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);this.packedArr.forEach((item, index) => {const r = ((item.rotate + item.round) * Math.PI) / 180;const temp = item.y - item.x * Math.tan(r);const top = temp * Math.cos(r);const left = item.x / Math.cos(r) + temp * Math.sin(r);this.ctx.save();this.ctx.rotate(r);this.ctx.drawImage(item.img,left - item.imgInfo.w / 2,top - item.imgInfo.h / 2,item.imgInfo.w,item.imgInfo.h);this.ctx.restore();if (item.direction < 0.5) {item.round -= item.roundSpeed;} else {item.round += item.roundSpeed;}if (item.y + item?.speed <= window.innerHeight) {item.y = item.y + item?.speed || 0;} else {// inititem.y = 0 + item?.speed || 0;item.x = positionX();Object.assign(item, this.createPack());}});window.requestAnimationFrame(this.drawPacked);};start = () => {this.pushPackArr();this.drawPacked();};render() {return (<div style={{ position: 'absolute', left: 0, top: 0, background: '#000' }}><canvas id="canvas"></canvas></div>);}
}
utils/index.ts
export const loadImage = (url: string) => {if (!window?.Image) return null;return new Promise((resolve, reject) => {const img = new Image();img.src = url;img.onload = () => {resolve(img);};img.onerror = () => {reject(new Error('load image error!'));};});
};
export const positionX = () => Math.random() * window.innerWidth;
export const randomRange = (start: number, end: number) => {const random = (end - start) * Math.random() + start;const number = 1;const arr = new Array(number).fill('').map((v, i) => random / (i + 1));return arr[Math.floor(Math.random() * number)];
};
效果图


相关文章:
js实现红包雨功能(canvas,react,ts),包括图片不规则旋转、大小、转速、掉落速度控制、屏幕最大红包数量控制等功能
介绍 本文功能由canvas实现红包雨功能(index.tsx)本文为react的ts版。如有其他版本需求可评论区观赏地址,需过墙 import React, { Component } from react; // import ./index.css; import moneyx from /assets/images/RedEnvelopeRain/bal…...
【数字IC设计/FPGA】FIFO与流控机制
流控,简单来说就是控制数据流停止发送。常见的流控机制分为带内流控和带外流控。 FIFO的流水反压机制 一般来说,每一个fifo都有一个将满阈值afull_value(almost full)。当fifo内的数据量达到或超过afull_value时,将满…...
C++笔记之遍历vector的所有方式
C笔记之遍历vector的所有方式 —— 2023年4月15日 上海 code review 文章目录 C笔记之遍历vector的所有方式1.普通for循环2.迭代器版3.const迭代器4.C11引入的范围for循环5.使用auto关键字和迭代器6.使用std::for_each算法7.使用std::for_each和lambda表达式8.普通版vector::at…...
OpenCV 笔记(2):图像的属性以及像素相关的操作
Part11. 图像的属性 11.1 Mat 的主要属性 在前文中,我们大致了解了 Mat 的基本结构以及它的创建与赋值。接下来我们通过一个例子,来看看 Mat 所包含的常用属性。 先创建一个 3*4 的四通道的矩阵,并打印出其相关的属性,稍后会详细…...
基于指数分布优化的BP神经网络(分类应用) - 附代码
基于指数分布优化的BP神经网络(分类应用) - 附代码 文章目录 基于指数分布优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.指数分布优化BP神经网络3.1 BP神经网络参数设置3.2 指数分布算法应用 4.测试结果…...
Python--练习:使用while循环求1~100之间,所有偶数的和(涉及if判断是不是偶数)
案例:求1~100之间,所有偶数的和 思考: 先套用原有基础模式,之后再思考其他的。 其实就是在之前文章 Python--练习:使用while循环求1..100的和-CSDN博客 的基础上,再判断如果获取到里面的全部偶数&#…...
带温度的softmax
用pytorch写一下使用带有温度的softmax的demo import torch import torch.nn.functional as F# 定义带有温度的softmax函数 def temperature_softmax(logits, temperature1.0):return F.softmax(logits / temperature, dim-1)# 输入logits logits torch.tensor([[1.0, 2.0, 3.…...
js函数调用的方式有几种
在 JavaScript 中,函数可以通过不同的方式进行调用。以下是常见的几种函数调用方式: 函数调用:使用函数名称后跟一对小括号来调用函数,这是最基本的调用方式。 functionName(); 方法调用:函数可以作为对象的方法进行调…...
聊聊设计模式--简单工厂模式
简单工厂模式 前面也学了很多各种微服务架构的组件,包括后续的服务部署、代码管理、Docker等技术,那么作为后端人员,最重要的任务还是代码编写能力,如何让你的代码写的漂亮、易扩展,让别人一看赏心悦目,…...
Python基础教程:内置函数之字典函数的使用方法
嗨喽~大家好呀,这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 len(字典名): 返回键的个数,即字典的长度 # len(字典名): # 返回键的个数,即字典的长度dic {a:123,b:456,c:789…...
Pytorch从零开始实战06
Pytorch从零开始实战——明星识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——明星识别环境准备数据集模型选择开始训练模型可视化模型预测总结 环境准备 本文基于Jupyter notebook,使用Python3.8,Pytorch2.0.1c…...
RT-Thread学习笔记(三):线程管理
线程管理 线程管理相关概念什么是时间片轮转调度器锁线程运行机制线程的五种状态 动态和静态创建线程区别动态和静态创建线程优缺点RT-Thread动态线程管理函数动态创建线程动态删除线程 RT-Thread静态线程管理函数静态创建线程 线程其他操作线程启动线程延时获得当前执行的线程…...
pymysql连接Mariadb/Mysql出现错误(配置正确情况下)解决办法
场景:在kali中使用python中pymysql对Mariadb进行连接,在整个过程中配置全部正确,但是就是无法进行连接,提示结果如下: Access denied for user rootlocalhost解决办法:进入数据库中,将默认密码…...
数据仓库扫盲系列(1):数据仓库诞生原因、基本特点、和数据库的区别
数据仓库的诞生原因 随着互联网的普及,信息技术已经深入到各行各业,并逐步融入到企业的日常运营中。然而,当前企业在信息化建设过程中遇到了一些困境与挑战。 1、历史数据积存。 过去企业的业务系统往往是在较长时间内建设的,很…...
DataX-web安装部署和使用
DataX-web的环境准备 MySQL (5.5) 必选,对应客户端可以选装, Linux服务上若安装mysql的客户端可以通过部署脚本快速初始化数据库 JDK (1.8.0_xxx) 必选 DataX 必选 Python (2.x) (支持Python3需要修改替换datax/bin下面的三个python文件,替换文件在do…...
sqlmap防御以及文件读写
一.防御 过滤 1.使用过滤函数 $email filter_var($_POST[email], FILTER_VALIDATE_EMAIL); if ($email) { // input is a valid email address } else { // input is not a valid email address 使用 filter_var() 函数和 FILTER_VALIDATE_EMAIL 过滤器来验证用户输…...
【源码】C/C++运动会计分系统 期末设计源码
文章目录 题目介绍功能源码效果展示带报告(内容) 题目介绍 使用语言: 两个版本都会发: 版本1:C语言 版本2: C 代码量: 500 题目介绍: 要求:初始化输入:N-参赛…...
Ubuntu安装Docker
卸载官方库中之前的旧版本 sudo apt-get remove docker docker-engine docker-ce docker.io更新安装包列表 sudo apt-get update安装以下包以使apt可以通过HTTPS使用存储库 sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common添…...
useReducer+createContext真的可以代替Redux吗?
概念 useReducer useReducer 是 React 提供的一个状态管理钩子,通常用于管理组件的复杂状态逻辑。它采用两个参数:reducer 函数和初始状态。Reducer 函数接受当前状态和一个操作(action),并返回一个新的状态。这有点…...
Mysql忘记登入密码找回 方法(超详细)
如果你找不到 MySQL 的安装路径,可以尝试以下几种方法: 检查环境变量:打开命令提示符,并运行以下命令: echo %PATH% 这会显示系统的环境变量。查找其中是否包含 MySQL 相关的路径,例如 C:\Program Files…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
