JavaScript动画实例之粒子文本的实现方法详解

1.粒子文本的实现原理

粒子文本的实现原理是:使用两张 canvas,一张是用户看不到的canvas1,用来绘制文本;另一张是用户看到的canvas2,用来根据canvas1中绘制的文本数据来生成粒子。

先在canvas1中用如下的语句绘制待显示的文本。

ctx1.font = '100px PingFang SC';

ctx1.textAlign = 'center';

ctx1.baseline = 'middle';

ctx1.fillText('Happy New Year',canvas1.width/2, canvas1.height/2);

然后使用canvas API的getImageData方法,获取一个ImageData对象,这个对象用来描述 canvas 指定区域内的像素数据。语句为:var imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;

这样imgData中保存了canvas1指定区域内所有像素点的rgba值,它是一个数组。由于每个像素点有 rgba 四个值,所以这个数组的长度也就是“像素点数量 * 4”。

最后通过遍历imgData数组,可以判断在canvas1中,哪些点是有色彩的(处于文本中间),哪些点是没有色彩的(不在文本上),把那些有色彩的像素位置记下来,然后在用户可见canvas2上生成粒子并绘制粒子即可。具体编程遍历imgData数组时,可以根据透明度,也就是 rgba 中的第4个元素是否不为0来判断该像素是否在文本中。

为此,创建一个自定义的粒子类Particle,该类中每个粒子对象有坐标位置(x,y)、半径radius和颜色color等4个属性;有一个方法draw(),用于绘制粒子。

编写的HTML代码如下。

<html>

<head>

<title>普通粒子文本</title>

</head>

<body>

<canvas hidden></canvas>

<canvas></canvas>

<script>

var canvas1=document.getElementById('myCanvas1');

ctx1= canvas1.getContext('2d');

var canvas2=document.getElementById('myCanvas2');

ctx2= canvas2.getContext('2d');

canvas1.width = canvas2.width = window.innerWidth;

canvas1.height = canvas2.height = window.innerHeight;

ctx1.font = '100px PingFang SC';

ctx1.textAlign = 'center';

ctx1.baseline = 'middle';

ctx1.fillText('Happy New Year',canvas1.width/2, canvas1.height/2);

var imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;

function Particle(x,y,radius,color)

{

this.x = x;

this.y = y;

this.radius = radius;

this.color = color;

}

Particle.prototype.draw= function()

{

ctx2.beginPath();

ctx2.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);

ctx2.fillStyle = this.color;

ctx2.fill();

ctx2.closePath();

}

var particles = [];

var skip =1;

for (var y = 0; y < canvas1.height; y +=skip)

{

for (var x = 0; x < canvas1.width; x += skip)

{

var opacityIndex = (x + y * canvas1.width) * 4 + 3;

if (imgData[opacityIndex] > 0)

{

var hue = Math.floor(Math.random() * 360);

var color=`hsl(${hue}, 100%, 50%)`;

particles.push(new Particle(x,y,2,color));

}

}

}

for (var particle of particles)

{

particle.draw();

}

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以看到在浏览器窗口中绘制出如图1所示的粒子文本。

图1 skip=1时显示的粒子文本

由图1可以看出拼凑文本的粒子非常密集,这是因为程序中遍历的步长skip=1,这样扫描了canvas1指定区域内的所有像素点。实际上在形成粒子文本时,无需所有像素点一个像素一个像素地扫,可以增大skip值,使得最后产生的粒子稀疏些。

例如,将程序中的语句“skip=1”修改为“skip=4”,则在浏览器窗口中绘制出如图2所示的粒子文本。

图2 skip=4时显示的粒子文本

2.粒子文本的动态效果

了解了普通粒子文本的实现原理后,可以为拼凑文本的粒子添加一些动态动效。从2个方面着手。

(1)给粒子赋予一些随机的位移,避免看上去过于整齐。

(2)粒子的大小随机产生,在创建粒子时对粒子初始半径radius 进行random 取随机值。另外为了让粒子半径动态改变,增加一个属性dynamicRadius,代表粒子的渲染半径,它根据粒子的初始半径radius,采用三角函数进行平滑改变。

编写如下的HTML代码。

<html>

<head>

<title>粒子文本的动态效果</title>

</head>

<body>

<canvas hidden></canvas>

<canvas></canvas>

<script>

var canvas1=document.getElementById('myCanvas1');

ctx1= canvas1.getContext('2d');

var canvas2=document.getElementById('myCanvas2');

ctx2= canvas2.getContext('2d');

canvas1.width = canvas2.width = window.innerWidth;

canvas1.height = canvas2.height = window.innerHeight;

ctx1.font = '120px PingFang SC';

ctx1.textAlign = 'center';

ctx1.baseline = 'middle';

ctx1.fillText('Happy New Year',canvas1.width/2, canvas1.height/2);

var imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;

function Particle(x,y,radius,color)

{

this.x = x;

this.y = y;

this.radius = radius;

this.color = color;

this.dynamicRadius = radius;

}

