>  기사  >  웹 프론트엔드  >  CSS와 JS는 낭만적인 유성우 애니메이션을 구현합니다.

CSS와 JS는 낭만적인 유성우 애니메이션을 구현합니다.

云罗郡主
云罗郡主앞으로
2018-11-13 17:30:142555검색

이 글의 내용은 CSS와 JS를 사용하여 로맨틱한 유성우 애니메이션을 구현하는 내용입니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다. 효과는 다음과 같습니다.

CSS와 JS는 낭만적인 유성우 애니메이션을 구현합니다.

HTML

노드가 많고 최대한 현실적이고 흥미롭게 만들고 싶어서 노드에 임의의 위치도 추가했습니다. 따라서 노드의 출력은 JS에 의해 제어됩니다. HTML 측에서는 몇 개의 상위 요소 상자와 해당 ID 이름 및 클래스 이름만 작성되며 구조는 비교적 간단합니다.

CSS

CSS 부분에서 어려운 부분은 유성 스타일과 원으로 구름을 그린 후 구름을 쌓아 입체감을 주는 스타일입니다. [추천 도서: CSS 스태킹 컨텍스트란 무엇인가요? 그것은 무엇을 합니까?

먼저 유성의 스타일에 대해 이야기해 보겠습니다.

#sky  .star {      position:absolute;
     不透明度:0 ;
     z-index:10000 ;
 }
 
 .star :: after {      content:“” ;
     显示:块;
     边界:坚固;     border-width:2px  0  2px  80px ;
     / *流星随长度逐渐缩小* / 
     border-color:透明透明透明rgba(255,255,255,1);     border-radius:2px  0  0  2px ;     transform:rotate(-45deg);     transform-origin:0  0  0 ;
     盒子阴影:0  0  20px  rgba(255,255,255,.3);
 }

먼저 공개 스타일을 추출하고 위치 속성을 추가합니다.

그런 다음 포스트 의사 클래스를 통해 별 뒤에 유성을 추가하고 경계 속성:

1) 모델 그리기: 테두리 너비의 순서는 위쪽, 오른쪽, 아래쪽, 왼쪽입니다. 마찬가지로 테두리 색상의 순서는 위쪽, 오른쪽, 아래쪽, 왼쪽입니다. 이렇게 border-width와 border-color를 일대일로 대응시키면 2px가 유성의 너비, 80px가 유성의 길이, 0픽셀의 유성이 꼬리임을 알 수 있고, 따라서 a를 형성합니다. 머리 너비 2px, 꼬리 0px, 길이 80px의 유성 모델

2) 약간 현실적: 테두리 반경 기준? 유성의 머리 부분에 둥근 모서리를 추가하여 더욱 사실적으로 보이게 합니다. 마지막으로 회전타를 통해 비스듬히 회전하여 떨어지는 것처럼 보이게 합니다.

3) 반짝임 추가: 유성에 약간의 후광을 추가합니다. 박스섀도우를 반짝반짝하게 만들어 보세요

위의 3단계를 거치면 별똥별이 완성됩니다.

그 다음은 구름 그림입니다.

구름의 코드가 비교적 길기 때문에 여기에는 올리지 않겠습니다. 방법은 하나씩 겹쳐서 덮어서 구름 모양을 완성하는 것 뿐입니다. .
구름 레이어를 완성한 후 하나를 복사한 다음 여러 구름 레이어를 회전, 불투명도, 왼쪽 위치 지정 등을 사용하여 페이드 및 겹침의 3차원 효과를 만듭니다.

JS

JS 부분에서는 유성을 예로 사용합니다. :

setInterval(function() {
     const obj = addChild(“#sky”,“div”,2,“star”); //插入流星
    for(let i = 0 ; i <obj.children.length; i ++){         //随机位置
        const top = -50 + Math .random()* 200 + “px”,
            left = 200 + Math .random()* 1200 + “px”,
            scale = 0.3 + Math .random()* 0.5 ;
        const timer = 1000 + Math .random()* 1000 ;
        obj.children [i] .style.top = top;
        obj.children [i] .style.left = left;
        obj.children [i] .style.transform = `scale($ {scale})` ;        
        //添加动画
        requestAnimation({
            ele:obj.children [i],
             attr:[ “top”,“left”,“opacity” ],
             值:[ 150,-150,.8 ],
             time:timer,
             flag:false,
             fn:function() {
                requestAnimation({
                    ELE:obj.children [I],
                     ATTR:“顶”,“左”,“不透明” ],
                     值:[ 150,-150,0 ],
                     时间:定时器,
                     标志:假,
                     FN:() => {
                        obj.parent.removeChild(obj.children [I]); //动画结束删除节点
                    }
                })
            }
        });
    }
},1000);

여기서 사용함 제가 직접 캡슐화한 두 가지 메소드는 requestAnimationFrame 기반의 requestAnimation과 appendChild 기반의 addChild입니다.

임의의 별 위치 효과를 얻기 위해 타이머의 setInterval을 통해 유성은 지속적으로 삽입 및 삭제됩니다.

