看一个跟斜率有关的效果
codepen 地址 https://codepen.io/xiaodun/pen/NOLyKP

这种代码很难去注释,因为不太好描述!
if(this.isStart){
if(Math.random() < 0.5){
if(Math.random() < 0.5){
this.offsetDistance = this.width * Math.random();
if(Math.random() < 0.5){
this.data.push({
x1:this.offsetDistance,
y1:-this.addDistance,
x2:this.enterX - (this.offsetDistance - this.enterX) * (this.height - this.enterY) / this.enterY,
// x2:this.enterX + (this.enterX - this.offsetDistance),
y2:this.height + this.addHeight,
o:1,
c:this.color
})
}
else{
this.data.push({
x1:this.offsetDistance,
y1:this.height + this.addDistance,
x2:this.enterX - (this.offsetDistance - this.enterX) * this.enterY / ( this.height - this.enterY),
// x2:this.enterX + (this.enterX - this.offsetDistance),
y2:-this.addDistance,
o:1,
c:this.color
})
}
}
else{
this.baseY = Math.random() * this.height | 0;
if(Math.random() < 0.5){
this.data.push({
x1:-this.addDistance,
y1:this.baseY,
x2:this.width + this.addDistance,
y2:this.enterY - (this.baseY - this.enterY) * (this.width - this.enterX) / this.enterX,
o:1,
c:this.color
})
}
else{
this.data.push({
x1:this.width + this.addDistance,
y1:this.baseY,
x2:-this.addDistance,
o:1,
y2:this.enterY - (this.baseY - this.enterY) * this.enterX / ( this.width - this.enterX ),
c:this.color
})
}
}
}
}
几处 Math.random() < 0.5 是为了随机产生起始点在四条边界外的线。
以第一组为例
this.offsetDistance = this.width * Math.random();
this.offsetDistance 随机x轴坐标,this.addDistance 常量,主要为了起始点和结束点都不在画布上。
终止点如何经过鼠标悬浮的位置(this.enterX,this.enterY),首先我想到的是斜率。
this.enterX - (this.offsetDistance - this.enterX) * (this.height - this.enterY) / this.enterY
只是有点像而已,首先y2的坐标只要在画布外就可以了,并且它和y1:-this.addDistance 形成了对应关系
上述公式只是单纯的对x2的一种操作
首先this.offsetDistance - this.enterX 是起始点x1与鼠标进入点的距离。
这段距离先被放大,在被缩小,是为了产生更"细腻“的值,并使值在一定范围内。
这里有一个变化,this.height - this.enterY 随着enterY的增大 ,this.height - this.enterY变小,也就是扩大的倍数小了,缩小的倍数大了,会让线更加的密集
因为(this.offsetDistance - this.enterX) 本身自带正负性 所以上面的公式便能确定x2的位置

注意上述公式并没有随便的加减乘除,而是和主要变量息息相关。
我在效验逻辑时,发现this.baseY 没有被使用,而是用的上面this.offsetDistance...
直线思维是精确的结果,而曲线思维是范围,后续的例子,会看到很多复杂的式子都是在求一个范围。
绘画时的逻辑
for(let i=0;i<this.data.length;i++){
let item = this.data[i];
this.pen.beginPath();
this.pen.moveTo(item.x1,item.y1);
this.pen.lineTo(item.x2,item.y2);
this.pen.closePath();
this.pen.globalAlpha = item.o;
this.pen.strokeStyle = item.c;
this.pen.lineWidth = 2;
this.pen.stroke();
item.o -= this.perChangeOpacity;
if(item.o <= 0){
this.data.splice(i,1);
i--;
}
}
每次减去指定的透明度,当透明度小于0时,移除改项
判定逻辑
if(this.isStart || this.data.length > 0){
requestAnimationFrame(()=>{
this.start();
})
}
即使鼠标移开,若数组长度不为0,仍继续,使得动画缓慢的结束。
网友评论