我用Vue2实现了QQ空间的漂浮千纸鹤效果

lxf2023-05-05 03:48:01
我用Vue2实现了QQ空间的漂浮千纸鹤效果

我正在参加「码上AdminJS挑战赛」详情请看:码上AdminJS挑战赛来了!

大家好,我是小七月,今天我为大家带来了漂浮的千纸鹤效果。作为一个自工作后就很少使用QQ的人,今天突然打开了QQ空间,看到了自己曾经设置过的空间背景图效果,心血来潮,也打算自己实现一个。下面将为大家讲解该效果的实现思路。

代码片段如下:

首先,我们需要一个小小的千纸鹤,于是,我便去网上找了一个纸鹤的图(ps:纸鹤的背景是白色的,但是我找了好久都没有看到透明的图片,所以就将就以下,重点是实现思路哈),图片的地址为:纸鹤的地址

首先想的是,一个屏幕上有多个纸鹤的地址,所以我使用了一个数组来存放在屏幕中显示的纸鹤。至于纸鹤是一直在运动的,所以我决定使用绝对定位,不断地更改纸鹤的lefttop属性,所以纸鹤列表里面应该存放的信息有:x (left值,随机),y (top值),vx (纸鹤向左或向右移动的速度),vy(纸鹤向下移动的速度),g (负值,慢慢减小纸鹤向下移动的速度)。

然后纸鹤应该是从最上面慢慢往下飘的,而且应该在容器的中间一块区域内产生,那样纸鹤会比较好看。由于我设置的容器为width:500,height:500,所以我决定在200-300间不断地产生新的纸鹤,然后纸鹤生成了之后,它在水平方向上应该是左右,所以vx为正负的机率应该是相等的。纸鹤只能向下移动,所以vy一定是正数。下面是我实现的代码:

initCranePosition() {
  return {
    x: (Math.random() * 100 + 200).toFixed(2),
    y: 0
  };
},
genSpeed() {
  return {
    vx: (Math.random() * 2 - 1).toFixed(2),
    vy: (Math.random() * 5).toFixed(2) + 5,
    g: -Math.random().toFixed(2)
  };
 }

纸鹤在容器中的数量也不应该太多,否则会比较混乱,所以我限制了纸鹤的数量,判断当纸鹤列表小于7个的时候就会新增一个纸鹤,并且改变原来屏幕上纸鹤的位置。注意:一定不要忘了清空掉那些离开了容器的纸鹤,否则纸鹤将不会生成,实现的代码如下:

genCrane() {
  if (this.craneList.length) {
    let list = [...this.craneList].filter((item) => item.x > 0 && item.x < 500 && item.y < 500);
    this.craneList = list.map((item) => {
      item.x = Number(item.x) + Number(item.vx);
      item.y = Number(item.y) + Number(item.vy);
      if (item.vy > 2) item.vy = Number(item.vy) + Number(item.g);
      return item;
    });
  }
  if (this.craneList.length < this.maxLenth) {
    const position = this.initCranePosition();
    const speed = this.genSpeed();
    this.craneList.push({
      ...speed,
      ...position
    });
  }
  this.timer = window.requestAnimationFrame(this.genCrane);
}

最后,推荐一个执行动画的方法window.requestAnimationFrame()  告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。回调函数执行次数通常是每秒 60 次,但在大多数遵循 W3C 建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。(该解释来自于mdn)。该方法是用来替代setInterval,因为该方法可能会延时,所以对于动画来说不太建议使用。

总结:该实现只是一个简单的实现,其实还有很大的优化空间,比如防止纸鹤重叠,比如容器的宽高不应该写死等等,欢迎小伙伴们自行优化。谢谢大家!