iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript+Canvas实现文字粒子流特效
  • 876
分享到

JavaScript+Canvas实现文字粒子流特效

摘要

目录动手前思考绘制文字获取像素点位渲染粒子简单的动画效果1、随机选择四个方向中的某一个方向,生成初始坐标2、从初始位置运动到实际位置3、点击文字炸开的特效动手前思考 首先要在特定的位

动手前思考

首先要在特定的位置生成粒子,要获取到canvas上像素的点位,通过canvas的getImageData函数我们可以得到canvas像素点的信息,获取像素点中透明度大于0的位置。

绘制文字

新建一个canvas画布,在画布上绘制任意的文字

ctx.font = "200px Arial";
ctx.fontWeight = "900";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillStyle = "red";
ctx.fillText("稀土掘金", 0, 0);

获取像素点位

canvas的getImageData函数返回了imageData对象,该对象复制画布上指定矩形的像素数据,数组中四个值一组存放像素的RGBA信息,其中A代表透明度,当透明度大于0时表示该位置上可以生成粒子。

对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:

  • R - 红色 (0-255)
  • G - 绿色 (0-255)
  • B - 蓝色 (0-255)
  • A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

也就是

red=imgData.data[0];
green=imgData.data[1];
blue=imgData.data[2];
alpha=imgData.data[3];

调用getImageData函数,有4个参数,x/y表示开始复制的左上角位置的xy坐标,width/height表示将要复制的矩形区域的宽度和高度。

var imgData=context.getImageData(x,y,width,height);

imageData对象信息如下:

如果绘制文字较小最好截取所在矩形位置,以减少获取的data数组。获取canvas绘制文字的宽度方法如下:

const { width } = ctx.measureText(this.text);

遍历数组,得到可用像素点:

  • 4组一个像素点,gap表示点的间隔,我们只获取A的位置。
  • wl表示canvas宽度,矩形像素格子排满宽度后会换行,由此可以计算出点位的xy坐标。因为四个组合一个点,所以wl要乘以4。
const gap = 4;
for (let i = 0, wl = this.canvas.width * gap; i < length; i += gap) {
    if (data[i + gap - 1]) {
      // 根据透明度判断
      const x = (i % wl) / gap;
      const y = parseInt(i / wl);
      this.textPoints.push([x, y]);
    }
}

渲染粒子

获取到像素点位textPoints数据之后就可以开始渲染粒子了

  • 新建一个画布,隐藏获取像素点的画布,在这个新的画布上绘制粒子
  • 设置粒子的半径为5,间隔10个点位生成一个粒子
  • 粒子的颜色随机生成,最终得到如下图:

let startX;
let startY;
const points = [];
for (let i = 0; i < this.textPoints.length; i++) {
    let point = this.textPoints[i];
    let x = point[0];
    let y = point[1];
    const radius = 5;
    // const radius = Math.random() * 10; // 随机生成粒子宽度
    const color = parseInt(Math.random() * 0xffffff).toString(16); // 随机生成粒子颜色
    const { x: x0, y: y0 } = this.adjustPoint(x, y); // 矫正粒子相对于画布所在位置
    if (i == 0 || ((x - startX) % 10 == 0 && (y - startY) % 10 == 0)) {
      startX = x;
      startY = y;
      const params = { x: x0 + radius, y: y0, radius, color };
      points.push(params);
    }
}

优化展示效果

  • 为了让生成的文字更好看,我们可以随机设置粒子的半径
  • 为了避免后面生成的粒子总是挡住前面粒子,我们可以随机生成粒子的顺序
  • adjustPoint函数让粒子在新画布中居中展示
this.points = points.sort((a, b) => (Math.random() > 0.5 ? -1 : 1)); // 随机排序
adjustPoint(x, y) {
  const { width, height } = this.canvasLizi;
  return {
    x: x + (width - this.textWidth) / 2,
    y: y + (height - this.textSize) / 2,
  };
}

简单的动画效果

  • 粒子从上下左右四个方向随机生成,汇聚到画布中心点
  • 点击文字时,粒子出现炸开的特效

1、随机选择四个方向中的某一个方向,生成初始坐标

  • 从左边进入画布初始坐标为(0,y),从右边进入画布初始坐标为(canvasWidth, y),y是随机数
  • 从上边进入画布初始坐标为(x,0),从下边进入画布初始坐标为(x,canvasHeight),x是随机数
for (let item of this.points) {
    let direction;
    const num = Math.random() * 1;
    if (num < 0.25) {
      direction = "left";
      item.initX = 0;
      item.initY = Math.random() * height;
    } else if (num < 0.5) {
      direction = "right";
      item.initX = width;
      item.initY = Math.random() * height;
    } else if (num < 0.75) {
      direction = "top";
      item.initX = Math.random() * width;
      item.initY = 0;
    } else {
      direction = "bottom";
      item.initX = Math.random() * width;
      item.initY = height;
    }
}