먼저 페이지에 매번 2개의 유성을 추가하지만 타이머의 간격 시간은 유성의 애니메이션 시간이므로 페이지의 유성 개수는 고정된 값이 아니지만 확실히 2보다 크다는 것이 보장됩니다. 그렇지 않으면 한 번에 2개의 유성이 약간 버려지게 됩니다.

그런 다음 루프를 통해(표현으로도 사용할 수 있으며 대체할 수 있습니다. -의 경우 가장 간단합니다) 새로 추가된 유성을 각각에 제공합니다. 페이지 내 임의 위치(위, 왼쪽), 임의 크기(크기), 임의 애니메이션 실행 시간(타이머)

마지막으로 사용된 루프에서 페이지에 새로 추가된 각 유성에 애니메이션을 적용하고 콜백을 전달하는 함수입니다. 애니메이션 실행 후 노드. 여기서 주목해야 할 점은 애니메이션이 두 단계(나타남과 사라짐, 주로 불투명도 조절)로 나누어진다는 점이다. 게다가 여기서 처리할 때 각 유성은 300px 같은 거리로 이동합니다. 이 거리도 임의의 숫자로 제어할 수 있다고 생각하는데 게을러서 그렇게 하지 않았습니다.

첨부 코드:

HTML:

< body > 
    < div  class = “container” > 
        < div  id = “mask” > </ div > 
        < div  id = “sky” > </ div > 
        < div  id = “moon” > </ div > 
        < div  id = “stars” > </ div > 
        < div  class = “cloud cloud-1” ></ div > 
        <div  class = “cloud cloud-2” > </ div > 
        < div  class = “cloud cloud-3” > </ div > 
    </ div > 
</ body >

css:

