上一节我们探究了绘制静态图像手绘与码绘的差异,但是万事万物,变化万千,有很多东西仅仅用静态是无法描述的。
正如恩格斯所言:“整个自然界,从最小的东西到最大的东西,从沙粒到太阳,从原生生物到人,都处于永恒的产生和消灭中,处于不断的流动中,处于无休止的运动和变化中。”世间万物都是出于永不停歇的运动状态,因为有了运动,我们才会有丰富多彩的各种变换。

让我们来看看几组动态图像作品感受一下动态的魅力

水墨画

android 抖音烟花特效 抖音烟花动态壁纸_p5.js

流淌的河流

android 抖音烟花特效 抖音烟花动态壁纸_p5.js_02

飘落的雪花

android 抖音烟花特效 抖音烟花动态壁纸_javascript_03

看完以上作品,动态真是能够很贴切很形象的展现事物的美感了

这次要绘制的也是动态的作品——烟火,辛弃疾有诗:“东风夜放花千树。更吹落,星如雨。”动态的烟火转瞬即逝,它所求只是在人们眼前短暂的停留几秒,带来美的愉悦与享受,喜欢烟火的那一瞬间,把最美的,霎那间的光辉,留在了短暂的夜空。诗人笔下写出了多少烟花的绚烂,画家手中又描绘出多少烟花的色彩,在烟花绽放的一瞬间,他的生命也随之消失在无边的黑夜之中。烟火的绘制不仅仅是一种美的欣赏,也是对转瞬即逝的事物的感慨,一片片烟花绽放、消失,但开得很是灿烂、很是尽情,仿佛要把自己整个生命中的光芒在一瞬间展示出来。洋溢出生命的活力与激情、很是振奋人心,给人以无穷地感染力。那我们用画笔和代码实现烟花的动态绘制岂不妙哉。

花了一番功夫,实现了烟花的手绘和码绘,先来展现一下最终成果图吧

手绘作品

android 抖音烟花特效 抖音烟花动态壁纸_烟花绘制_04

要点

烟火的手绘过程:先建立参考线,围绕参考线中心点周围做圆形状的点状分布,密度情况按照自己想制作的烟花的密度情况而定。然后旋转图像角度,用滤镜来实现飘落的轨迹,然后调整一下色彩的明度和对比度就OK啦。

码绘作品

android 抖音烟花特效 抖音烟花动态壁纸_android 抖音烟花特效_05

要点

烟花:是粒子上升到一定的高度,然后在距离爆炸中心点一定范围内随机产生随机颜色的爆炸粒子而形成的轨迹。它的的逼真在于其颜色的多彩变幻和运行轨迹的合理性。从现象上看,一道光柱逐渐上升,到达一定高度时停止,同时出现多个粒子以一定半径散开并逐渐下降。随着烟花绽放的时间增加,其颜色逐渐暗淡,最终消逝不见。

1.粒子属性初始化
x, y代表运行轨迹的当前坐标。控制运动的代码部分只需要负责计算并更新x和y的值

this.firework = firework;
  this.lifespan = 255;
  this.pos = createVector(x,y);

2.色彩的随机
不仅每一个烟花之间的颜色是不一样的,而且同一个烟花在炸的过程中,它会变颜色。在程序中,通过随机数*RGB来实现。

function randombinary(){
    x = random(1);
    if(x<0.5){
      return 1;
    } else {
      return 0;
    }
  }
  
  //调整烟花随机颜色,使其更亮丽
  this.colorR = 255*randombinary();
  this.colorG = 255*randombinary();
  this.colorB = 255*randombinary();
  
  if (this.colorR+this.colorG+this.colorB == 0){
    this.colorR = 255*randombinary();
    this.colorG = 255*randombinary();
    this.colorB = 255;
  }

3.粒子的更新和消亡
使用 update函数对粒子进行更新,done函数实现粒子的消亡,如此每一次清除画布将使原有的图形被最新的烟花轨迹覆盖,随着时间流逝,粒子最终消失在夜幕背景下,

