https://www.cnblogs.com/visualiz/p/fireworks.html
创建模型列表
function
create(){
初始化
circles = [];
for
(
var
i = 0; i < count; i++) {
var
particle =
new
Circle(objs[i], pos[0], pos[1]);
var
angle = Math.random() * Math.PI * 2;
var
speed = Math.cos(Math.random() * Math.PI / 2) * 15;
particle.vel.x = Math.cos(angle) * speed;
particle.vel.y = Math.sin(angle) * speed;
particle.size = 10;
particle.gravity = 0.2;
particle.resistance = 0.92;
particle.shrink = Math.random() * 0.05 + 0.93;
circles.push(particle);
}
}
In Model Class
模型参数更新
this
.update =
function
(){
this
.vel.x *=
this
.resistance;
this
.vel.y *=
this
.resistance;
// gravity down
this
.vel.y +=
this
.gravity;
this
.pos.x +=
this
.vel.x;
this
.pos.y +=
this
.vel.y;
// shrink
this
.size *=
this
.shrink;
this
.move();
};
实体位置移动
this
.move =
function
(){
this
.object.attr(
'cx'
,
this
.pos.x)
.attr(
'cy'
,
this
.pos.y)
.attr(
'r'
,
this
.size)
;
}
我们抽象出一个物体模型,它的主要属性是pos(当前位置)、vel(方向参数)、resistance(阻力作用参数)、gravity(重力系数),主要方法是update() 和 move()。可在Codepen查看完整源码。
以上代码中, create() 是一个初始化所有爆炸物的方法,总数量count设置为80左右的随机数,objs是用d3.js添加的svg上的元素集合(在此我们使用圆形circle),模型类的每一个实例的‘object‘属性对应一个画布上的元素,在此根据分层思想把update()和move()分开,前者负责逻辑,后者负责效果。
在create里初始化了模型的一系列参数,其中重要的是移动方向,我们逐条来分析:
var angle = Math.random() * Math.PI * 2; 不难理解,就是角度取 0 ~ 360 度的随机一个方向。取值在0 ~ 6.28之间。
var speed = Math.cos(Math.random() * Math.PI / 2) * 15; 其中括号内的取值在 0 ~ π/2 之间,我们知道在此区间上cos函数的值为正,值域在0 ~ 1之间,故speed的取值在0 ~ 15之间。
particle.vel.x = Math.cos(angle) * speed; 区间0 ~ 2π上,cos函数的取值是-1 ~ 1之间,正负概率均等,参考图5。
particle.vel.y = Math.sin(angle) * speed; 区间0 ~ 2π上,sin函数的取值是-1 ~ 1之间,正负概率均等。
因此,方向偏移变量vel分布在二维坐标轴的四个象限,各爆炸物的初始坐标离爆炸点的横纵距离随机分布在0 ~ 15之间。
图5 - 三角函数曲线
在update()函数里,修改方向偏移变量,使力度逐渐衰减,并加入重力影响,然后修改物体的当前位置坐标,以及逐渐减小物体在视觉范围内的尺寸。
this.vel.x *= this.resistance; resistance 的赋值是0.92,故偏移量每次以92%的比例衰减。因此在效果图中我们看到,物体完全自由落体前移动速度有越来越慢的缓冲效果,类似于cubicOut缓冲。
this.vel.y *= this.resistance;
this.vel.y += this.gravity; gravity是重力系数,所以运动时需要每次沿y轴下方适当偏移。当vel变量的衰减殆尽时,只受重力作用影响,就呈直线下降状态。(此处物理专业的朋友禁止较真!)
this.pos.x += this.vel.x; 物体位置信息更新。
this.pos.y += this.vel.y;
this.size *= this.shrink; 物体尺寸大小衰减。
this.move(); 视图层移动。