整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

网页设计中粒子动画的 10 个漂亮例子

年前,粒子动画席卷了网络,并成功地为自己开辟了一个利基市场。当前对具有高科技氛围和几何装饰的设计的巨大痴迷使它们成为当今更受欢迎的解决方案之一。


使用粒子动画给人留下深刻印象
随着时间的推移,技术成熟了。从散落在画布上的杂乱无章的小白点,它变成了一种潜力巨大的工具。这不是什么特别的东西,但它有一定的令人惊叹的因素。此外,它完美地为高科技、几何和商务美学做出了贡献——自然而然地完成了它们。


前提是:粒子动画要给人留下深刻印象。而且,开发人员始终坚持这一假设,充分利用它。让我们考虑一下这个解决方案的真正粉丝创建的一些惊人的代码片段。


NO.1 Justin Windle 的 30,000 个粒子

这里的标题不言自明。船上有 30,000 个粒子,您会期待一些宏伟的东西。贾斯汀温德尔当然达到了我们的期望。他的概念令人难以置信。用你的鼠标到处玩。物理学只是例外。这个版本的粒子动画在开发者中很受欢迎,尽管规模没有那么大。


NO.2 Alex Safayan 在水中的鱼

Alex Safayan 提出了几乎相同的解决方案,但在这种情况下,粒子越来越大。鼠标光标也将这些点推开,形成带有微妙涟漪效果的痕迹。动画的行为让人想起鱼靠近水面时的运动。注意物理学:点之间的相互作用是经过深思熟虑的。


NO.2 浮游生物——Marco Dell'Anna 的粒子生命

获得 2017 年度最受关注项目奖的 Plankton 无疑是值得关注的。该项目不仅着迷于想法,还着迷于实现。从像手套一样适合这里的微妙色彩到看起来令人难以置信的自然的华丽行为,Marco Dell'Anna 对细节有着敏锐的洞察力。



NO.4 Marco Dell'Anna的星尘

我喜欢这里华丽的复古氛围、霓虹灯和华丽的色彩。很难把你的眼睛从它身上移开。Stardust 是设计和编码的共生体,是一部鼓舞人心的杰作。


NO.5 Akimitsu Hamamuro 的重力点

Akimitsu Hamamuro 邀请您在他的游乐场添加所谓的“重力点”。它们侵入点的混乱运动,像磁铁一样拉动它们。虽然它们不扮演轨道中心的角色;然而,它们形成了迫使粒子向其方向移动的焦点。


NO.6 Nate Wiley 的 Particle Orb CSS

如今,球体是英雄区域非常流行的风格选择。Nate Willey 对这一趋势的看法令人印象深刻。由于微小的颗粒,球体看起来很脆弱,同时由于经过深思熟虑的行为而坚固。他分解和重新形成球体的程序非常棒。


NO.7 Kevin Rajaram 的粒子波

Kevin Rajarm 汲取了粒子动画的美丽和优雅,并用Three.js的强大来增强它,带来了一个精致但真正复杂的概念。令人惊叹的海浪景色让人感觉未来主义、人工和迷人。

非正统用途

还有更令人印象深刻的使用粒子动画的方法。让我们走出常规,开箱即用地思考:这种方法很容易使标识和字母等元素受益。


NO.8 Tamino Martinius 的交互式粒子标志

Interactive Particle Logo 就是一个典型的例子。它看起来像是上面提到的 Justin Windle 片段的重新设想的解决方案。虽然没有 30,000 个点,但它由数量惊人的粒子组成,巧妙地组成了“CODEPEN”这个词。这是该概念找到实际用途的案例之一。


NO.9 Louis Hoebregts 的文本到粒子

Louis Hoebregts 在这支笔中提供了先前解决方案的彩色版本。这里的文本是由一千个彩色实心圆圈组成的,这些圆圈通过与上一个示例相同的交互性来丰富。


NO.10 粒子由 Marco Dell'Anna 书写文本

虽然这不是一个戏剧性的入口,但它有一些令人着迷的东西。流畅的动画慢慢揭开人物的面纱,点燃我们的兴趣。这个概念有某种神秘的风格,类似于“陌生人”的介绍。



