react + canvas点线动画背景

效果图

在这里插入图片描述

实现步骤

1、public文件夹中的index.html引入

2、将变量存起来

// 引入
<script src='./Dot.js'></script>
// 变量存储
<script>
  	window.circle = circle;
</script>

3、组件中使用

constructor(props) {
    super(props);
    // 创建一个 ref 来存储 canvas 的 DOM 元素
    this.canvas = React.createRef();
}
componentDidMount(){
    new window.circle(100, this.canvas.current);
}
render() {
    return <canvas  ref={this.canvas} style={{position:'absolute',top:'0'}}></canvas>
}

Dot.js是一个类,用于实现canvas点线动画

以下代码非原创,小小修改了下

代码参考原文地址:https://blog.csdn.net/rudy_zhou/article/details/106051706?utm_medium=distribute.pc_relevant.none-task-blog-utm_term-4&spm=1001.2101.3001.4242

class circle {
    constructor(num, canvas) {
    // 由于react不直接操作dom,所以将canvas对象以形参形式传入
      this.canvas = canvas;
      this.canvas.width = document.documentElement.clientWidth;
      this.canvas.height = document.documentElement.clientHeight;
      this.ctx = this.canvas.getContext('2d');
   
      // 创建随机状态小球
      this.arr = Array.from(new Array(num)).map(item => ({
        x: Math.random() * this.canvas.width,
        y: Math.random() * this.canvas.height,
        speed: Math.random() * 1.5 + 0.5,
        xDir: Math.random() > 0.5 ? -1:1,
        yDir: Math.random() > 0.5 ? -1:1,
        r: 2
      }))
      // 小球连线距离
      this.dist = 300
   
      this.animation()
   
      window.onresize = ()=> {
        this.canvas.width = document.documentElement.clientWidth;
        this.canvas.height = document.documentElement.clientHeight;
      }
    }
    // 计算小球位置并判断方向与绘制
    drawCircle() {
      this.arr.forEach(item => {
        item.x += item.xDir * item.speed
        item.y += item.yDir * item.speed
   
        item.x <= 0 && (item.xDir = 1) 
        item.x > this.canvas.width - 1 && (item.xDir = -1, item.x = this.canvas.width - 1)
   
        item.y <= 0 && (item.yDir = 1) 
        item.y > this.canvas.height - 1 && (item.yDir = -1, item.y = this.canvas.height - 1)
        
        this.ctx.beginPath();
        this.ctx.arc(item.x, item.y, item.r, 0, 2 * Math.PI);
        // this.ctx.fillStyle = 'rgb(26,52,135)';
        this.ctx.fill();
      })
    }
   
    // 计算连线距离内的小球
    calcLine() {
      var arr = this.arr.concat()
      this.lineArr = []
      for(var i = 0,len = arr.length; i < len; i++){
        for(let y = i+1; y < len; y++){
          let val = Math.sqrt(Math.pow(arr[i].x - arr[y].x, 2) + Math.pow(arr[i].y - arr[y].y, 2) ,2);
          if(val < this.dist){
            this.lineArr.push({
              start: arr[i],
              end: arr[y],
              val: val,
              ratio: (val / this.dist)
            })
          }
        }
      }
   }
   
   // 绘制链接线条
    drawLine() {
      while(this.lineArr.length){
        this.ctx.beginPath()
        let item = this.lineArr.shift();
        let r = 255 * item.ratio;
        let g = 255 * item.ratio;
        let b = 255 * item.ratio;
   
        this.ctx.strokeStyle = `rgb(${r},${g},${b})`
        this.ctx.moveTo(item.start.x, item.start.y)
        this.ctx.lineTo(item.end.x, item.end.y); 
        // 线宽设置,必须放在绘制之前
        // this.ctx.lineWidth = 4;
        this.ctx.stroke();
      }
    }
   
    // 动画过渡
    animation() {
      this.canvas.width = this.canvas.width
      this.drawCircle()
      this.calcLine()
      this.drawLine()
      setTimeout(() => {
        this.animation()
      }, 30)
    }
   }
  
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值