js+css 实现星空效果实现效果 先来看一下实现的动画效果 需求分析 1、我们需要捕捉一块天空,设置成黑色的夜空(一定
【今日文章】:使用js+css 实现星空效果
实现效果
先来看一下实现的动画效果
需求分析
1、我们需要捕捉一块天空,设置成黑色的夜空(一定宽高的黑色背景而已)。 2、在黑色的夜空中随机分布着一定数量的星星(其实就是若干张图片,我们用定位就能实现)。 3、有大星星小星星(图片宽度随机,高度自适应就可以了)。 4、星星交替在夜空中一眨一眨闪耀星光(我们使用animation给图片设置一个透明度渐变,动画给一个延时就行)
实现步骤
1、新建一个块,设置成黑色背景;
相信大家应该都知道怎么设置了,就不叙述了
2、在黑色的夜空中随机分布着一定数量的星星
首先给父元素设置相对定位,父元素包含若干个图片,每张图片设置绝对定位,图片的x轴坐标和y轴坐标随机,这里x、y值单位使用百分比,那么x、y值得大小范围就是0到100,另外每个图片还有一个最小间距。 我们使用类实现:
class Star {
constructor(starQuantity,distancePercent = 6) {
this.starQuantity = starQuantity
this.distancePercent = distancePercent
}
initStar() {
const xyArr = Star.getPointList(this.distancePercent)
const starArr = Star.getStar(xyArr, this.starQuantity)
}
/**
* 获取坐标
* @params num: 坐标间距
*/
static getPointList(num) {
let x = num
let y = num
let maxX = 100 - num
let maxY = 100 - num
const arr = []
while (y < maxY) {
arr.push({
x,
y
})
x+= num
if (x > maxX) {
x = num
y+= num
}
}
// console.log('arr', arr)
return arr
}
**
* 随机获取一定数量的星星坐标
* @params arr: 所有坐标
* @params len: 坐标数组长度
*/
static getStar(arr, len) {
// 获取的最大长度不能超过坐标列表长度
if (arr.length < len) {
len = arr.length
}
const newArr = arr.slice(0)
const leng = newArr.length - 1
for(let i = 0; i< len; i++) {
const index = Math.floor(Math.random() * (leng - i))
const temp = newArr[leng - i]
newArr[leng - i] = newArr[index]
newArr[index] = temp
}
// console.log('arr===>', newArr.slice(-len))
return newArr.slice(-len)
}
}
3、给星星设置宽高
代码见第4步
4、星星交替在夜空中一眨一眨闪耀星光(我们使用animation给图片设置一个透明度渐变,动画给一个延时就行)
此步骤方法中添加了延时时间,星星动画通过css实现
// 我们需要新增方法
/**
* 设置星星大小和延迟时间
* @params starArr: 坐标
* @params widthArr: 宽度集合
* @params delay: 最大延迟时间
*/
getWidthAndDur(starArr, widthArr, delay = 2) {
return starArr.map(item => {
const index = Math.floor(Math.random() * widthArr.length)
return {
...item,
width: widthArr[index],
delay: parseFloat(Math.random() * delay)
}
})
}
// 需要修改方法
/**
* @params distancePercent: 间距百分比
* @params starQuantity: 要展示的星星数量
* @params size: 星星尺寸width
* @params delay: 星星最大延迟展示时间单位秒
*/
constructor(starQuantity, distancePercent = 6, widthArr = [8, 12, 20], delay = 2) {
this.starQuantity = starQuantity
this.distancePercent = distancePercent
this.widthArr = widthArr
this.delay = delay
}
initStar() {
const xyArr = Star.getPointList(this.distancePercent)
const starArr = Star.getStar(xyArr, this.starQuantity)
return this.getWidthAndDur(starArr, this.widthArr, this.delay)
}
完整vue文件
<template>
<div class="receive-blind">
<div class="receive-blind-star">
<img
class="star"
v-for="(item, index) in starArr"
:key="index"
src="./star.png"
:style="{
left: item.x + '%',
top: item.y + '%',
width: item.width + 'px',
'animation-delay': item.delay + 's'
}"
>
</div>
</div>
</template>
<script>
import Star from './star'
export default {
data() {
return {
starArr: new Star(80).initStar() // 星星数据
}
},
created() {
},
methods: {
},
}
</script>
<style lang="less" scoped>
.receive-blind {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
z-index: 1100;
background: rgba(0,0,0,1);
&-star {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
.star {
position: absolute;
opacity: 0.5;
animation: starMove 3s ease-in-out infinite;
}
}
.receive-block {
width: 100%;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
text-align: center;
}
}
@keyframes starMove{
0%{
opacity: 0.1;
}
50% {
opacity: 0.1;
}
75% {
opacity: 1;
}
100%{
opacity: 0.1;
}
}
</style>
star类
//
export default class Star {
/**
* @params distancePercent: 间距百分比
* @params starQuantity: 要展示的星星数量
* @params size: 星星尺寸width
* @params delay: 星星最大延迟展示时间单位秒
*/
constructor(starQuantity, distancePercent = 6, widthArr = [8, 12, 20], delay = 2) {
this.starQuantity = starQuantity
this.distancePercent = distancePercent
this.widthArr = widthArr
this.delay = delay
}
initStar() {
const xyArr = Star.getPointList(this.distancePercent)
const starArr = Star.getStar(xyArr, this.starQuantity)
return this.getWidthAndDur(starArr, this.widthArr, this.delay)
}
/**
* 获取坐标
* @params num: 坐标间距
*/
static getPointList(num) {
let x = num
let y = num
let maxX = 100 - num
let maxY = 100 - num
const arr = []
while (y < maxY) {
arr.push({
x,
y
})
x+= num
if (x > maxX) {
x = num
y+= num
}
}
// console.log('arr', arr)
return arr
}
/**
* 随机获取一定数量的星星坐标
* @params arr: 所有坐标
* @params len: 坐标数组长度
*/
static getStar(arr, len) {
// 获取的最大长度不能超过坐标列表长度
if (arr.length < len) {
len = arr.length
}
const newArr = arr.slice(0)
const leng = newArr.length - 1
for(let i = 0; i< len; i++) {
const index = Math.floor(Math.random() * (leng - i))
const temp = newArr[leng - i]
newArr[leng - i] = newArr[index]
newArr[index] = temp
}
// console.log('arr===>', newArr.slice(-len))
return newArr.slice(-len)
}
/**
* 设置星星大小和延迟时间
* @params starArr: 坐标
* @params widthArr: 宽度集合
* @params delay: 最大延迟时间
*/
getWidthAndDur(starArr, widthArr, delay = 2) {
return starArr.map(item => {
const index = Math.floor(Math.random() * widthArr.length)
return {
...item,
width: widthArr[index],
delay: parseFloat(Math.random() * delay)
}
})
}
}
星星图片
如果本文对你有帮助,就点个赞支持下吧,你的「赞」是我创作的动力。
转载自:https://juejin.cn/post/7413959991583588363