用canvas画一个炫酷的粒子动画倒计时
前言
😆 这是一篇踩在活动尾声的文章,主要是之前在摸鱼社群里有人发了个粒子动画的特效视频,想着研究研究写一篇文章出来看看,结果这一下子就研究了半个多月。
😂 下面就把研究成果通过文字的形式展现出来吧!!文末有码上掘金可以看效果的哦!!
canvas 粒子动画介绍
何为canvas?
canvas是HTML5中新增的一个标签,主要是用于网页实时生成图像并可操作图像,它是用JavaScript操作的bitmap。
粒子动画是啥?
粒子动画就是页面上通过发射许多微小粒子来表示不规则模糊物体,比如:用小圆点来模拟下雪、下雨的效果,用模糊线条模拟黑客帝国背景效果等。
canvas
🤨 新建一个HTML文件,写入canvas标签用于后续展示倒计时
<canvas id="canvas-number"></canvas>
<canvas id="canvas-dots"></canvas>
- canvas-number 是用于倒计时数字展示
- canvas-dots 是用于全屏粒子动画展示
🤨 加点样式效果看看吧
body {background-color: #24282f;margin: 0;padding: 0;
}canvas {position: absolute;top: 0;left: 0;
}#canvas-number {width: 680px;height: 420px;
}
- 主要是定义了
canvas-number画布大小,canvas-dots画布大小会在JavaScript中定义
定义初始变量
🤨 在JavaScript中定义所需的变量
var numberStage,numberStageCtx,numberStageWidth = 680,numberStageHeight = 420,numberOffsetX,numberOffsetY,stage,stageCtx,stageWidth = window.innerWidth,stageHeight = window.innerHeight,stageCenterX = stageWidth / 2,stageCenterY = stageHeight / 2,countdownFrom = 3,countdownTimer = 2800,countdownRunning = true,number,dots = [],numberPixelCoordinates,circleRadius = 2,colors = ['61, 207, 236', '255, 244, 174', '255, 211, 218', '151, 211, 226'];
- numberStage - stageCenterY 这一块主要是定义画布宽高和坐标
- countdownFrom 从 10 开始倒计时
- countdownTimer 数字显示的时长
- countdownRunning 动起来
- colors 页面上所有粒子颜色
- 其他的可以自己理解一下哦~
初始化canvas和数字文本
😏 创建一个init函数,里面会包裹初始化内容
function init() {// 初始化canvas-numbernumberStage = document.getElementById("canvas-number");numberStageCtx = numberStage.getContext('2d');// 设置文字文本的窗口大小numberStage.width = numberStageWidth;numberStage.height = numberStageHeight;// 初始化canvas-dots和窗口大小stage = document.getElementById("canvas-dots");stageCtx = stage.getContext('2d');stage.width = stageWidth;stage.height = stageHeight;// 设置一定的偏移量,让文字居中numberOffsetX = (stageWidth - numberStageWidth) / 2;numberOffsetY = (stageHeight - numberStageHeight) / 2;
}
- 根据代码中的注释可以了解初始化的内容哦~
😏 初始化完成之后,我们需要直接运行方法
init();
- 在
init函数结束之后,马上就需要运行该函数了
创建一定数量的点
for (var i = 0; i < 2240; i++) {var dot = new Dot(randomNumber(0, stageWidth), randomNumber(0, stageHeight), colors[randomNumber(1, colors.length)], .3);dots.push(dot);tweenDots(dot, '', 'space');
}
- 循环创建点,这里循环给的是个固定数据
- new Dot 是创建点对象的方法
- tweenDots 是让点动起来的第三方js
function Dot(x, y, color, alpha) {var _this = this;_this.x = x;_this.y = y;_this.color = color;_this.alpha = alpha;this.draw = function () {stageCtx.beginPath();stageCtx.arc(_this.x, _this.y, circleRadius, 0, 2 * Math.PI, false);stageCtx.fillStyle = 'rgba(' + _this.color + ', ' + _this.alpha + ')';stageCtx.fill();}}
- 通过 x、y坐标定位点
- 通过随机颜色,让点样式更丰富
- draw 里面的内容都是canvas画图的方法,具体可参考canvas文档
倒计时
function countdown() {// 发送倒计时数字drawNumber(countdownFrom.toString());// 倒计时为 0 时停止if (countdownFrom === 0) {countdownRunning = false;drawNumber('蜡笔小心');}countdownFrom--;
}
- 倒计时结束之后,就可以想干啥干啥了,这里我重新输出了额外的文字
- countdownFrom 需要做递减的操作
countdown();
- 我们需要在页面进入时,直接触发倒计时函数
倒计时文本绘画
😔 每一个倒计时都需要用不同的点去绘制
😔 这里通过循环 让每个文本都有四种颜色绘制
function drawNumber(num) {numberStageCtx.clearRect(0, 0, numberStageWidth, numberStageHeight);numberStageCtx.fillStyle = "#24282f";numberStageCtx.textAlign = 'center';numberStageCtx.font = "bold 118px Lato";numberStageCtx.fillText(num, 250, 300);var ctx = document.getElementById('canvas-number').getContext('2d');var imageData = ctx.getImageData(0, 0, numberStageWidth, numberStageHeight).data;numberPixelCoordinates = [];for (var i = imageData.length; i >= 0; i -= 4) {if (imageData[i] !== 0) {var x = (i / 4) % numberStageWidth;var y = Math.floor(Math.floor(i / numberStageWidth) / 4);if ((x && x % (circleRadius * 2 + 3) == 0) && (y && y % (circleRadius * 2 + 3) == 0)) {numberPixelCoordinates.push({x: x,y: y});}}}formNumber();
}function formNumber() {for (var i = 0; i < numberPixelCoordinates.length; i++) {tweenDots(dots[i], numberPixelCoordinates[i], '');}if (countdownRunning && countdownFrom > 0) {setTimeout(function () {breakNumber();}, countdownTimer);}
}function breakNumber() {for (var i = 0; i < numberPixelCoordinates.length; i++) {tweenDots(dots[i], '', 'space');}if (countdownRunning) {setTimeout(function () {countdown();}, countdownTimer);}}
循环绘制
function loop() {stageCtx.clearRect(0, 0, stageWidth, stageHeight);for (var i = 0; i < dots.length; i++) {dots[i].draw(stageCtx);}requestAnimationFrame(loop);
}
loop();
- 循环绘制,需要进入页面即执行,所以在方法之后马上执行该函数
点动画
🤯 在倒计时文本中,我们一直会调用tweenDots方法,就是用于点动画效果的绘制
function tweenDots(dot, pos, type) {if (type === 'space') {TweenMax.to(dot, (3 + Math.round(Math.random() * 100) / 100), {x: randomNumber(0, stageWidth),y: randomNumber(0, stageHeight),alpha: 0.3,ease: Cubic.easeInOut,onComplete: function () {tweenDots(dot, '', 'space');}});} else {TweenMax.to(dot, (1.5 + Math.round(Math.random() * 100) / 100), {x: (pos.x + numberOffsetX),y: (pos.y + numberOffsetY),delay: 0,alpha: 1,ease: Cubic.easeInOut,onComplete: function () {}});}
}function randomNumber(min, max) {return Math.floor(Math.random() * (max - min) + min);
}
- 随机移动画布周围的点
- 让点和文本内容协调展示
最后
最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。




