马黑黑 发表于 2022-1-21 19:42

繁星似锦实现原理解析

本帖最后由 马黑黑 于 2022-1-21 19:51 编辑

首先要有天空,我们先定义一下天空的样式,它是黑的,但不能黑的太彻底以免过于压抑,所以给它个略微透明的背景:

#sky {
      margin: 10px auto;
      width: 720px;
      height: 460px;
      background-color: rgba(0,0,0,0.85);
      position: relative; /*定位总是需要的 */
}


我们用 <span> 标签来布置星星。span是行内标签,display 最好定义,block 和 inline-block 都可以:

#sky span {
      position: absolute;
      display: inline-block;
      width: 3px;
      height: 3px;
      background: white;
      opacity: 0.6; /* 透明度是让它们模糊 */
      transform: rotate(45deg); /* 转一下像个菱形模拟星星 */
      animation: splash var(--d) infinite;
/*    上一句调用动画,其中:
      var(--d) 是CSS声明的变量:运动时长
*/
}


下面是动画,其实可以设置为更复杂一点:

@keyframes splash {
      0%, 100% { opacity: 0.2; }
      50% { opacity: 0.8; transform:scale(1.5) rotate(-45deg); }
}


月亮要有一个吧,让它是月牙的:

.moon {
      position: absolute; /* 定位 */
      width: 100px;
      height: 100px;
      border-radius: 50%;
      box-shadow: 20px 20px 0 0 silver; /* 银色的月牙 */
      z-index: 100; /* 星星只能在它背后 */
      left: 70%;
}


以上,CSS样式写好了。我们要画几百甚至几千个星星,用CSS画要画到猴年马月!但我们要先懂得如果用CSS画,怎么画:

#sky span:nth-child(1){ left:25%; top:10%; --d: 3s; }
#sky span:nth-child(2){ left:30%; top:15%; --d: 2s; }
#sky span:nth-child(3){ left:40%; top:17%; --d: 5s; }

…………
#sky span:nth-child(600){ left:40%; top:17%; --k: 1s; }

这上面,定义每一个 span 标签基于定位和动画变量的样式,谁给我写600个看看!

JS好哥们这时候说:我来!

JS哥哥是这样写标签的:

str = '<span style="left:25%; top:10%; --d: 3s;"></span>';
document.getElementById('sky').innerHTML += str;

我看看。嗯,JS哥定义了一个 str 变量,用来装载 span 标签,然后通过读取 id 为 sky 的标签重新给它赋值,就是说 sky 标签里面的HTML代码重新写, += 的意思是在原本基础上加 str 变量的值。

可以,咦,囧哥,哦不,JS哥,你这不是只画了一个吗?我要600个星星!

JS个说:别急,看我的——

for (i=0; i<600; i++) {
    str += '<span style="left:25%; top:10%; --d: 3s;"></span>';
}

document.getElementById('sky').innerHTML += str;

哦~~~,JS哥用一个 for 语句画了600个 span 标签。太厉害了,JS哥哥!

可是,咦,JS哥,你画的 span 标签是叠加在一起的耶,我要他随机分布在天空中!

JS个这才想起来要随机给星星定位、定闪烁时长,于是它忍住不笑,继续努力:

var str = "";
for (i=0; i<600; i++) {
      str += '<span style="left: ' + Math.ceil(Math.random()*100) + '%; top: ' + Math.ceil(Math.random()*100) + '%; --d:' + Math.ceil(Math.random()*10+0.5) + 's;"></span>';
}
document.getElementById('sky').innerHTML += str;


这回,JS哥哥用了数学方法,给星星 xy坐标、运动时长分派随机数值,其中,高宽在0%-100%之间随机分配,运动时长在0.5-10.5秒之间随机分配。

下面是HTML代码,它应该放在 CSS 和 JS 之间:

<div id="sky">
      <div class="moon"></div>
</div>


就酱。演示效果(多加了音乐):【新提醒】繁星似锦 - 动画音画 - 花潮论坛 - Powered by Discuz! (huachaowang.com)


马黑黑 发表于 2022-1-21 20:16

原帖完整代码:
<style>
#sky {
        margin: 10px auto;
        width: 720px;
        height: 460px;
        background-color: rgba(0,0,0,0.85);
        position: relative;
}
#sky:hover .wyyfram { display:block; }
.moon {
        position: absolute;
        width: 100px;
        height: 100px;
        border-radius: 50%;
        box-shadow: 20px 20px 0 0 silver;
        z-index: 100;
        left: 70%;
}
.wyyfram { position: relative; top: 400px; display: none; opacity: 0.5; }
#sky span {
        position: absolute;
        display: inline-block;
        width: 3px;
        height: 3px;
        background: white;
        opacity: 0.6;
        transform: rotate(45deg);
        animation: splash var(--d) infinite;
}

@keyframes splash {
        0%, 100% { opacity: 0.2; }
        50% { opacity: 0.8; transform:scale(1.5) rotate(-45deg); }
}

</style>

<div id="sky">
        <div class="moon"></div>
        <iframe class="wyyfram" frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=86 src="https://music.163.com/outchain/player?type=2&id=410042763&auto=1&height=66"></iframe>
</div>

<script>

var str = "";
for (i=0; i<600; i++) {
        str += '<span style="left: ' + Math.ceil(Math.random()*100) + '%; top: ' + Math.ceil(Math.random()*100) + '%; --d:' + Math.ceil(Math.random()*10+0.5) + 's;"></span>';
}
document.getElementById('sky').innerHTML += str;
</script>

