zoukankan      html  css  js  c++  java
  • 谈谈文字图片粒子化

      之前写了谈谈文字图片像素化,主要是为了将文字和图片像素化后的坐标提取出来,而本篇所讲即为像素化后的粒子化过程。

      先上一个简单的demo -> 粒子化demo,本篇的目的就是为了讲解怎样做这样的简单demo(大牛请无视);同时会介绍一些优秀的demo供大家参考。

    主要思路

      首先我们谈谈粒子化的主要思路。

      像素化后(不知道怎样像素化,参考谈谈文字图片像素化),我们得到了所需图像或者文字的具体坐标,我们将它们形象地用一个个的粒子表示(这里用了圆形),得到的坐标即是粒子的最终位置。粒子的初始位置在哪里?粒子从初始位置到最终位置的运动又是如何?这些是我们可以自由发挥的。所以粒子化过程究其根本,就是怎样表示粒子的运动过程。

    基本准备

    • canvas自适应电脑屏幕(不出现滚条):

    css部分:

    body {margin:0; padding:0; wdith:100%; height: 100%}
    canvas {display:block; background-color:#000}
    

    js部分:

    window.canvas = document.createElement('canvas'); 
    document.body.appendChild(window.canvas); 
    canvas.height = window.height = window.innerHeight;
    canvas.width = window.width = window.innerWidth;
    • 关于像素化再补充几句:

      像素化过程简单描述就是将所需的文字fillText到画布上或者将图片drawImage到画布上(设置一个离屏的canvas),然后利用getImagedata这个api将像素点提取出来。值得注意的是getImagedata并不会获取背景点的像素,所以canvas的背景使用怎样的颜色并不会影响像素点的提取。

      一般像素点的提取是根据某个像素点rgba的a值进行判断,a值的取值是0~255(rgba当做颜色属性赋值时a的取值是0~1),通常做法是判断a值非0或者半透(>125)。这里我也做了个简单的测试,当color值取black或者#000时,a值如下:

               

    • 关于阴影

      粒子化效果一般在黑夜最漂亮,所以背景我一般设置成黑色。如果要更带感,需要一点阴影效果。

      其实很简单,调整一下透明度即可。比如这样:

      当然用globalAlpha也是一样的。
     
    • 粒子具有的属性:
      将粒子放入运动场中,我们可以赋予它一些属性,比如速度,加速度,位移等等,而这些属性都可以用矢量来表示。
     

    粒子运动

      之前我说过,以上皆是铺垫,运动才是粒子化的关键。因为粒子最终要汇聚成一定的形状,所以运动的某一段的终点已知,那么粒子怎样能运动到对应的位置?

      我们从最简单的直线运动说起。

    • 直线运动:

      谈谈文字图片像素化中用的demo就是直线运动 -> 像素化

      如何用js描述一个直线运动?首先我们要明白在怎样的情况下物体会做直线运动?学过物理我们知道速度和加速度在一条直线时,物体做直线运动。

      那么很简单,已知粒子的终点,随机粒子的起点,速度方向就确定了(起点指向终点),如果有必要,还可以设置加速度。
     
    • 曲线运动:
      仅仅做直线运动或许视觉效果太差,曲线运动会不会产生更好的视觉效果?
      什么情况下物体会做曲线运动?速度和加速度不在一条直线时,比如抛物运动。
      先看这个demo:demoHome(W·Axes) 我们取它的第一个过程进行分析,实际上就是一个二维的曲线运动。和抛物运动的不同之处是,加速度方向指向粒子的终点,为的是能够准确达到终点位置。W.Axes的另一个粒子demo也大同小异:粒子化,相比于前一个demo只是改变了粒子的初始位置和初始速度,以及粒子运动顺序。
      我们尝试着来完成一个demo。
      前面说到,为了能使粒子能到达指定的位置,我们给了粒子一个指向指定位置的加速度,在粒子的每一帧运动中,可以将该加速度分解到x和y轴分别进行计算。比如这样:
    update: function() {
      var v = this.pos2.minusNew(this.now);
      var angle = v.getAngle();
      this.v.x = (this.v.x + this.a * Math.cos(angle) / 1000 * 60) * 0.96;
      this.v.y = (this.v.y + this.a * Math.sin(angle) / 1000 * 60) * 0.96;
      this.now.x += this.v.x;
      this.now.y += this.v.y;
    }
    

      a表示粒子的加速度值,/1000*60表示每帧的速度增加,*0.96模拟能量损失。这样的运动的话粒子通过曲线运动就能到达指定位置。

      模拟屏幕左上角到屏幕中心的曲线运动:

      当然你也可以自己设置运动函数,不过我觉得这样比较方便而已。
     
      
    • 关于缓动:
      有时为了效果我们需要设计一个缓动,什么是缓动?就是速度越来越小的运动。
      或许涉及到x和y轴同时变化的运动太过复杂,我们假设一个物体沿着x轴正方向运动,并且物体运动速度越来越小,即为缓动。
      最简单的缓动如下:
    update: function() {
      var v = this.pos2.minusNew(this.now);
      v.scale(0.05);
      this.now.add(v);
    }
      稍微复杂点的缓动v-s图像可以设计成二次函数或者三角函数,因为某点的切线的斜率即为速度,而切线斜率越来越小即为速度越来越小。
      更多可以参考岑安的文章 -> 【前端应该知道的那些事儿】运动学基础
     
    • 二维三维:
      三维和二维环境下的粒子化其实大同小异,不了解三维的话可以参考rotate 3d基础试着实现一个球体的3d旋转demo。
     

    关于创意

      其实粒子化本身并不难,难的是创意。这里稍微介绍几个有创意的demo。

      codepen上的一个demo,代码很长,其实实现思路也大同小异,就是变着花样的粒子的运动。

      同样只是粒子的运动,只是多了点创意,构造了动态文字效果。

    总结

      文字图片粒子化其实就是粒子系统的一部分,不妨可以从最简单的一个粒子系统开始,一步步实现一个简单的粒子化demo。

      觉得不尽兴,可以参考下面更多文章:

      

      
  • 相关阅读:
    Unable to satisfy the following requirements解决方式
    零基础学python》(第二版)
    mysql 更新数据表的记录
    mysql创建数据库和删除数据库
    正则表达式
    python lambda函数详细解析(面试经常遇到)
    Linux 命令 统计进程数目
    Python 时间戳与时间字符串互相转
    python 安装配置(windows)
    linux 系统 tar 的用法详解
  • 原文地址:https://www.cnblogs.com/lessfish/p/4303125.html
Copyright © 2011-2022 走看看