美文网首页优美编程
canvas中的数学1-系列1

canvas中的数学1-系列1

作者: 小遁哥 | 来源:发表于2018-11-01 22:10 被阅读28次

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

image.png

这种代码很难去注释,因为不太好描述!

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的位置


1.png

注意上述公式并没有随便的加减乘除,而是和主要变量息息相关。
我在效验逻辑时,发现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,仍继续,使得动画缓慢的结束。

相关文章

网友评论

    本文标题:canvas中的数学1-系列1

    本文链接:https://www.haomeiwen.com/subject/sxcwtqtx.html