小辣椒 发表于 2022-1-21 21:11

黑黑很强大,直接语句制作特效{:4_178:}

红影 发表于 2022-1-21 21:16

这个比较复杂,好多没接触过的,需要好好看看了。

马黑黑 发表于 2022-1-21 21:21

小辣椒 发表于 2022-1-21 21:11
黑黑很强大,直接语句制作特效

这个是很基本的

马黑黑 发表于 2022-1-21 21:22

红影 发表于 2022-1-21 21:16
这个比较复杂,好多没接触过的,需要好好看看了。

CSS部分不复杂,先弄懂这个部分。

JS也就是用了一个 for 语句,常规语言必要的,然后就是它来写 HTML 代码带 style 语句,也算简单,关键是CSS的原理。

红影 发表于 2022-1-21 22:10

马黑黑 发表于 2022-1-21 21:22
CSS部分不复杂,先弄懂这个部分。

JS也就是用了一个 for 语句,常规语言必要的,然后就是它来写 HTML...

那就先说css,月亮就没看懂,看着像做个圆呀,咋加个阴影就成月牙了呢{:4_173:}

马黑黑 发表于 2022-1-21 23:35

红影 发表于 2022-1-21 22:10
那就先说css,月亮就没看懂,看着像做个圆呀,咋加个阴影就成月牙了呢

月亮大概就是这组代码产生的效果:

.moon {
        position: absolute;
        width: 100px;
        height: 100px;
        border-radius: 50%;
        box-shadow: 20px 20px 0 0 silver;
        z-index: 100;
        left: 70%;
}


定位、高宽、圆角都看懂,关键是红色那句,利用元素的盒子阴影巧妙设置,就是它和边框圆形设置以及继承来的背景色共同产生了月牙效果(下楼给出一个独立的效果,一看就能明白)。倒数第二句是为了保证星星不浮于它之上,数字越大它就越不容易被其他元素覆盖(除非有另外的元素设置了比它更大的值并与他有重叠部分)。

马黑黑 发表于 2022-1-21 23:36

<style>
.月牙 {
        position: absolute;
        width: 100px;
        height: 100px;
        border-radius: 50%;
        box-shadow: 20px 20px 0 0 silver;
        z-index: 100;
        left: 50%;
background:red;
}
</style>
<div class="月牙"></div>

马黑黑 发表于 2022-1-21 23:38

看9楼,如果红色部分设置为透明或和父容器的背景色一样的颜色,我们就只能看到阴影的部分,那一部分就是月牙。是不是很巧妙?

@红影

马黑黑 发表于 2022-1-21 23:39

<div class="月牙" style="background: transparent;"></div>

马黑黑 发表于 2022-1-21 23:40

11楼,代码如下:

<div class="月牙" style="background: transparent;"></div>

这里,已将 div 的背景色设置为透明

红影 发表于 2022-1-22 15:08

马黑黑 发表于 2022-1-21 23:35
月亮大概就是这组代码产生的效果:

.moon {


位置那句看懂了,没懂的事月牙效果。看楼下明白了,原来是巧用颜色弄成的,前面没明白画圆的命令怎么弄出来的月牙,现在懂了。若不是背景色将圆的那部分变成“不见”,将是楼下那种效果。
这法子真巧妙{:4_199:}

红影 发表于 2022-1-22 15:10

马黑黑 发表于 2022-1-21 23:40
11楼,代码如下:




哈,这个是另一个思路了,原来有这么多方法可以做出月牙来{:4_187:}

红影 发表于 2022-1-22 15:11

马黑黑 发表于 2022-1-21 23:38
看9楼,如果红色部分设置为透明或和父容器的背景色一样的颜色,我们就只能看到阴影的部分,那一部分就是月 ...

嗯嗯,设置透明或者设置成跟父容器一样颜色,都会出现月牙。{:5_116:}

马黑黑 发表于 2022-1-22 15:13

红影 发表于 2022-1-22 15:11
嗯嗯,设置透明或者设置成跟父容器一样颜色,都会出现月牙。

先领会,后动手,然后自己改变月牙的大小,甚至上弦月和下弦月都能做

马黑黑 发表于 2022-1-22 15:15

红影 发表于 2022-1-22 15:10
哈,这个是另一个思路了,原来有这么多方法可以做出月牙来

想象力加充分利用自己掌握的知识和能力,能做很多事情

马黑黑 发表于 2022-1-22 15:16

红影 发表于 2022-1-22 15:08
位置那句看懂了,没懂的事月牙效果。看楼下明白了,原来是巧用颜色弄成的,前面没明白画圆的命令怎么弄出 ...

弄懂了你也能做,然后举一反三,做更多的事情

红影 发表于 2022-1-22 19:39

马黑黑 发表于 2022-1-22 15:16
弄懂了你也能做,然后举一反三,做更多的事情

我不行,常规的都做不出来,这么巧妙的更做不出新的了,跟着做原样的还磕磕绊绊呢{:4_173:}

红影 发表于 2022-1-22 20:10

马黑黑 发表于 2022-1-22 15:15
想象力加充分利用自己掌握的知识和能力,能做很多事情

我现在还没掌握呢,等学会了才有可能呢。
页: [1] 2 3
查看完整版本: 繁星似锦实现原理解析