NO.11 马可·戴尔安娜 (Marco Dell'Anna) 就这样做

这是Marco Dell'Anna的又一杰作。这一次,粒子动画参与塑造了著名的耐克标志。从晦涩、半透明到明快、立体,动画逐渐暴露了标志,不显眼地抓住了整体的注意力。


引人注目的效果

粒子动画是越小越好的情况之一。点越小,可以实现的效果就越令人印象深刻。一方面,由于涉及几何和物理,它看起来很复杂。另一方面,由于精致的形状,它看起来脆弱而微妙。这种独特的融合使粒子动画与众不同且引人注目。


粒子动画在企业网站建设中的运用案例

图片来源:素马设计

习canvas,javascript的小伙伴,可以跟着我这篇文章的思路一起做一个小效果出来,代码都齐全了。

这里还是要说一下我的前端学习群:230354270,从我一个到现在的都是看我每一篇文章来的,可以说都是我们大前端的学霸啊,不定期分享干货。想学到东西的都可以来,欢迎初学和进阶中的小伙伴

首先看一下源图和转换成粒子效果的对比图:

左侧图片为源图,右侧图片为粒子效果图。该效果是在Canvas画布上制作的。将图片制作成粒子效果相对而言是比较简单的。重点了解两个知识点即可

1:图片是通过image对象形式绘制在画布上的,然后使用Canvas的getImageData接口,获取图像的像素信息。

var imageData=ctx.getImageData(x, y, width, height);

参数说明:x,y为画布上的x和y坐标

width,height为获取指定区域图像的信息

返回值说明:imageData为返回值,它是一个对象,包含三个属性

2:了解像素区域数据的排布说明,以上获取的图片数据像素信息(imageData对象中的data属性)为RGBA整型的一维数组数据。一个像素是有4个值(R,G,B,A)组成的。也就是说,数组信息每四个为一个像素点。因此,有以下规则,

第一个像素信息为:RGBA(data[0],data[1],data[2],data[3])

第二个像素信息为:RGBA(data[4],data[5],data[6],data[7])

.....

第N个像素信息为: RGBA(data[(n-1)*4],data[(n-1)*4+1],data[(n-1)*4+2],data[(n-1)*4+3])

.....

另外,像素区域既然是一个区域,它是有宽和高的。上面的推算公式适合单独一行使用定位一个像素点。所以计算像素点时要考虑到在整个图像区域内定位:

以上图为例。图像的宽和高都为200,如果按照每一个像素为一行一列时。则该图像共有200行,200列。所以要取得 i 行第 j 列的像素初始位置信息为:

var pos =[( i-1 )*200]+( j-1 )]*4;

其中,公式中的 i 表示行数,j 表示列数。200为图像的宽度。

demo代码:


上面如果不理解, 对照代码运行一下试试理解吧:

这次没能为粒子加上炫酷的动态效果~~下次补上,找一些算法就可以粒子动起来的,有兴趣可以做做看~

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助

整个效果的功能都完成了

如果大家想学习canvas,JavaScript,可以加群:230354270 群里面有每天都会上传视频供大家学习,欢迎学习交流的小伙伴过来一起学习交流!

如果想看到更加系统的文章和学习方法经验可以关注我的微信公众号:‘HTML网页’关注后回复可以领取一套完整的学习视频!

前几天在整理书签时,发现收藏了好多宝藏网站,宝藏项目,就光说文字效果,就让诸位大佬玩出了一万个花样,所以小包准备跟大家一起来分享和学习这些异彩纷呈的创意和写法。

该文作为《文字到底能玩出多少花样》的第一篇文章,首先来带大家学习 文字粒子 的实现。

文字粒子这个创意最先源自于哪位大佬我也不知道,但我最早发现这个效果是 kennethcachia 写的巨炫酷的文字粒子效果,每次我打开这个 demo ,我都感觉我是个审美笨比,大佬做的真炫酷,真漂亮。

下面是 shape-shifter 效果的 github 地址和 demo 演示界面:

  • shape-shifter
  • Demo演示地址

不多说了,一起进入阿包的文字粒子效果吧。

基础知识

文章最开始之前,先带大家了解两个 canvas 函数

fillText

语法

ctx.fillText(text, x, y, [maxWidth]);
复制代码

参数

  • text: 规定在画布上输出的文本。
  • x: 文本起点的 x 轴坐标。
  • y: 文本起点的 y 轴坐标。
  • maxWidth: 可选,绘制的最大宽度。

可以通过 font 属性来定义字体和字号,fillStyle 属性来定义字体颜色。

getImageData

语法

ctx.getImageData(sx, sy, sw, sh);
复制代码

参数

  • sx, sy: 要提取图像的左上角 x y 坐标
  • sw, sh: 要提取图像的宽高

返回值

  • 返回 ImageData 对象,该对象拷贝了指定图像区域的像素
  • 对于图像中的每个像素点,都分别存放 RGBA 四方面的信息,所有的像素数据以一维数组形式存放在 data 属性中

绘制思路

在基础知识方面,我首先介绍了两个方法: fillText 和 getImageData 。 fillText 可以在画布上绘制文字,getImageData 可以提取画布上一定矩形区域的像素点。也就是说,通过这两个方法就可以提取到我们绘制的文字的像素数据。那剩下的工作就是怎么处理这些像素数据,绘制对应运动粒子就可以。

