在TypeScript + Vue项目中实现一个酷炫的Canvas运动背景,实现代码如下:

<template>
  <div id="main">
    <div id="bg-main">
      <canvas id="bg"></canvas>
    </div>
  </div>
</template>
​
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
​
let tick = 0,
    options = {      len: 20,
      count: 50,
      baseTime: 10,
      addedTime: 10,
      dieChance: .01,
      spawnChance: .5,
      sparkChance: .1,
      sparkDist: 10,
      sparkSize: 2,
      color: `hsl(tone, 100%, light%)`,
      baseLight: 50,
      addedLight: 10,
      shadowToTimePropMult: 6,
      baseLightInputMultiplier: .01,
      addedLightInputMultiplier: .02,
      ox: 0,
      oy: 0,
      repaintAlpha: .04,
      toneChange: .1
    },
    lines = new Array(),
    dieX: number = 0,
    dieY: number = 0,
    clientHeight: number = 0,
    clientWidth: number = 0,
    baseRadius = Math.PI * 2 / 6
​
@Component
export default class Main extends Vue {  name = "ContentMain"
​
  mounted(){    const bg = document.getElementById('bg') as HTMLCanvasElement,
          bgMain = document.getElementById('bg-main') as HTMLDivElement
    let ctx = bg.getContext('2d') as CanvasRenderingContext2D
    clientWidth = bg.width = bgMain.clientWidth
    clientHeight = bg.height = bgMain.clientHeight
    options.ox = clientWidth / 2
    options.oy = clientHeight / 2
    dieX = clientWidth / 2 / options.len
    dieY = clientHeight / 2 / options.len
    ctx.fillStyle = 'black'
    ctx.fillRect(0, 0, clientWidth, clientHeight)
​
    function loop(){      // setTimeout(()=>requestAnimationFrame(loop),  50)
      requestAnimationFrame(loop)
      ++tick;
      ctx.globalCompositeOperation = "source-over"
      ctx.shadowBlur = 0
      ctx.fillStyle = "rgba(0, 0, 0, alp)".replace('alp', options.repaintAlpha.toString())
      ctx.fillRect(0, 0, clientWidth, clientHeight)
      ctx.globalCompositeOperation = "lighter"
      if(lines.length < options.count && Math.random()<options.spawnChance)
        lines.push(new Line(ctx))
      lines.map(line=>line.step())
    }
​
    window.addEventListener('resize', (e:Event)=>{      clientWidth = bg.width = bgMain.clientWidth
      clientHeight = bg.height = bgMain.clientHeight
      ctx.fillStyle = 'black'
      ctx.fillRect(0, 0, clientWidth, clientHeight)
      options.ox = clientWidth / 2
      options.oy = clientHeight / 2
      dieX = clientWidth / 2 / options.len
      dieY = clientHeight / 2 / options.len
    })
​
    loop()
  }
}
​
interface Option {  readonly len: number;
  readonly count: number;
  readonly baseTime: number;
  readonly addedTime: number;
  readonly dieChance: number;
  readonly spawnChance: number;
  readonly sparkChance: number;
  readonly sparkDist: number;
  readonly sparkSize: number;
  readonly color: string;
  readonly baseLight: number;
  readonly addedLight: number;
  readonly shadowToTimePropMult: number;
  readonly baseLightInputMultiplier: number;
  readonly addedLightInputMultiplier: number;
  ox: number;
  oy: number;
  readonly repaintAlpha: number;
  readonly toneChange: number;
}
class Line {  private x = 0;
  private y = 0;
  private addedX = 0;
  private addedY = 0;
  private radius = 0;
  private lightInputMultiplier = 0;
  private color = "";
  private cumulativeTime = 0;
  private time = 0;
  private targetTime = 0;
  private ctx: CanvasRenderingContext2D
​
  constructor(ctx: CanvasRenderingContext2D) {    this.ctx = ctx
    this.reset()
  }
​
  reset(): void {    this.x = 0;
    this.y = 0;
    this.addedX = 0;
    this.addedY = 0;
    this.radius = 0;
    this.lightInputMultiplier =
      options.baseLightInputMultiplier +
      options.addedLightInputMultiplier * Math.random();
    this.color = options.color.replace(
      "tone",
      (options.toneChange * tick).toString()
    );
    this.cumulativeTime = 0;
    this.beginPhase();
  }
​
  beginPhase(): void {    this.x += this.addedX;
    this.y += this.addedY;
    this.time = 0;
    this.targetTime =  (options.baseTime + options.addedTime * Math.random()) | 0;
    this.radius += baseRadius * (Math.random() < 0.5 ? 1 : -1);
    this.addedX = Math.cos(this.radius);
    this.addedY = Math.sin(this.radius);
​
    if ( Math.random() < options.dieChance ||
        this.x > dieX || this.x < -dieX ||
        dieY > dieY || this.y < -dieY )
      this.reset()
  }
​
  step() {    ++this.time
    ++this.cumulativeTime
    if (this.time >= this.targetTime) this.beginPhase();
    let prop = this.time / this.targetTime,
        wave = Math.sin(prop * Math.PI / 2),
        x = this.addedX * wave,
        y = this.addedY * wave;
    this.ctx.shadowBlur = prop * options.shadowToTimePropMult;
    this.ctx.fillStyle = this.ctx.shadowColor = this.color.replace(
      "light",
      (options.baseLight +
        options.addedLight *
          Math.sin(this.cumulativeTime * this.lightInputMultiplier)).toString()
    );
    this.ctx.fillRect(
    options.ox + (this.x + x) * options.len,
    options.oy + (this.y + y) * options.len,
    2, 2);
    if (Math.random() < options.sparkChance)
      this.ctx.fillRect(
        options.ox +
          (this.x + x) * options.len +
          Math.random() * options.sparkDist * (Math.random() < 0.5 ? 1 : -1) - options.sparkSize / 2,
        options.oy +
          (this.y + y) * options.len +
          Math.random() * options.sparkDist * (Math.random() < 0.5 ? 1 : -1) - options.sparkSize / 2,
        options.sparkSize,
        options.sparkSize
      );
  }
}
</script>
​
<style lang="scss">
#main {  position: relative;
  top: 5vh;
  left: 0;
  margin: 0;
  width: 100%;
  height: 80%;
  margin-top: 0;
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
​
  #bg-main {    margin: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    z-index: 0;
  }
}
</style>
代码仅供参考学习