this.update = function() {
    
    if(!this.exploded){
      this.firework.applyForce(gravity);
      this.firework.update();
      
      if(this.firework.vel.y >= 0){
        this.exploded = true;
        this.explode();
      }
    }
    
     for(var i = this.particles.length-1; i>=0; i--){
      this.particles[i].applyForce(gravity);
      this.particles[i].update();
      
      if(this.particles[i].done()){
        this.particles.splice(i,1);
      }
    }
  };
  
this.done = function(){
    if(this.exploded && this.particles.length === 0){
      return true;
    } else {
      return false;
    }
  };

4.粒子的爆炸轨迹
烟花轨迹模拟的核心是模拟物体在物理力作用下的运行状态。在此我们主要考虑方向、速度、重力的影响。烟花在爆炸时向四面八方散开,体现在2D画布上就是0~360度随机方向。我们假想在爆炸的一瞬间冲击力最大,速度最大,然后受阻力影响速度逐渐减小。此外我们需要考虑重力的影响,使其最终大致呈自由落体运动。这里使用了p5.js的粒子系统类来实现对粒子施加力的效果以及重力效果。

this.explode = function() {
    
    explode.setVolume(0.1);
    explode.play();
    
    for(var i = 0; i<250; i++){
      var p = new Particle(this.firework.pos.x, this.firework.pos.y, false, this.colorR, this.colorG, this.colorB);
      this.particles.push(p);
    }
  };

5.用户与界面交互的实现
用户鼠标在界面滑动,生成不同颜色大小的烟花。

fireworks.push(new Firework(mouseX, mouseY));

6.将编写的程序挂载到网页

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width">
  <script language="javascript" type="text/javascript" src="libraries/p5.js"></script>
  <script language="javascript" src="libraries/p5.dom.js"></script>
  <script language="javascript" src="libraries/p5.sound.js"></script>
  <script language="javascript" type="text/javascript" src="particle.js"></script>
  <script language="javascript" type="text/javascript" src="firework.js"></script>
  <script language="javascript" type="text/javascript" src="main.js"></script>

  <style> body {padding: 0; margin: 0;} </style>
</head>

<body>
</body>
</html>

接下来我们从不同的几个方面来谈谈手绘与码绘的异同。

(1)技法

手绘是一门精细的具有实际用途的学问,需要一种活跃又不失严谨的思维状态以及实际操作去学习以及领悟。当然,既然手绘作为一种手上技能,那么肯定需要足够多的实际动手操作才能越画越好。烟火的手绘是比较简单的,你只需要绘制一个烟火,然后改变形状和颜色,使其置于合适的位置,然后调整一下色彩的明度和对比度就OK啦。码绘时,烟花的各种属性都要考虑进去,比如爆炸范围、色彩变化、重力的调节,这些都是为了使作品的体现比较生动形象。还有不同函数的调用,比较关键的是几个循环函数和随机函数,它可以使烟火的绘制更自然。

(2)工具

手绘使用的工具是Photoshop:它主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具,可以有效地进行图片编辑工作。
码绘使用的工具是p5.js :它是一个库配上许多工具,它让编程爱好者、艺术家、设计师们轻松使用 JavaScript 语言进行创意编程。编辑代码的工具是vs code 2017,你也可以直接在P5 js的官网上https://p5js.org/进行编辑,作为一种简单而友善的环境,p5.js 提供了一种通过创建交互式图形来学习编程的方法,这也大大降低了学习 JavaScript 的难度。
为什么选择JavaScript脚本语言来编写呢,其优势在于 JavaScript 广泛的可用性和无处不在的支持——每个 Web 浏览器都内置了 JavaScript 解释器,也就意味着 p5.js 程序通常可以在任何Web浏览器中运行。有人把它看作是 Processing 的 Web 版本。这也并不无道理。它们都在构建草图和原型方面有着无可替代的优势,既好玩又方便,让我们在很短的时间内能探索更多的想法。