下面来分析一下具体实现思路:

  1. 绘制主画布: 作为文字粒子的渲染画布
  2. 生成副画布: 作为绘制文字的画布,不需要添加到页面中,作为提取绘制文字像素的载体
  3. 生成文字粒子: 根据获取到的像素点,渲染粒子
  4. 文字粒子运动轨迹: 计算每个粒子的移动轨迹
  5. 启动动画

初始化工作

设立配置项 options 和 textOptions ,分别存放画布的宽高、速度等信息和副画布文字的配置。

const options = {
    width: 400,
    height: 400,
    speed: 10
};
const textOptions = {
    words: "战场小包",
    font: "200px fangsong",
};
复制代码

绘制主画布

主画布已经通过 标签添加至页面中,因此只需要配置它的 width 与 height ,为了方便展示,将 canvas 宽高设置为浏览器宽高

function pointCanvas(canvas, { width, height }) {
    canvas.width = width;
    canvas.height = height;
    ctx = canvas.getContext("2d");
    return ctx;
}
// pointCavas(canvas, options)
复制代码

创建副画布

副画布的创建也非常简单,只需要通过 JavaScript 创建一个 canvas 节点,配置副画布的宽高(与主画布相同),不需要添加到 dom 中。

副画布与主画布的宽高保持一致,这样副画布中的像素点,就可以对应到主画布中的像素位置,无需进行转换

function createVitualCvs({ width, height }) {
    const vitualCvs = document.createElement("canvas");
    vitualCvs.width = width;
    vitualCvs.height = height;
    let vitualCxt = vitualCvs.getContext("2d");
    initCanvas(vitualCxt, options, textOptions);
    return getFontInfo(vitualCxt, options);
}
复制代码

初始化副画布

设置文字属性,通过 fillText 绘制文字。通过 (canvas.width - measure.width) / 2 保证在画布中间绘制文字。

measureText 可以获取到文字的宽高,更详细的参考链接: measureText

function initCanvas(ctx, { width, height }, { font, words }) {
    ctx.font = font;
    const measure = ctx.measureText(words);
    ctx.fillText(words, (width - measure.width) / 2, height / 2);
}
复制代码

构建粒子类

每个粒子有以下属性:

  • x: 粒子最终停留的位置 x 坐标
  • y: 粒子最终停留的位置 y 坐标
  • mx: 初始化时粒子的 x 坐标位置
  • my: 初始化时粒子的 y 坐标位置
  • radius: 粒子大小
  • speed: 粒子移动速度

同时还具备两个方法:

  • draw: 绘制粒子本身的方法
  • update: 更新粒子位置的方法

这里给出 draw 和 update 方法代码

draw() {
    ctx.beginPath();
    ctx.fillStyle = this.color;
    ctx.arc(this.mx, this.my, this.radius, 0, Math.PI * 2, false);
    ctx.fill();
    this.update();
}
// 我这里的 update 比较简单,如果想要更复杂更炫酷的效果,可以使用贝塞尔曲线 
update() {
    this.mx = this.mx + (this.x - this.mx) / this.speed;
    this.my = this.my + (this.y - this.my) / this.speed;
}
复制代码

获取文字位置信息,绘制粒子

通过 getImageData 获取副画布的像素信息,getImageData 返回值中对每个像素点存储 RGBA 四方面信息,因此每四个数组元素代表一个像素点,可以通过 Alpha 来判断该像素点是否存在文字。

function getWordPxInfo(ctx, { width, height }) {
    let imageData = ctx.getImageData(0, 0, width, height).data;
    const particles = [];
    for (let x = 0; x < width; x += 4) {
        // 为了粒子效果出现,间隔选点
        for (let y = 0; y < height; y += 4) {
        // 判断当前像素点是否有文字
        const pxAlphaIndex = (x + y * width) * 4 + 3;
        if (imageData[pxAlphaIndex] > 0) {
            particles.push(
            new Particle({
                x,
                y,
            })
            );
        }
        }
    }
    return particles;
}
复制代码

启动动画

动画是通过 requestAnimationFrame 实现,每一帧清空画布,重新绘制所有的粒子。

requestAnimationFrame学习: 【今天你更博学了么】一个神奇的前端动画 API requestAnimationFrame

function init(points, { width, height }) {
    ctx.clearRect(0, 0, width, height);
    points.forEach((value) => {
        value.draw();
    });
    const timer = window.requestAnimationFrame(function () {
        init(points, options);
    });
}
复制代码

大功告成

大功告成,摸鱼成功。


源码仓库

传送门: 文字粒子