如何建立我有趣的时间表?

时间:2018-07-16 17:48:25

标签: animation timeline effect

建立我的响应式网站,我想建立我有趣的时间表,但是我无法提出解决方案。

它将是精灵,例如火箭或飞碟,它们会从页面中间的底部起飞并冒出烟雾。

抽烟或多或少会保留并透露我的时间表。

Sketch

有没有人知道如何实现这一目标?

1 个答案:

答案 0 :(得分:1)

要模拟烟雾,您必须使用粒子系统。 如您所知,WebGL能够绘制三角形,直线和点。 这是我们所需要的。烟雾是由数百个大小各异的半透明白盘组成的。每个点由7个属性定义:

  • x,y:起始位置。
  • vx,vy:方向。
  • 半径:最大半径。
  • life:消失之前的毫秒数。
  • delay:诞生之前要等待的毫秒数。

一个技巧是沿垂直居中轴创建点。上升的次数越多,延迟越大。另一个窍门是使该点在到达生存期时变得更加透明。

以下是创建此类顶点的方法:

function createVertices() {
  var x, y, vx, vy, radius, life, delay;
  var vertices = [];
  for( delay=0; delay<1; delay+=0.01 ) {
    for( var loops=0; loops<5; loops++ ) {
      // Going left.
      x = rnd(0.01);
      y = (2.2 * delay - 1) + rnd(-0.01, 0.01);
      vx = -rnd(0, 1.5) * 0.0001;
      vy = -rnd(0.001);
      radius = rnd(0.1, 0.25) / 1000;
      life = rnd(2000, 5000);
      vertices.push( x, y, vx, vy, radius, life, delay );
      // Going right.
      x = -rnd(0.01);
      y = (2.2 * delay - 1) + rnd(-0.01, 0.01);
      vx = rnd(0, 1.5) * 0.0001;
      vy = -rnd(0.001);
      radius = rnd(0.1, 0.25) / 1000;
      life = rnd(2000, 5000);
      vertices.push( x, y, vx, vy, radius, life, delay );
    }
  }

  var buff = gl.createBuffer();  
  gl.bindBuffer( gl.ARRAY_BUFFER, buff );
  gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW );

  return Math.floor( vertices.length / 7 );
}

如您所见,我创建了向右移动点和向左移动点的方法,以获得越来越大的模糊三角形。

然后,您需要一个顶点着色器来控制点的位置和大小。 WebGL提供输出变量 gl_PointSize ,该变量是要为当前点绘制的正方形的大小(以像素为单位)。

uniform float uniWidth;
uniform float uniHeight;
uniform float uniTime;

attribute vec2 attCoords;
attribute vec2 attDirection;
attribute float attRadius;
attribute float attLife;
attribute float attDelay;

varying float varAlpha;

const float PERIOD = 10000.0;
const float TRAVEL_TIME = 2000.0;

void main() {
  float time = mod( uniTime, PERIOD );
  time -= TRAVEL_TIME * attDelay;
  if( time < 0.0 || time > attLife) return;
  vec2 pos = attCoords + time * attDirection;
  gl_Position = vec4( pos.xy, 0, 1 );
  gl_PointSize = time * attRadius * min(uniWidth, uniHeight);
  varAlpha = 1.0 - (time / attLife);
}

最后,片段着色器将以白色显示一个点。但是,离中心越远,碎片变得越透明。 要知道您在当前点绘制的正方形中的位置,可以阅读全局WebGL变量 gl_PointCoord

precision mediump float;
varying float varAlpha;

void main() {
  float x = gl_PointCoord.x - 0.5;
  float y = gl_PointCoord.y - 0.5;
  float radius = x * x + y * y;
  if( radius > 0.25 ) discard;

  float alpha = varAlpha * 0.8 * (0.25 - radius);
  gl_FragColor = vec4(1, 1, 1, alpha);
}

这是一个实时示例:https://jsfiddle.net/m1a9qry6/1/