Vue + Less 实现动态星空效果

583 阅读2分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战

20200422080819348.gif

因为要使用 Less 作为预处理器,在此之前,要先安装 less less-loader。

Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言。因为 Less 和 CSS 非常像,因此很容易学习。

在 webpack.base.conf.js

{
  test: /\.less$/,
  use: [{
    loader: "style-loader"
  }, {
    loader: "css-loader"
  }, {
    loader: "less-loader", options: {
      strictMath: true,
      noIeCompat: true
    }
  }]
},

添加背景色

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>动态星空</title>
    <style>
      body {
        background: radial-gradient(200% 100% at bottom center, #f7f7b6, #e96f92, #1b2947);
        background: radial-gradient(220% 105% at top center, #1b2947 10%, #75517d 40%, #e96f92 65%, #f7f7b6);
        background-attachment: fixed;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div id="app">
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>

正式开始编写页面。

starsCount:星星✨的数量

distance:距离

Vue 框架推崇数据驱动视图开发。但偶尔还是需要用到操作元素实例。

Vue 提供了 ref 供开发者获取元素实例。

<template>
  <div class="stars">
    <div class="star" v-for="(item, index) in starsCount" :key="index" ref="star"></div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      starsCount: 800,
      distance: 800
    }
  },
  mounted () {
    // 通过 $ref 获取实例
    let starArr = this.$refs.star
    starArr.forEach(item => {
      let speed = 0.2 + (Math.random() * 1)
      let thisDistance = this.distance + (Math.random() * 300)
      item.style.transformOrigin = `0 0 ${thisDistance}px`
      item.style.transform = `translate3d(0, 0, -${thisDistance}px) rotateY(${(Math.random() * 360)}deg) rotateX(${(Math.random() * -50)}deg) scale(${speed}, ${speed})`
    })
  }
}
</script>

<style scoped lang="less">
@keyframes rotate {
  0% {
    transform: perspective(400px) rotateZ(20deg) rotateX(-40deg) rotateY(0);
  }
  100% {
    transform: perspective(400px) rotateZ(20deg) rotateX(-40deg) rotateY(-360deg);
  }
}
.stars {
  transform: perspective(500px);
  transform-style: preserve-3d;
  position: absolute;
  perspective-origin: 50% 100%;
  left: 50%;
  animation: rotate 90s infinite linear;
  bottom: 0;
}
.star {
  width: 2px;
  height: 2px;
  background: #f7f7b8;
  position: absolute;
  top: 0;
  left: 0;
  backface-visibility: hidden;
}
</style>

小知识点拆分:

radial-gradient() 径向渐变创建 "图像"。径向渐变由中心点定义。为了创建径向渐变你必须设置两个终止色。(以中心为起点)。

background: radial-gradient(#e66465, #9198e5);

image.png

background-attachment 设置背景图像是否固定或者随着页面的其余部分滚动。

background-attachment: scroll | fixed | local | (local, scroll) | (scroll, local);

在线查阅网站:developer.mozilla.org/zh-CN/docs/…

transform: 允许你旋转,缩放,倾斜或平移给定元素。这个属性就比较常见了。一般的开发中都会用到。比较常用的值 scale,translate,rotate 等等。

perspective 属性指定了观察者与z=0平面的距离,使具有三维位置变换的元素产生透视效果。z>0的三维元素比正常大,而z<0时,比正常小,大小程度由该属性的值决定。当为元素定义perspective属性时,其子元素会获得透视效果,而不是元素本身。

perspective-origin: 50% 100%; 定义 3D 元素所基于的 X 轴和 Y 轴。该属性允许您改变 3D 元素的底部位置。当为元素定义 perspective-origin 属性时,其子元素会获得透视效果,而不是元素本身。注释:该属性必须与 perspective 属性一同使用,而且只影响 3D 转换元素。

backface-visibility: 属性定义当元素不面向屏幕时是否可见。如果在旋转元素不希望看到其背面时,该属性很有用。

scale(x,y): 定义 2D 缩放转换。