/*  -  -  -  -  -  - 重启 -  -  -  -  -  -  */
 
 * {
     保证金:0 ;
     填充:0 ;
 }
 
 html,
  body {      width:100% ;
     最小宽度:1000px ;
     身高:100% ;
     最小高度:400px ;
     溢出:隐藏;
 }
 / * ------------画布------------ * / 
 .container {      position:relative;
     身高:100% ;
 }
 / *遮罩层* /
 
 #mask {      position:absolute;
     宽度:100% ;
     身高:100% ;     background:rgba(0,0,0,.8);
     z-index:900 ;
 }
 / *天空背景* /
 
 #sky {      width:100% ;
     身高:100% ;     background:线性渐变(rgba(0,150,255,1),rgba(0,150,255,.8),rgba(0,150,255,.5));
 }
 / *月亮* /
 
 #moon {      position:absolute;
     上:50px ;
     右:200px ;
     宽度:120px ;
     身高:120px ;
     背景:rgba(251,255,25,0.938);     border-radius:50% ;     box-shadow:0  0  20px  rgba(251,255,25,0.5);
     z-index:9999 ;
 }
 / *闪烁星星* /
 
 .blink {      position:absolute;     background:rgb(255,255,255);     border-radius:50% ;     box-shadow:0  0  5px  rgb(255,255,255);
     不透明度:0 ;
     z-index:10000 ;
 }
 / *流星* /
 
 .star {      position:absolute;
     不透明度:0 ;
     z-index:10000 ;
 }
 
 .star :: after {      content:“” ;
     显示:块;
     边界:坚固;     border-width:2px  0  2px  80px ;
     / *流星随长度逐渐缩小* / 
     border-color:透明透明透明rgba(255,255,255,1);     border-radius:2px  0  0  2px ;     transform:rotate(-45deg);     transform-origin:0  0  0 ;
     盒子阴影:0  0  20px  rgba(255,255,255,.3);
 }
 / *云* /
 
 .cloud {      position:absolute;
     宽度:100% ;
     身高:100px ;
 }
 
 .cloud-1 {
      bottom: - 100px ;
     z-index:1000 ;
     不透明度:1 ;
     变换:规模(1.5);
     -webkit-transform:scale(1.5);
     -moz-transform:scale(1.5);
     -ms-transform:scale(1.5);
     -o-transform:scale(1.5);
 }
 
 .cloud-2 {
      left: - 100px ;
     底部: - 50px ;
     z-index:999 ;
     不透明度:。5 ;
     变换:旋转(7deg);
     -webkit-transform:rotate(7deg);
     -moz-transform:rotate(7deg);
     -ms-transform:rotate(7deg);
     -o-transform:rotate(7deg);
 }
 
 .cloud-3 {
      left:120px ;
     底部: - 50px ;
     z-index:999 ;
     不透明度:。1 ;     transform:rotate(-10deg);
     -webkit-transform:rotate(-10deg);
     -moz-transform:rotate(-10deg);
     -ms-transform:rotate(-10deg);
     -o-transform:rotate(-10deg);
 }
 
 .circle {      position:absolute;     border-radius:50% ;
     背景:#fff ;
 }
 
 .circle-1 {      width:100px ;
     身高:100px ;
     上: - 50px ;
     左:10px ;
 }
 
 .circle-2 {      width:150px ;
     身高:150px ;
     上: - 50px ;
     左:30px ;
 }
 
 .circle-3 {      width:300px ;
     身高:300px ;
     上: - 100px ;
     左:80px ;
 }
 
 .circle-4 {      width:200px ;
     身高:200px ;
     上: - 60px ;
     左:300px ;
 }
 
 .circle-5 {      width:80px ;
     身高:80px ;
     上: - 30px ;
     左:450px ;
 }
 
 .circle-6 {      width:200px ;
     身高:200px ;
     上: - 50px ;
     左:500px ;
 }
 
 .circle-7 {      width:100px ;
     身高:100px ;
     上: - 10px ;
     左:650px ;
 }
 
 .circle-8 {      width:50px ;
     身高:50px ;
     上:30px ;
     左:730px ;
 }
 
 .circle-9 {      width:100px ;
     身高:100px ;
     上:30px ;
     左:750px ;
 }
 
 .circle-10 {      width:150px ;
     身高:150px ;
     上:10px ;
     左:800px ;
 }
 
 .circle-11 {      width:150px ;
     身高:150px ;
     上: - 30px ;
     左:850px ;
 }
 
 .circle-12 {      width:250px ;
     身高:250px ;
     上: - 50px ;
     左:900px ;
 }
 
 .circle-13 {      width:200px ;
     身高:200px ;
     上: - 40px ;
     左:1000px ;
 }
 
 .circle-14 {      width:300px ;
     身高:300px ;
     上: - 70px ;
     左:1100px ;

JS:

//流星动画 
setInterval(function() {
     const obj = addChild(“#sky”,“div”,2,“star”);    for(let i = 0 ; i <obj.children.length; i ++){
         const top = -50 + Math .random()* 200 + “px”,
            left = 200 + Math .random()* 1200 + “px”,            scale = 0.3 + Math .random()* 0.5 ;
        const timer = 1000 + Math .random()* 1000 ;
        obj.children [i] .style.top = top;
        obj.children [i] .style.left = left;
        obj.children [i] .style.transform = `scale($ {scale})` ;
        requestAnimation({
            ele:obj.children [i],
             attr:[ “top”,“left”,“opacity” ],
             值:[ 150,-150,.8 ],             time:timer,
             flag:false,
             fn:function() {
                requestAnimation({
                    ELE:obj.children [I],
                     ATTR:“顶”,“左”,“不透明” ],
                     值:[ 150,-150,0 ],
                     时间:定时器,
                     标志:假,
                     FN:() => {
                        obj.parent.removeChild(obj.children [I]);
                    }
                })
            }
        });
    }
},1000);
//闪烁星星动画 
setInterval(function() {
     const obj = addChild(“#stars”,“div”,2,“blink”);    for(let i = 0 ; i <obj.children.length; i ++){
         const top = -50 + Math .random()* 500 + “px”,
            left = 200 + Math .random()* 1200 + “px”,            round = 1 + Math .random()* 2 + “px” ;
        const timer = 1000 + Math .random()* 4000 ;
        obj.children [i] .style.top = top;
        obj.children [i] .style.left = left;
        obj.children [i] .style.width = round;
        obj.children [i] .style.height = round;
        requestAnimation({
            ele:obj.children [i],
             attr:“opacity”,
             值:.5,             time:timer,
             flag:false,
             fn:function() {
                requestAnimation({
                    ele:obj.children [i],
                     attr:“opacity”,
                     value:0,                     time:timer,
                     flag:false,
                     fn:function() {
                        obj.parent.removeChild(obj.children [I]);
                    }
                });
            }
        });
    }
},1000);
//月亮移动
requestAnimation({
    ele:“#moon”,
     attr:“right”,
     值:1200,
     时间:10000000,
});
//添加云
const clouds = addChild(“。cloud”,“div”,14,“circle”,true);for(let i = 0 ; i <clouds.children.length; i ++){     for(let j = 0 ; j <clouds.children [i] .length;){
        clouds.children [i] [j] .classList.add(`circle- $ {++ j} `);
    }
}
//云动画let flag = 1 ;
的setInterval(
    功能() {
         const clouds = document .querySelectorAll(“。cloud”);
        const left = Math .random()* 5 ;
        bottom = Math .random()* 5 ;        let timer = 0 ;        for(let i = 0 ; i <clouds.length; i ++){
            requestAnimation({
                ele:clouds [i],
                 attr:[ “left”,“bottom” ],
                 value:flag%2?[-left,-bottom]:[left,bottom],                 time:timer + = 500,
                 flag:false,
                 fn:function() {
                    requestAnimation({
                        ele:clouds [i],
                         attr:[ “left”,“bottom” ],
                         value:flag%2?[left,bottom]:[ -  left,-bottom],                         time:timer,
                         flag:false
                    })
                }
            });
        }
        标志++;
    },2000)

위는 CSS 튜토리얼에 대해 더 알고 싶다면 로맨틱한 유성우 애니메이션을 구현하기 위한 CSS 및 JS에 대한 완전한 소개입니다. , PHP 중국어 웹사이트를 팔로우하세요.


위 내용은 CSS와 JS는 낭만적인 유성우 애니메이션을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제