有需要的小伙伴,可以点击下方卡片领取,无偿分享
相关文章:
用canvas画一个炫酷的粒子动画倒计时
前言 😆 这是一篇踩在活动尾声的文章,主要是之前在摸鱼社群里有人发了个粒子动画的特效视频,想着研究研究写一篇文章出来看看,结果这一下子就研究了半个多月。 😂 下面就把研究成果通过文字的形式展现出来吧…...
Java技术学习——Maven相关知识
一、什么是Maven? Maven是Apache软件基金会组织维护的一款专门为Java项目提供构建和依赖管理支持的工具。 1.1 构建 构建过程包含的主要环节如下: 清理:删除上一次构建的结果,为下一次构建做好准备编译:Java源程序…...
C++ 认识和了解C++
1.在使用C语言写代码的时候开头要用到的是: #include<iostream> using namespace std;不可以写成这样: #include iostream.h(1)iostream是输入输出流类, istream输入流类 cin >> ostream输出流类 cout &…...
u盘误删的文件怎么找回
u盘误删的文件怎么找回?u盘的特点之一就是极其便携,可以容纳各种格式的数据和文件,需要时可以直接使用。每次使用都会或多或少的存放一些文件,但有使用就会有删除,为了不影响使用性,清理存储空间是必要的。清理中如果…...
二分查找由浅入深--算法--java
二分查找写在开头算法前提:算法逻辑算法实现简单实现leftright可能超过int表示的最大限度代码分析和变换更多需求:求索引最小的值java二分API应用基础题思考难度方法写在开头 二分查找应该是算比较简单的这种算法了,我本以为还可以。但有时候…...
【学习】笔记本电脑重新安装系统win10
安装系统有很多方法: 软件安装制作启动u盘本文使用的方法就是启动盘安装: 1.首先下载iso镜像文件: msdn我告诉你:MSDN, 我告诉你 - 做一个安静的工具站 (itellyou.cn) 2.下载启动盘制作工具: 制作启动盘rufus:Rufus - 轻松创建 USB 启动盘 3.官网下载: https://do…...
RocketMQ的一些使用理解
1.RocketMQ的生产者生产负载策略(3种) (1)SelectMessageQueueByHash (一致性hash) (2)SelectMessageQueueByMachineRoom (机器随机) (3)SelectMessageQueueByRandom (随机) 第1种一…...
Java枚举详解
一.枚举 1.为什么有枚举? 如果我们的程序需要表示固定的几个值: 比如季节:spring (春),summer(夏),autumn(秋),winter(冬) 用常量表示: public static final int SEASON_SPRING 1;public st…...
虚拟机上安装openKylin详细步骤总结
一、创建虚拟机 首先获取操作系统安装镜像文件: 链接:https://pan.baidu.com/s/1tSuXmDk2ZILR4ieee6iImw?pwdcy47 提取码:cy47 (1-1)进入新虚拟机创建向导,选择“自定义”: (1-…...
夜天之书 #74 企业开源的软件协议模型实践(Part 2)
在上一篇文章中,我介绍了企业开源的完全开放源码策略及其风险。完全开放源码,即以符合开源定义的软件协议发布企业自研软件的情形。本文介绍应对完全开放源码后的风险的第一种策略:提高市场占有率与开放标准。与其说是策略,不如说…...
2.webpack实时打包
简介 上一章已经实现了使用 webpack 构建了一个简单的项目;但是我们发现,每次修改了 index.js 需要重新执行 cnpm run dev 命令重新构建 main.js;这在开发阶段是无法忍受的,因为这样调式将浪费大量的时间;还好 webpac…...
KingbaseES V8R3 表加密
前言 透明加密是指将数据库page加密后写入磁盘,当需要读取对应page时进行加密读取。此过程对于用户是透明, 用户无需干预。 该文档进行数据库V8R3版本测试透明加密功能,需要说明,该版本发布时间早于V8R6,所以只能进行表…...
2 为社么软件架构很重要?
2 为社么软件架构很重要? 啊,建造,建造! 这是所有艺术中最崇高的艺术。 — 亨利沃兹沃思朗费罗 如果架构是答案,那么问题是什么? 本章从技术角度重点介绍架构的重要性。我们将研究面包师的十几个最重要…...
Python 之 Pandas merge() 函数、set_index() 函数、drop_duplicates() 函数和 tolist() 函数
文章目录一、merge() 函数1. inner2. left 和 right3. outer二、set_index() 函数三、drop_duplicates() 函数四、tolist() 函数五、视频数据分析案例1. 问题要求2. 解决过程在最开始,我们先导入常规的 numpy 和 pandas 库。 import numpy as np import pandas as …...
MySQL实战之深入浅出索引(下)
1.前言 在上一篇文章中,我们介绍了InnoDB索引的数据结构模型,今天我们再继续聊一下跟MySQL索引有关的概念。 在介绍之前,我们先看一个问题: 表初始化语句 mysql> create table T ( ID int primary key, k int NOT NULL DEFA…...
(二分查找)leetcode1539. 第 k 个缺失的正整数
文章目录一、题目1、题目描述2、基础框架3、原题链接二、解题报告1、思路分析2、时间复杂度3、代码详解三、本题小知识一、题目 1、题目描述 给你一个 严格升序排列 的正整数数组 arr 和一个整数 k 。 请你找到这个数组里第 k 个缺失的正整数。 示例 1: 输入&…...
yaml文件格式详解及实例
🍁博主简介 🏅云计算领域优质创作者 🏅华为云开发者社区专家博主 🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 文章目录yaml简介yaml语法规则Yaml语法实例数组…...
AOP在PowerJob中的使用,缓存锁保证并发安全,知识细节全总结
这是一篇简简单单的文章,需要你简简单单看一眼就好,如果有不明白的地方,欢迎留言讨论。 在之前的文章中出现过一次AOP的使用,就是在运行任务之前,需要判断一下,触发该任务执行的server,是不是数…...
对账平台设计
背景 随着公司业务的蓬勃发展,交易履约清结算业务的复杂性也在不断的增高,资金以及各种数据的一致性和准确性也变得越发重要。 以交易链路为例,存在着如下一些潜在的不一致场景: 订单支付成功了,但是订单状态却还是“…...
JavaEE进阶第五课:SpringBoot的创建和使用
上篇文章介绍了Bean 作用域和生命周期,这篇文章我们将会介绍SpringBoot的创建和使用 目录1.为什么要学习StringBoot1.1什么是SpringBoot1.2SpringBoot的优点2.如何用Idea创建SpringBoot项目3.项目目录介绍和运行3.1输入Helloworld结尾1.为什么要学习StringBoot 在前…...
STM32F103 IAP实战:从Bootloader设计到远程固件更新
1. 为什么你的STM32需要IAP升级? 第一次接触IAP(In-Application Programming)这个概念时,我正蹲在工厂车间的设备旁边,手里拿着需要升级的STM32板子发愁。产线上30台设备需要更新程序,而每台设备都要拆外壳…...
汉字可视化探索平台:基于Flask+Vue的汉字浏览系统架构与实现
1. 项目概述:一个汉字学习者的“浏览器”如果你和我一样,对汉字的结构、演变和背后的文化故事着迷,那你一定经历过这样的时刻:在阅读古籍、碑帖,或者仅仅是看到一个生僻字时,心里会冒出无数个问号——这个字…...
超声引导手术中的‘呼吸’难题:我们如何用体外标记法搞定肝部超声-CT的实时配准?
超声与CT影像实时配准:破解呼吸运动干扰的临床实战方案 在肝癌射频消融或穿刺活检手术中,影像引导的精准度直接决定治疗效果。超声凭借其实时性成为首选引导工具,但图像质量局限常需与高分辨率的CT影像融合。这一过程中,呼吸运动导…...
Day3:拆箱ROS2|一起搭建机器人开发车间
Day1:一起学习了ros2是什么以及ros2为机器人开发提供了哪些核心功能. Day2一起安装了ros2。 接下来自然会想到如果现在要用ROS2开发一个机器人,应该怎样开始? 下面我们以雷达小车机器人举例说明: 1、需要为机器人创建一个【工作空间】作为顶层…...
保姆级教程:用Lumerical FDTD参数扫描功能,分析WO3薄膜厚度对反射率的影响
从零到精通:Lumerical FDTD参数扫描在薄膜光学设计中的实战指南 在光电材料研究和器件设计中,薄膜厚度的精确控制往往直接影响器件的光学性能。以三氧化钨(WO₃)薄膜为例,其厚度变化会显著改变反射光谱特性,…...
千问 LeetCode 2281.巫师的总力量和 Python3实现
LeetCode 2281. 巫师的总力量和(Sum of Total Strength of Wizards) 是一道难度较高的题目,核心在于 贡献法 单调栈 前缀和的前缀和(prefix sum of prefix sums)。下面给出 清晰、高效、符合 Python3 习惯 的实现&am…...
手机主板级维修
在智能手机高度普及的今天,一块主板几乎承载了用户所有的数字生活——从个人照片、工作文档到社交聊天记录。当设备遭遇进水、重摔或系统崩溃时,普通软件扫描往往束手无策,而“手机数据恢复”中的主板级维修技术,正成为破解这类“…...
保姆级避坑指南:用GGCNN源码处理Cornell抓取数据集,解决tiff文件生成失败问题
GGCNN源码实战:Cornell数据集预处理深度排错指南 第一次运行GGCNN的Cornell数据集预处理脚本时,我盯着毫无反应的终端窗口足足等了十分钟——没有进度条,没有错误提示,只有光标在无情地闪烁。这大概是每个复现论文的开发者都会经历…...
开源OmenSuperHub:解决惠普OMEN笔记本性能限制的完整技术方案
开源OmenSuperHub:解决惠普OMEN笔记本性能限制的完整技术方案 【免费下载链接】OmenSuperHub 使用 WMI BIOS控制性能和风扇速度,自动解除DB功耗限制。 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 第一部分:技术挑战分…...
长期使用Taotoken Token Plan套餐带来的成本控制感受
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 长期使用Taotoken Token Plan套餐带来的成本控制感受 1. 从按需付费到预算规划 对于个人开发者或小型团队而言,大模型…...