TypeScript + Vue 实现某个canvas科幻背景 -- 1相关推荐

  1. vue3 canvas 星空背景图

    vue3 canvas 星空背景图 页面截图 代码 页面截图 代码 <template><div ref="container" class="cont ...

  2. vue 中利用canvas 给pdf文件加水印---详细教程(附上完整代码)

    需求:在h5网页中打开pdf文件,要求给文件添加水印 实现技术及插件:vue,vue-pdf,canvas 插件安装: npm i vue-pdf --save npm i pdf-lib --sav ...

  3. python中mainloop添加背景_Python实例讲解 - tkinter canvas (设置背景图片及文字)

    Python实例讲解 -- tkinter canvas (设置背景图片及文字) 先来一个绘图: from Tkinter import * master = Tk() w = Canvas(mast ...

  4. vue+webpack项目打包后背景图片加载不出来问题解决

    vue+webpack项目打包后背景图片加载不出来问题解决 参考文章: (1)vue+webpack项目打包后背景图片加载不出来问题解决 (2)https://www.cnblogs.com/mica ...

  5. canvas线条背景(抽象画布可视化,利用canvas绘制多条线条,再利用多条线条同时动态发生改变,形成一幅美妙的动态图,非常惊艳!)

    canvas线条背景(抽象画布可视化,利用canvas绘制多条线条,再利用多条线条同时动态发生改变,形成一幅美妙的动态图,非常惊艳!) 动态变化中的静态截图 <!doctype html> ...

  6. python设置背景图片大全_Python实例讲解 - tkinter canvas (设置背景图片及文字)

    Python实例讲解 -- tkinter canvas (设置背景图片及文字) 先来一个绘图: from Tkinter import * master = Tk() w = Canvas(mast ...

  7. python中mainloop添加背景_Python实例讲解 tkinter canvas (设置背景图片及文字)

    Python实例讲解 tkinter canvas (设置背景图片及文字) 2018-09-14 Python实例讲解 -- tkinter canvas (设置背景图片及文字) 博客分类:Pytho ...

  8. Vue单文件中引入背景图片时,四周有空白的问题

    Vue单文件中引入背景图片时,四周有空白的问题 问题背景 初始引入背景图 更新后的背景图设置 问题背景 近期公司有个管理系统前后端分离,但是前端人员不够,只能我们后端来凑,而在前端的开发过程中总是遇到 ...

  9. Canvas科幻网状波浪动画效果

    下载地址Canvas科幻网状波浪动画效果是一款正弦波弧度波浪动画,像素块波浪特效. dd:

最新文章

  1. Android Activity和Intent机制学习笔记
  2. yolov5损失函数笔记
  3. SD-WAN如何安装在企业WAN中?—Vecloud
  4. windows 下安装 scrapy报错:error: Unable to find vcvarsall.bat
  5. Linux下socket最大连接数 ulimit -n 最大值修改
  6. linux中显示目录名,在linux下显示中文目录和文件名
  7. ACM算法--spfa算法--最短路算法
  8. 实时监控后台数据 vue_实时数据监控,快速掌握B站爆款视频热度走向
  9. 当网页数据到达用户计算机,当网页数据到达用户计算机时,数据进行转换步骤是()...
  10. Python 爬虫 (三) - Socket 网络编程
  11. 蚁群算法最短路径规划多出口情况及问题答疑
  12. Android ListView 指定显示最后一行
  13. NB-Iot烟感02:NB-IOT概念和技术特点
  14. 群晖 kodi mysql,用群晖为 Kodi 注入多设备同步能力
  15. ASP.NET程序读取二代身份证(附源码)
  16. “对不起,我是用AI做的警察”
  17. 如视VR显示连不上服务器,HTC Vive播放本地视频图文教程(附常见问题解决办法)...
  18. 一个目前很火的文字转语音方法,小工具为你的视频配音
  19. ARM微控制器与嵌入式系统 基础知识
  20. 2023年软考高级系统分析师考试时间及安排

热门文章

  1. 纽曼u盘无法打开的解决方法 量产工具
  2. Apache Sqoop Job :案例练习
  3. CentOS安装FastDHT
  4. Python实现自动挂机脚本(GUI 打包)
  5. C#实现爬取淘宝商品
  6. 如何在Windows中设置默认的Web浏览器
  7. 一文读懂网关中间件-Nginx
  8. 【博学谷学习记录】超强总结,用心分享|前端开发基础知识总结(js一)
  9. android放微信功能吗,微信8.0上线,安卓也能用!5大功能新媒体人要注意!
  10. 微信公众号开发Django 图片处理