Particle.prototype.draw= function()

{

ctx2.beginPath();

ctx2.arc(this.x, this.y,this.dynamicRadius, 0, 2 * Math.PI, false);

ctx2.fillStyle = this.color;

ctx2.fill();

ctx2.closePath();

}

Particle.prototype.update= function()

{

this.dynamicRadius =3+2*Math.sin(new Date()/1000%1000*this.radius);

}

function random(min,max)

{

return Math.random() * ( max - min ) + min;

}

var particles = [];

var skip =4;

for (var y = 0; y < canvas1.height; y +=skip)

{

for (var x = 0; x < canvas1.width; x += skip)

{

var opacityIndex = (x + y * canvas1.width) * 4 + 3;

if (imgData[opacityIndex] > 0)

{

var hue = Math.floor(Math.random() * 360);

var color=`hsl(${hue}, 100%, 50%)`;

particles.push(new Particle(x+random(1,3),y+random(1,3),random(1,4),color));

}

}

}

for (var particle of particles)

{

particle.draw();

}

function loop()

{

requestAnimationFrame(loop);

ctx2.clearRect(0,0,canvas2.width,canvas2.height);

for (var particle of particles)

{

particle.update();

particle.draw();

}

}

loop();

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以看到在浏览器窗口中呈现出如图3所示的粒子文本动态效果。

图3 粒子文本的动态效果

