この記事はCSSとJSでロマンチックな流星群のアニメーションを実現するというもので、困っている方は参考にしていただければ幸いです。効果は次のとおりです。
HTML
多くのノードがあり、できるだけ現実的で興味深いものにしたいので、次も追加しましたノードへのランダムな位置。したがって、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); }
まずパブリック スタイルを抽出し、位置決め属性を追加します;
次に、星の後ろに擬似流星をクラスに追加し、border プロパティで描画します。
1) モデル描画: border-width の順序は、4 辺の上、右、下、左です。 border-color の順序は 4 辺の上、右、下、左です。このように、border-width と border-color を 1 対 1 に対応させると、2px が流星の幅、80px が流星の長さ、0 ピクセルの流星が尾であることがわかります。したがって、 a を形成します。頭部の幅 2 ピクセル、尾の幅 0 ピクセル、長さ 80 ピクセルの流星モデル;
2) 少し現実的: 境界線の半径による?流星の頭に丸い角を追加して、より現実的に見えるようにします。最後に、rotationta を使用して斜めに回転させ、落下しているように見せます。
3) 輝きを追加: ボックスの影を追加します。流星に少しハローを追加して、キラキラと見せます。
上記の 3 つの手順を完了すると、流れ星の準備が整います。
次に、雲の描画です。
雲のコードは比較的長いため、ここには掲載しません。方法は、1 つずつ重ねてカバーするだけです。雲の形。
雲レイヤーが完成したら、1 つをコピーし、回転、不透明度、左位置などを使用して、フェードと重なりの 3 次元効果を作成します。 ##JS 部分は Meteor の例です:
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);
ここでは自分でカプセル化した 2 つのメソッドを使用します。1 つは requestAnimationFrame に基づく requestAnimation と、appendChild に基づく addChild です。
ランダムな星の位置の効果を実現するために、タイマーの setInterval を通じて流星が継続的に挿入および削除されます。
最初に、毎回 2 つの流星をページに追加しますが、間隔は流星のアニメーション時間よりも短いタイマーの値。これにより、ページ上の流星の数が固定値ではなく、2 より大きくなければなりません。そうしないと、一度に 2 つの流星が少し寂しくなります;
次に、ループ (式としても使用でき、変更できます。- の場合、これが最も簡単です) を介して、それぞれに与えます。ページに新しく追加された meteor は、ランダムな位置 (上、左)、ランダムなサイズ (スケール)、ランダムなアニメーション実行時間 (タイマー);
最後に、ループ内で、ページに新しく追加されたそれぞれの Meteor を追加します。アニメーションを作成し、コールバック関数を通じてアニメーションを実行した後にノードを削除します。ここで注目すべきはアニメーションが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の実装であり、 JS ロマンチックな流星群アニメーションの完全な紹介
CSS チュートリアルについて詳しく知りたい場合は、PHP 中国語 Web サイトに注目してください。
以上がCSSとJSでロマンチックな流星群アニメーションを実現の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。