(3)创作理念

绘画点点滴滴都是来自生活,无论是一棵树、一株草、一朵花、一块石头、一块木头、流水、山石、房屋,或者一个动作、一丝气息、一抹颜色等等,都是与我们的生活息息相关的,画面上的场景来自于生活而归于生活,只有了解了生活中的点点滴滴,才能准确地表现出物体与场景的形、色、构成,才能将自然的神、生活的韵以及画者的精神绘声绘色地表现在人们面前。本次实验的选材也是源于生活,传达出一种对美好的向往。

(4)创作体验

不要拿着笔就开始画。对一个空间进行刻画前。首先应该大体上了解这个空间的内部构造,以及空间内部主要的陈设,做到心中有数,能够合理在纸张上安排画面后才开始动笔。否则看到一部分就开始刻画,后面很可能会产生比例问题。我们不是大师,可以窥一发而知全身。我们当前要做的就是慢慢一步一个脚印的走。有时画出的画总是或多或少有比例上的问题。这主要还是基于观察不够以及练习不够的原因。观察不够,下笔匆忙自然没有过多的全局观,容易导致构图比例出现问题。而这些归根结底还是练习不够多的原因,所以对于构图的把握还不成熟,才容易出现这样的问题。码绘时,你会发现可能就是一个简单的扇形,你可能绘制都要花一番功夫,但好在前辈们已经打好了基础,你可以通过调用不同的函数库,加以修改和补充,就能绘制很多图案出来。对于不了解编程这方面的朋友们来说,也许你看到的只是一副简单的图画,但是其中包含的代码和心血超出你的想象,或许你用手绘几分钟就能搞定,但在写代码时,代码的逻辑性需要十分的严谨,一个不注意,可能会造成“车祸现场”(手动滑稽)。

(5)呈现效果

在呈现效果上,手绘可能更具有感染力和张力,你可以通过画笔表达你所想,将情感寄托于你自己的作品上,给人以触发。码绘虽然缺少一点感染力,但是通过不断地逻辑思考和函数的编写,呈现效果上可能会带来不一样的惊喜。

(6)交互性

在网络传播中,受者能够通过多种输入输出方式与系统或者其他受者在一定程度上进行直接双向交流的特性被称为网络交互性。从传播的基本模式来看它是这样的一个过程,传者发出讯息,并通过受者的反馈来确认传播的效果;而受者不但接收讯息,而且也会根据自己的理解做出相应的反馈。码绘的烟花就实现了与用户的交互,通过鼠标在屏幕滑动,产生不同的烟花粒子,给用户更有趣的体验。

(7)局限性

绘画中的光线是非常重要的,只有通过光影,才能产生体感,产生空间感,并且光影也是烘托某种气氛的重要元素,光影对于画面来说是非常重要的,真实的反应我们肉眼所能看到的实物,并用绘画手段将其本身在有光线情况下,将他固有的质感,形体表现出来。西方画家多采用光影画法来作为画面表达技法,利用光影来突出主体物,而中国画家又采用水彩光影表现技法这种技法也要求绘画者不能单纯从表象观察到光,而要在实际的构思中去灵活运用光。而码绘在光影效果的实现上比较复杂,不容易表现,实现需要较高的技术。

体会

通过以上对比我们可以发现,码绘和手绘各有所长,各有所短,毕竟事物都不是完美的,码绘和手绘本来就有许多相通的地方,只是一个用画笔画画,一个用代码画画罢了。不同工具的使用会带来不同的效果,虽然它们在创作时会给创作者不同的体验,但是从本质上来讲,它们都是为了绘制出更优质的作品服务的。不知道看到这里的朋友,更喜欢哪种绘画方式呢?

参考资料

1.用p5.js制作烟花特效
链接:https://www.huuinn.com/archives/146

2.量化绘画:程序和绘画之间的化学反应
链接:https://36kr.com/p/5038073.html