JavaScript利用Canvas实现粒子动画倒计时
作者:蜡笔小心_ 发布时间:2024-04-16 09:37:52
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-number
numberStage = 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);
}
随机移动画布周围的点
让点和文本内容协调展示
效果图
来源:https://juejin.cn/post/7173487087961210911


猜你喜欢
- 本文实例为大家分享了python学生信息管理系统的具体代码,供大家参考,具体内容如下#!/usr/bin/env python# @Time
- 首先是创建一个类,继承于ActionResult,记住要引用System.Web.Mvc命名空间,如下: public class Imag
- 如下所示:# coding=utf-8import pandas as pd# 读取csv文件 3列取名为 name,sex,births,
- 如下所示:#python解决字符串倒序输出def string_reverse(m): num=len(m) a=[] for i in r
- 用python实现21点小游戏,供大家参考,具体内容如下from random import shuffleimport randomimp
- mysql5.7版本:方法1: 用SET PASSWORD命令 格式:mysql> set password f
- 创建一张作者表,author,创建外键与book表,多对多关系 ,外键字段放在那张表都可以,class Author(models.Mode
- python中,我们可以对列表、字符串、元祖中的元素进行排序,那对于字典中的元素可以排序吗?其实对于字典本身我们无法进行排序,但是我们可以对
- 如果你有过Web编程的经验,那么或多或少都听说过或者使用过模板。简而言之,模板是可用于创建动态内容的文本文件。例如,你有一个网站导航栏的模板
- golang常用库:gorilla/mux-http路由库使用golang常用库:配置文件解析库-viper使用golang常用库:操作数据
- 作为一个标准的程序猿,为程序编写说明文档是一步必不可少的工作,如何才能写的又好又快呢,下面我们就来详细探讨下吧。今天将告诉大家一个简单平时只
- Python json 错误xx is not JSON serializable解决办法在使用json的时候经常会遇到xxx
- 为了更好的理解邮件发送功能的实现,要先了解邮件发送系统的大致流程。首先 电子邮件之间的相互发送接受就像 邮局邮件发送
- 下面是Sql Server 和 Access 操作数据库结构的常用Sql,希望对你有所帮助。内容由海娃整理,不正确与不完整之处还请提出,谢谢
- python3版本的Scapy--Scapy3k来实现一个简单的DDos。首先实现SYN泛洪攻击(SYN Flood,是一直常用的DOS方式
- 什么是变量在Python编程语言中,变量是用于存储数据值的标识符。它们可以用来引用数据值,而不是直接使用值本身。可以使用等号(=)运算符来将
- Boundary MatchersJava regex API还支持边界匹配。如果我们关心在输入文本中匹配的确切位置,那么这就是我们要寻找的
- 如下所示:import numpynew_list = [i for i in range(9)]numpy.array(new_list)
- 合并两个数组 - concat()源代码:<!DOCTYPE html><html><body><
- Bootstrap 通过一些简单的 HTML 标签和扩展的类即可创建出不同样式的表单。0x01 样式1一个登录界面:<!DOCTYPE