2、从初始位置运动到实际位置

  • 计算实际点与运动点之间的坐标差offsetX,offsetY
  • 判断差值是正数还是负数,当x差值为正数,则每次运动的速率为正,否则为负;当y差值为正数,则每次运动的速率为正,否则为负。
  • 计算每次运动的增量或减量。因为初始坐标和实际坐标连线可能是一条斜线,当x增加或减少一定数值,y值增量或减量等于x增量或减量乘以斜率。
animatDot() {
  if (!this.points.find((item) => item.hasOwnProperty("initX"))) {
    // 当不存在运动点时取消动画
    cancelAnimationFrame(this.animatDot.bind(this));
    return;
  }
  this.points.forEach((item) => {
    const offsetX = item.x - item.initX;
    const offsetY = item.y - item.initY;
    if (Math.abs(offsetX) > 0 || Math.abs(offsetY) > 0) {
      const rate = offsetX / 10; // 速率等于坐标差除以10,不断缩小运动距离
      const x = item.initX + rate;
      if (Math.abs(rate) < 1) {
        item.initX = item.x; // 当运动距离小于1时,等于实际坐标
      } else {
        if (offsetX > 0) {
          item.initX = x < item.x ? x : item.x;
        } else {
          item.initX = x > item.x ? x : item.x;
        }
      }
      const k = offsetY / offsetX; // 计算斜率
      const y = k * item.initX;
      if (offsetY > 0) {
        item.initY = y < item.y ? y : item.y;
      } else {
        item.initY = y > item.y ? y : item.y;
      }
    } else {
      delete item.initX; // 当运动点坐标和实际坐标相同时,删除初始坐标
      delete item.initY;
    }
  });
  this.drawPoint(); // 绘制粒子函数
  requestAnimationFrame(this.animatDot.bind(this), 1000 / 60);
}

3、点击文字炸开的特效

  • 监听鼠标点击事件,获取鼠标点击坐标clickPointX,clickPointY
  • 设置一个鼠标点击缓冲区clickRange,使一定范围内的粒子都产生炸开的效果;设置一个炸开的最远距离spreadRange,当大于该距离就停止运动
  • y轴的移动还是跟斜率有关系,要计算运动点跟鼠标点击位置的斜率
this.clickRange = 30; // 点击范围
this.spreadRange = 30; // 扩散范围
PBomb() {
  const that = this;
  function animaion(time) {
    that.PBomb();
  }
  if (!this.points.find((item) => item.bomb)) {
    cancelAnimationFrame(animaion); // 停止动画判断
    return;
  }
  const step = 10; // x轴步长,每帧增加或减少的大小
  this.points.forEach((point) => {
    if (point.bomb) {
      if (point.bombX > this.clickPointX) {
        if (point.bombX < point.x + this.spreadRange) {
          point.bombX += step;
        } else {
          point.bomb = false;
        }
      }
      if (point.bombX < this.clickPointX) {
        if (point.bombX > point.x - this.spreadRange) {
          point.bombX -= step;
        } else {
          point.bomb = false;
        }
      }
      const k =
        point.x - this.clickPointX == 0
          ? 1
          : Math.abs(
              (point.y - this.clickPointY) /
                (point.x - this.clickPointX),
            ).toFixed(2); // 计算斜率
      if (point.bombY > this.clickPointY) {
        if (point.bombY < point.y + this.spreadRange) {
          point.bombY += k * step;
        } else {
          point.bomb = false;
        }
      }
      if (point.bombY < this.clickPointY) {
        if (point.bombY > point.y - this.spreadRange) {
          point.bombY -= k * step;
        } else {
          point.bomb = false;
        }
      }
    }
  });
  this.drawPoint();
  setTimeout(() => {
    requestAnimationFrame(animaion);
  }, 1000 / 10);
}

最终效果:

最后加上修改文字内容和大小的功能就完美了

到此这篇关于javascript+Canvas实现文字粒子流特效的文章就介绍到这了,更多相关JavaScript Canvas文字粒子流内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript+Canvas实现文字粒子流特效

