canvas实现星空动画

发布时间 2023-10-10 23:19:11作者: Mizuki-Vone

效果

  • 大概就是星星的运动轨迹是一个椭圆形的面,逆时针旋转,会随机眨眼睛,随机速度,随机运动半径(但是运动轨迹导致椭圆中心的点最密集),不会录制gif,暂不放图

实现

  • 每颗星星都有自己的属性,所以需要封装
export class Star {
  radius: any
  w: any
  h: any
  timePassed: any
  speed: any
  dis: any
  blinkCount: any

  constructor(w: any, h: any, count: any){
    // 星星大小
    this.radius = Math.random() * 1.5 + 0.1 ;
    this.w = w;
    this.h = h;
    // 星星移动速度
    this.timePassed = Math.random() * count;
    this.speed = Math.random() / 800;
    this.dis = Math.random()
    this.blinkCount = Math.floor(Math.random() * 500)
  }

  draw(ctx: any) {
    ctx.beginPath()
    const x = Math.sin(this.timePassed) * this.w * this.dis + this.w / 2;
    const y = Math.cos(this.timePassed) * this.h * this.dis + this.h / 2;
    // const opacity = Math.random() < 0.1 ? 
    const opacity = this.blinkCount > 20 ? this.dis : Math.abs(this.blinkCount - 10) / 20
    ctx.fillStyle = `rgba(255,255,255,${opacity})`
    ctx.arc(x, y, this.radius, 0, Math.PI * 2);
    ctx.fill();
    ctx.closePath();
    this.blinkCount = (this.blinkCount + 1) % 500
    this.timePassed += this.speed;
  }
}
  • 然后生成多个星星,并开启动画
initStarSky() {
  const dom = document.getElementById('canvas') as HTMLCanvasElement
  dom.width = window.innerWidth
  dom.height = window.innerHeight
  this.canvas = dom.getContext('2d')
  const w = dom.width
  const h = dom.height
  for(let i = 0; i < this.starCount; i++) {
    const star = new Star(w, h, this.starCount)
    this.stars.push(star)
  }
  this.starSkyTimer = setInterval(() => {
    this.canvas.clearRect(0, 0, w, h)
    this.stars.forEach(item => {
      item.draw(this.canvas)
    })
  }, 50)
}