到此这篇关于JavaScript动画实例之粒子文本的实现方法详解的文章就介绍到这了,更多相关JavaScript动画实例之粒子文本内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript实现的3D旋转魔方动画效果实例代码

    JS1K是JavaScript编程竞赛--参加竞赛的规则很简单,脚本必须小于1K,竞赛网站开始也只是为了娱乐,却意外地收到了很多优秀的作品. 这是2016年JS1k上传的作品,用几十行代码实现的一个3D旋转魔方: 代码如下: function z(t, e) { return t? e? t.appendChild(e) : "width:"+t+"px;height:"+t+" px;position:absolute;" : document

  • JavaScript实现移动端带transition动画的轮播效果

    JavaScript实现轮播的方式多种多样,桌面的移动端的实现方式都是大同小异的,具体的核心实现原理不外乎下面几个要点.即: 1. 确定播放方向.一般都是横向轮播,当然不排除纵向的需求可能.当然还有反向播放情况,这个自定义. 2. 对第一张图片的处理.如果当前是第一张了,那么如果继续往前面(就是你播放方向的反向)滑动,那么就会出现留白(如果你允许继续滑动的话,不过不允许滑动也没有啥意思了,除非你想来回轮播,这个我在另一篇用jQuery也说明过),此时应该让你的左边显示应该轮播图片的最后一张,实现

  • JS实现网页烟花动画效果

    原生js实现放烟花效果,点击鼠标,然后向四周扩散,最后自由落体效果!最简单的方法实现! 效果图: CSS代码: *{ padding: 0px; margin: 0px; background: #000; } .firworks{ width: 6px; height: 6px; position: absolute; } js代码: <script type="text/javascript"> //封装一个颜色随机的效果 function randomColor(){

  • JavaScript canvas动画实现时钟效果

    本文实例为大家分享了canvas动画实现时钟效果的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta

  • js通过循环多张图片实现动画效果

    本文实例为大家分享了js通过循环多张图片实现动画展示的具体代码,供大家参考,具体内容如下 以小鱼摇尾巴和眨眼睛为例 动画思路: 1.将图片资源放在数组里面 2.通过计时器来设定间隔时间 3.通过计数器来取相应的图片 第一步:基本框架,鱼身体 <body> <canvas id="canvas1" width="800" height="600"></canvas> </body> document.

  • JS div匀速移动动画与变速移动动画代码实例

    1.匀速移动代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>title</title> <style> * { margin: 0; padding: 0; } div { margin-top: 20px; width: 200px; height: 100px; background

  • JS实现水平移动与垂直移动动画

    本文实例为大家分享了JS实现水平移动与垂直移动的具体代码,供大家参考,具体内容如下 水平移动分析: 可看成是一个物体的左边距变化. 比如:向右移动是左边距越来越大(数值为正),可调整物体的左边距来实现 向左移动是左边距越来越小(数值为负),可调整物体的左边距来实现 实际代码如下: <style> *{padding: 0;margin: 0px;} #box{width: 100px;height: 100px;border-radius: 50%;background: red;positi

  • JavaScript变速动画函数封装添加任意多个属性

    下面通过实例代码给大家介绍JavaScript变速动画函数封装添加任意多个属性 ,具体代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> * { margin: 0; padding: 0; } div { width: 200px; height

  • JavaScript动画实例之粒子文本的实现方法详解

    1.粒子文本的实现原理 粒子文本的实现原理是:使用两张 canvas,一张是用户看不到的canvas1,用来绘制文本:另一张是用户看到的canvas2,用来根据canvas1中绘制的文本数据来生成粒子. 先在canvas1中用如下的语句绘制待显示的文本. ctx1.font = '100px PingFang SC'; ctx1.textAlign = 'center'; ctx1.baseline = 'middle'; ctx1.fillText('Happy New Year',canva

  • JavaScript实现生成动态表格和动态效果的方法详解

    今天上午完成了Vue实现一个表格的动态样式,那么JavaScript代码能不能实现同样的效果呢?这样也可以学习一下JavaScript的语法,晚上试了一下,完全可以,效果一模一样. <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="X-UA-Compatible" content="text/html; charset=utf-8">

  • Python处理文本数据的方法详解

    目录 前言 用python处理文本数据 用python处理数值型数据 前言 HI,好久不见,今天是关闭朋友圈的第60天,我是野蛮成长的AC-Asteroid. 人生苦短,我用Python,通过短短两周时间自学,从基础知识到项目实践,在这个过程中深刻体会到这款语言的魅力,今天带来一个有趣的项目,用Python处理文本数据,一起来看看今天的问题吧. 用python处理文本数据 实验目的 熟悉python的基本数据结构,以及文件的输入与输出. 实验数据 利用xxxx年xx机器学习会议的评测数据和评测任

  • JavaScript中数组去重常用的五种方法详解

    目录 1.对象属性(indexof) 2.new Set(数组) 3.new Map() 4.filter() + indexof 5.reduce() + includes 补充 原数组 const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; 1.对象属性(indexof) 利用对象属性key排除重复项 遍历数组,每次判断新数组中是否存在该属性,不存在就存储在新数组中 并把数组元素作为key,最后返

  • Python实现文本特征提取的方法详解

    目录 1.字典文本特征提取 DictVectorizer() 1.1 one-hot编码 1.2 字典数据转sparse矩阵 2.英文文本特征提取 3.中文文本特征提取 4. TF-IDF 文本特征提取 TfidfVectorizer() 1.字典文本特征提取 DictVectorizer() 1.1 one-hot编码 创建一个字典,观察如下数据形式的变化: import pandas as pd from sklearn.feature_extraction import DictVecto

  • Javascript获取图片原始宽度和高度的方法详解

    前言 网上关于利用Javascript获取图片原始宽度和高度的方法有很多,本文将再次给大家谈谈这个问题,或许会对一些人能有所帮助. 方法详解 页面中的img元素,想要获取它的原始尺寸,以宽度为例,可能首先想到的是元素的innerWidth属性,或者jQuery中的width()方法. 如下: <img id="img" src="1.jpg"> <script type="text/javascript"> var img

  • JavaScript动态检测密码强度原理及实现方法详解

    本文实例讲述了JavaScript动态检测密码强度原理及实现方法.分享给大家供大家参考,具体如下: 在注册账户,设置密码时,会出现密码强度动态检测,网上看了一些帖子,大多只写了具体的实现过程,而没有对原理的分析过程.下面着重讲一下其原理. 原理分析 通常实现密码强度动态判断有两种方案实现: 正则.但其效率低一点,难度也大一些. 字符串,函数和运算符. 这里用第二种方案,但是如何判断一个密码串是强还是弱呢? 一般我们的密码会设置为数字.字母(大小写).特殊符号三类. 强:密码串包含其中三种或以上

  • Java文本编辑器实现方法详解

    本文实例讲述了Java文本编辑器实现方法.分享给大家供大家参考,具体如下: 结构分析: 界面布局 : EditFrame main方法所在: EditText 打开功能实现:  FileReadThread 保存跟能实现:  save 实际运行效果: 附:完整代码实现 一. EditFrame 包括一个菜单Menu 底部:日期时间 代码附上: public class EditFrame extends JFrame { // TODO 自动生成的构造函数存根 boolean saveFlag

  • Vue 实现从文件中获取文本信息的方法详解

    本文实例讲述了Vue 实现从文件中获取文本信息的方法.分享给大家供大家参考,具体如下: 最近在使用vue做项目的时候,遇到一个需求,界面中需要显示大量的说明文字,为了保持界面的整洁和赶紧,决定采用单独的文件来存储显示信息,然后通过文件读取的方式显示到界面上. 刚开始我使用的是File和FileReader对象获取,但是比较气人的是这两个对象是IE浏览器特有的属性,chrome不支持,而且为了安全起见,现在浏览器是不推崇这种做法的,因为很容易造成文件被外部恶意删除或增加内容,安全性太低.无奈之下,

  • 微信小程序整合使用富文本编辑器的方法详解

    本文实例讲述了微信小程序整合使用富文本编辑器的方法.分享给大家供大家参考,具体如下: 使用WxParse插件实现小程序的富文本显示 ,下载地址:富文本插件WxParse 具体使用步骤: 1. 复制插件文件夹到项目根目录,emojis是表情包,可选择性删除 2. 在.js文件中引入WxParse模块 var WxParse= require('../../../wxParse/wxParse.js'); 3. 在.wxss文件中引入WxParse.wxss样式,也可以在app.wxss中引入 @i

随机推荐