本文链接: https://www.lsjlt.com/news/177739.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript+Canvas实现文字粒子流特效
    目录动手前思考绘制文字获取像素点位渲染粒子简单的动画效果1、随机选择四个方向中的某一个方向,生成初始坐标2、从初始位置运动到实际位置3、点击文字炸开的特效动手前思考 首先要在特定的位...
    99+
    2023-01-14
    JavaScript Canvas文字粒子流特效 JavaScript Canvas粒子流 JavaScript Canvas
  • js canvas实现随机粒子特效
    本文实例为大家分享了js canvas随机粒子特效的具体代码,供大家参考,具体内容如下 前言 canvas实现前端的特效美术 结果展示 代码 html <!DOCTYPE...
    99+
    2024-04-02
  • JavaScript+Canvas实现酷炫的粒子和流星效果
    目录一:粒子效果二:流星效果一:粒子效果 <html> <head> <meta charset="utf-8"> <title&...
    99+
    2023-01-31
    JavaScript实现粒子效果 JavaScript实现流星效果 JavaScript 粒子 JavaScript 流星
  • JavaScript canvas实现流星特效
    本文实例为大家分享了JavaScript canvas实现流星特效展示的具体代码,供大家参考,具体内容如下 1、控制透明度变化函数 function easeInQuad(cur...
    99+
    2024-04-02
  • 怎么在JavaScript中使用canvas实现一个随机粒子特效
    本篇文章给大家分享的是有关怎么在JavaScript中使用canvas实现一个随机粒子特效,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java的特点有哪些Java的特点有哪些...
    99+
    2023-06-14
  • JavaScript+Canvas实现带跳动效果的粒子动画
    目录前言实现过程运行效果总结前言 用 HTML5 的 Canvas 元素实现一个带有跳动效果的粒子动画。会用到 Canvas 的2D渲染上下文,通过 JavaScript 编写绘图代...
    99+
    2023-03-14
    JavaScript Canvas实现粒子动画 Canvas粒子动画 JavaScript Canvas
  • Canvas如何制作烟花粒子特效
    小编给大家分享一下Canvas如何制作烟花粒子特效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!<!DOCTYPE&nbs...
    99+
    2024-04-02
  • JavaScript中canvas如何实现流星特效
    小编给大家分享一下JavaScript中canvas如何实现流星特效,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、控制透明度变化函数function easeInQuad(curtime,begin,end,...
    99+
    2023-06-15
  • canvas如何实现粒子动画
    本篇内容主要讲解“ canvas如何实现粒子动画”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ canvas如何实现粒子动画”吧!代码如下:<!DOCTY...
    99+
    2024-04-02
  • JavaScript利用Canvas实现粒子动画倒计时
    目录canvas 粒子动画介绍何为canvas粒子动画是啥canvas定义初始变量初始化canvas和数字文本创建一定数量的点倒计时倒计时文本绘画循环绘制点动画效果图canvas 粒...
    99+
    2022-12-09
    JavaScript Canvas粒子动画倒计时 JavaScript  粒子动画倒计时 JavaScript Canvas 倒计时 JavaScript 倒计时
  • ThingJS粒子特效一键实现雨雪效果
    目录1、粒子效果2、 加载场景3、不同粒子特效实现结尾:使用ThingJS可以快速编写粒子效果,比如:下雨、下雪(可以控制雨雪大小)、喷水、火焰效果等,甚至可以通过对接第三方的数据,...
    99+
    2024-04-02
  • ThingJS粒子特效如何实现雨雪效果
    这篇文章主要介绍了ThingJS粒子特效如何实现雨雪效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用ThingJS可以快速编写粒子效果,比如:下雨、下雪(可以控制雨雪大...
    99+
    2023-06-15
  • 使用canvas怎么实现一个粒子动效
    本篇文章为大家展示了使用canvas怎么实现一个粒子动效,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。绘制刻度此例为小时刻度的绘制:表盘上共有12个小时,Math.PI为180&deg;,每...
    99+
    2023-06-09
  • 怎么使用JavaScript+Canvas实现带跳动效果的粒子动画
    这篇“怎么使用JavaScript+Canvas实现带跳动效果的粒子动画”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使...
    99+
    2023-07-05
  • vue实现登录页背景粒子特效
    本文实例为大家分享了vue实现登录页背景粒子特效的具体代码,供大家参考,具体内容如下 上图中的点和线,是由Vue-Particles生成的,不仅自己动,还可以与用户的鼠标互动。例子...
    99+
    2024-04-02
  • JavaScript实现带粒子效果的进度条
    本文实例为大家分享了JavaScript实现带粒子效果进度条的具体代码,供大家参考,具体内容如下 <html>     <head>         <...
    99+
    2024-04-02
  • canvas如何实现粒子喷泉动画
    今天小编给大家分享一下canvas如何实现粒子喷泉动画的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了...
    99+
    2024-04-02
  • vue怎么实现登录页背景粒子特效
    这篇“vue怎么实现登录页背景粒子特效”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“vue怎么实现登录页背景粒子特效”文章吧...
    99+
    2023-06-29
  • 使用Canvas怎么将文本转换为粒子效果
    使用Canvas怎么将文本转换为粒子效果?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实现原理总的来说要做出将文本变成粒子展示的效果其实很简单,实现的原理就是使...
    99+
    2023-06-09
  • jQuery实现动态粒子效果
    本文实例为大家分享了jQuery实现动态粒子效果的具体代码,供大家参考,具体内容如下 效果图 代码 <!DOCTYPE html> <html lang="...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作