js 实现代码雨功能

首先来看一下效果:

 

这里是使用了canvas来绘制出来的,但是canvas是静态的,如何实现动态的下雨效果呢?没错,定时器,都是基本的东西,但是组合起来效果还是很好的。

下面开始方法:

第一步是需要获取展示代码雨的dom宽高

这里是用的全屏,所以宽高就直接是windom的innerWidth和innerHeight


 const cvs = document.getElementById("app")
  const state = {
     str: "01",
     width: null,//窗口宽度
     height: null,//窗口高度
     ctx: null,//canvas上下文
     columnWidth: 20,//一列文字宽度
     columnCount: 0,//计算总共可以放下多少列文字
     columnNextIndexs: [],//记录每一列文字当前的文字应该是哪个
     timer: null//定时器
  }
//获取窗口宽高
state.width = window.innerWidth;
state.height = window.innerHeight;
//然后赋值给canvas
({ innerWidth: cvs.width, innerHeight: cvs.height } = window);

第二步计算列数

//计算一共可以多少列
state.columnWidth = 25;
state.columnCount = Math.floor(window.innerWidth / state.columnWidth);

  //初始化所有列文字的位置为1
  state.columnNextIndexs = new Array(state.columnCount).fill(1);
  
  /* 也可以初始化给点随机值 可以在第一次的时候有高度差异 */
  // state.columnNextIndexs.forEach((_, i) => state.columnNextIndexs[i] = Math.floor(Math.random() * state.columnCount));

 第三步获取随机文字与随机颜色

/* 获取随机颜色 */
function getRandomColor() {
   var r = Math.floor(Math.random() * 256);
   var g = Math.floor(Math.random() * 256);
   var b = Math.floor(Math.random() * 256);
   return "rgb(" + r + "," + g + "," + b + ")";
}

/* 获取随机文字 */
function getRandomChar() {
   return state.str[Math.floor(Math.random() * state.str.length)]
}

接着就是绘制了,如何实现字符渐变的效果,就是通过绘制的时候添加一层有透明度的遮罩,每次绘制都加一层,这样原本绘制的跟新绘制的字符就是产生颜色差

function draw() {
   const { ctx, width, height, columnWidth, columnCount, columnNextIndexs } = state
   ctx.fillStyle = `rgba(0, 0, 0, 0.1)`;//遮罩
   ctx.fillRect(0, 0, width, height)
   const fontsize = 16;
   ctx.fillStyle = getRandomColor();
   ctx.font = `${fontsize}px "Microsoft YaHei"`;
   for (let i = 0; i < columnCount; i++) {
       const x = i * columnWidth;
       const y = 20 * columnNextIndexs[i];
       ctx.fillText(getRandomChar(i), x, y);
   //当绘制的文字高度超过dom的高度时,重置位置为0,从头开始 或者随机数大于0.99时从头开始绘制,这样可以使每一列产生位差
if (y > height && Math.random() > .99) { columnNextIndexs[i] = 0 } else { //记录每列写到的文字,累计++ columnNextIndexs[i]++ } } }

 /* 开始执行绘画 */
  function startDraw() {
     initCalcSize()
     state.timer = setInterval(() => {
        draw()
     }, 40);
  }

  /* 重新开始绘画 */
  function againDraw() {
     clearInterval(state.timer)
     startDraw()
  }

  /* 窗口尺寸改变 重新开始绘制 */
  window.onresize = () => againDraw()
 

到此,代码雨的效果就可以展示了

 

posted @ 2022-09-23 13:56  wenwen。  阅读(312)  评论(0编辑  收藏  举报