建立我的响应式网站,我想建立我有趣的时间表,但是我无法提出解决方案。
它将是精灵,例如火箭或飞碟,它们会从页面中间的底部起飞并冒出烟雾。
抽烟或多或少会保留并透露我的时间表。
有没有人知道如何实现这一目标?
答案 0 :(得分:1)
要模拟烟雾,您必须使用粒子系统。 如您所知,WebGL能够绘制三角形,直线和点。 这是我们所需要的。烟雾是由数百个大小各异的半透明白盘组成的。每个点由7个属性定义:
一个技巧是沿垂直居中轴创建点。上升的次数越多,延迟越大。另一个窍门是使该点在到达生存期时变得更加透明。
以下是创建此类顶点的方法:
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/