<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>流星、烟花</title>
<style>
body {
background: #000;
margin: 0;
}
canvas {
cursor: pointer;
display: block;
}
.moon {
position: fixed;
right: 10%;
top: 10%;
width: 9rem;
height: 9rem;
overflow: hidden;
border-radius: 50%;
box-shadow: 0 0 10px #fff, 0 0 30px #fff;
}
.moon>img {
width: 100%;
transform: scale(1.5);
margin-left: -2px;
}
.verse {
position: fixed;
right: 5%;
top: 30%;
/* width: 30%; */
text-align: center;
letter-spacing: 2px;
color: rgb(228, 215, 241);
font-family: 楷体;
font-weight: bold;
/* text-shadow: 0px 0px 1px #fff; */
}
.path-0 {
animation: pathAnim-0 4s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes pathAnim-0 {
0% {
d: path("M 0,400 C 0,400 0,80 0,80 C 56.809462444771725,71.1209499263623 113.61892488954345,62.2418998527246 169,64 C 224.38107511045655,65.7581001472754 278.3337628865979,78.15335051546391 337,81 C 395.6662371134021,83.84664948453609 459.04602356406485,77.14469808541973 517,82 C 574.9539764359351,86.85530191458027 627.4821428571429,103.26785714285714 701,102 C 774.5178571428571,100.73214285714286 869.0254050073638,81.78387334315168 932,73 C 994.9745949926362,64.21612665684832 1026.416237113402,65.59664948453609 1082,73 C 1137.583762886598,80.40335051546391 1217.309646539028,93.82952871870398 1281,96 C 1344.690353460972,98.17047128129602 1392.345176730486,89.08523564064801 1440,80 C 1440,80 1440,400 1440,400 Z");
}
25% {
d: path("M 0,400 C 0,400 0,80 0,80 C 51.83302650957289,81.79418262150222 103.66605301914578,83.58836524300442 167,76 C 230.33394698085422,68.41163475699558 305.16881443298973,51.44072164948453 365,57 C 424.83118556701027,62.55927835051547 469.6586892488955,90.64874815905745 532,105 C 594.3413107511045,119.35125184094255 674.1964285714286,119.96428571428571 734,108 C 793.8035714285714,96.03571428571429 833.5555964653902,71.4941089837997 886,75 C 938.4444035346098,78.5058910162003 1003.5811855670104,110.05927835051546 1060,107 C 1116.4188144329896,103.94072164948454 1164.1196612665685,66.26877761413844 1226,56 C 1287.8803387334315,45.73122238586156 1363.9401693667157,62.86561119293078 1440,80 C 1440,80 1440,400 1440,400 Z");
}
50% {
d: path("M 0,400 C 0,400 0,80 0,80 C 52.520066273932244,72.68317378497791 105.04013254786449,65.36634756995582 171,69 C 236.9598674521355,72.63365243004418 316.3595360824742,87.21778350515464 384,92 C 451.6404639175258,96.78221649484536 507.52172312223854,91.76251840942562 551,93 C 594.4782768777615,94.23748159057438 625.5535714285713,101.73214285714286 693,104 C 760.4464285714287,106.26785714285714 864.2639911634759,103.30891016200296 927,103 C 989.7360088365241,102.69108983799704 1011.3904639175257,105.03221649484536 1065,94 C 1118.6095360824743,82.96778350515464 1204.1741531664213,58.56222385861561 1272,54 C 1339.8258468335787,49.43777614138439 1389.9129234167895,64.7188880706922 1440,80 C 1440,80 1440,400 1440,400 Z");
}
75% {
d: path("M 0,400 C 0,400 0,80 0,80 C 63.355486008836536,92.28865979381443 126.71097201767307,104.57731958762886 182,102 C 237.28902798232693,99.42268041237114 284.5115979381443,81.97938144329896 344,79 C 403.4884020618557,76.02061855670104 475.2426362297498,87.50515463917526 535,94 C 594.7573637702502,100.49484536082474 642.5178571428571,102 711,92 C 779.4821428571429,82 868.6859351988218,60.49484536082474 928,54 C 987.3140648011782,47.50515463917526 1016.7384020618558,56.02061855670103 1061,59 C 1105.2615979381442,61.97938144329897 1164.3604565537555,59.422680412371136 1230,62 C 1295.6395434462445,64.57731958762886 1367.8197717231224,72.28865979381443 1440,80 C 1440,80 1440,400 1440,400 Z");
}
100% {
d: path("M 0,400 C 0,400 0,80 0,80 C 56.809462444771725,71.1209499263623 113.61892488954345,62.2418998527246 169,64 C 224.38107511045655,65.7581001472754 278.3337628865979,78.15335051546391 337,81 C 395.6662371134021,83.84664948453609 459.04602356406485,77.14469808541973 517,82 C 574.9539764359351,86.85530191458027 627.4821428571429,103.26785714285714 701,102 C 774.5178571428571,100.73214285714286 869.0254050073638,81.78387334315168 932,73 C 994.9745949926362,64.21612665684832 1026.416237113402,65.59664948453609 1082,73 C 1137.583762886598,80.40335051546391 1217.309646539028,93.82952871870398 1281,96 C 1344.690353460972,98.17047128129602 1392.345176730486,89.08523564064801 1440,80 C 1440,80 1440,400 1440,400 Z");
}
}
.path-1 {
animation: pathAnim-1 4s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes pathAnim-1 {
0% {
d: path("M 0,400 C 0,400 0,160 0,160 C 54.34149484536083,145.6104565537555 108.68298969072166,131.22091310751105 168,135 C 227.31701030927834,138.77908689248895 291.60953608247416,160.7268041237113 358,159 C 424.39046391752584,157.2731958762887 492.87886597938154,131.87187039764362 547,131 C 601.1211340206185,130.12812960235638 640.875,153.78571428571428 701,164 C 761.125,174.21428571428572 841.6211340206188,170.98527245949924 904,176 C 966.3788659793812,181.01472754050076 1010.6404639175255,194.27319587628867 1073,186 C 1135.3595360824745,177.72680412371133 1215.8170103092784,147.92194403534612 1280,140 C 1344.1829896907216,132.07805596465388 1392.0914948453608,146.03902798232696 1440,160 C 1440,160 1440,400 1440,400 Z");
}
25% {
d: path("M 0,400 C 0,400 0,160 0,160 C 65.27393225331369,167.49079528718704 130.54786450662738,174.9815905743741 186,179 C 241.45213549337262,183.0184094256259 287.0824742268041,183.56443298969072 346,175 C 404.9175257731959,166.43556701030928 477.1222385861561,148.76067746686303 537,144 C 596.8777614138439,139.23932253313697 644.4285714285714,147.39285714285714 704,154 C 763.5714285714286,160.60714285714286 835.1634756995581,165.66789396170842 910,166 C 984.8365243004419,166.33210603829158 1062.9175257731958,161.93556701030928 1112,156 C 1161.0824742268042,150.06443298969072 1181.1664212076582,142.5898379970545 1231,143 C 1280.8335787923418,143.4101620029455 1360.4167893961708,151.70508100147276 1440,160 C 1440,160 1440,400 1440,400 Z");
}
50% {
d: path("M 0,400 C 0,400 0,160 0,160 C 54.760493372606774,164.8637702503682 109.52098674521355,169.7275405007364 169,171 C 228.47901325478645,172.2724594992636 292.6765463917526,169.95360824742266 355,174 C 417.3234536082474,178.04639175257734 477.77282768777627,188.45802650957293 539,180 C 600.2271723122237,171.54197349042707 662.2321428571428,144.2142857142857 717,136 C 771.7678571428572,127.7857142857143 819.2986008836524,138.68483063328426 882,153 C 944.7013991163476,167.31516936671574 1022.5734536082473,185.0463917525773 1094,179 C 1165.4265463917527,172.9536082474227 1230.407584683358,143.12960235640648 1287,136 C 1343.592415316642,128.87039764359352 1391.796207658321,144.43519882179675 1440,160 C 1440,160 1440,400 1440,400 Z");
}
75% {
d: path("M 0,400 C 0,400 0,160 0,160 C 41.69606038291603,158.04657584683358 83.39212076583206,156.09315169366715 154,156 C 224.60787923416794,155.90684830633285 324.1275773195877,157.67396907216497 391,163 C 457.8724226804123,168.32603092783503 492.09756995581733,177.21097201767304 536,174 C 579.9024300441827,170.78902798232696 633.4821428571429,155.48214285714286 695,153 C 756.5178571428571,150.51785714285714 825.9738586156111,160.8604565537555 888,159 C 950.0261413843889,157.1395434462445 1004.6224226804125,143.07603092783506 1066,148 C 1127.3775773195875,152.92396907216494 1195.5364506627393,176.83541973490426 1259,182 C 1322.4635493372607,187.16458026509574 1381.2317746686304,173.58229013254788 1440,160 C 1440,160 1440,400 1440,400 Z");
}
100% {
d: path("M 0,400 C 0,400 0,160 0,160 C 54.34149484536083,145.6104565537555 108.68298969072166,131.22091310751105 168,135 C 227.31701030927834,138.77908689248895 291.60953608247416,160.7268041237113 358,159 C 424.39046391752584,157.2731958762887 492.87886597938154,131.87187039764362 547,131 C 601.1211340206185,130.12812960235638 640.875,153.78571428571428 701,164 C 761.125,174.21428571428572 841.6211340206188,170.98527245949924 904,176 C 966.3788659793812,181.01472754050076 1010.6404639175255,194.27319587628867 1073,186 C 1135.3595360824745,177.72680412371133 1215.8170103092784,147.92194403534612 1280,140 C 1344.1829896907216,132.07805596465388 1392.0914948453608,146.03902798232696 1440,160 C 1440,160 1440,400 1440,400 Z");
}
}
.path-2 {
animation: pathAnim-2 4s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes pathAnim-2 {
0% {
d: path("M 0,400 C 0,400 0,240 0,240 C 72.96778350515464,245.45342415316642 145.93556701030928,250.90684830633285 210,249 C 274.0644329896907,247.09315169366715 329.22551546391753,237.82603092783506 375,241 C 420.77448453608247,244.17396907216494 457.16237113402053,259.78902798232696 521,261 C 584.8376288659795,262.21097201767304 676.1250000000001,249.01785714285714 739,246 C 801.8749999999999,242.98214285714286 836.3376288659792,250.1395434462445 883,247 C 929.6623711340208,243.8604565537555 988.5244845360826,230.4239690721649 1053,229 C 1117.4755154639174,227.5760309278351 1187.5644329896907,238.16458026509574 1253,242 C 1318.4355670103093,245.83541973490426 1379.2177835051548,242.91770986745212 1440,240 C 1440,240 1440,400 1440,400 Z");
}
25% {
d: path("M 0,400 C 0,400 0,240 0,240 C 54.676730486008836,249.2829528718704 109.35346097201767,258.5659057437408 173,254 C 236.64653902798233,249.4340942562592 309.2628865979382,231.01932989690718 372,233 C 434.7371134020618,234.98067010309282 487.5949926362297,257.35677466863035 537,264 C 586.4050073637703,270.64322533136965 632.3571428571429,261.5535714285714 704,247 C 775.6428571428571,232.4464285714286 872.9764359351987,212.42893961708396 932,213 C 991.0235640648013,213.57106038291604 1011.737113402062,234.73067010309276 1070,242 C 1128.262886597938,249.26932989690724 1224.0751104565538,242.6483799705449 1292,240 C 1359.9248895434462,237.3516200294551 1399.962444771723,238.67581001472755 1440,240 C 1440,240 1440,400 1440,400 Z");
}
50% {
d: path("M 0,400 C 0,400 0,240 0,240 C 69.93538291605303,234.76914580265097 139.87076583210606,229.53829160530194 195,236 C 250.12923416789394,242.46170839469806 290.4523195876288,260.61597938144325 352,260 C 413.5476804123712,259.38402061855675 496.3199558173786,239.99779086892494 559,230 C 621.6800441826214,220.00220913107506 664.2678571428571,219.39285714285714 725,218 C 785.7321428571429,216.60714285714286 864.6086156111929,214.4307805596465 927,218 C 989.3913843888071,221.5692194403535 1035.2976804123714,230.88402061855672 1091,236 C 1146.7023195876286,241.11597938144328 1212.2006627393225,242.03313696612665 1272,242 C 1331.7993372606775,241.96686303387335 1385.8996686303387,240.98343151693666 1440,240 C 1440,240 1440,400 1440,400 Z");
}
75% {
d: path("M 0,400 C 0,400 0,240 0,240 C 67.4913475699558,244.23287923416788 134.9826951399116,248.46575846833576 189,244 C 243.0173048600884,239.53424153166424 283.5605670103093,226.36984536082477 343,226 C 402.4394329896907,225.63015463917523 480.7750368188513,238.05486008836522 542,238 C 603.2249631811487,237.94513991163478 647.3392857142857,225.4107142857143 698,230 C 748.6607142857143,234.5892857142857 805.867820324006,256.30228276877756 871,261 C 936.132179675994,265.69771723122244 1009.1894329896909,253.38015463917526 1080,248 C 1150.8105670103091,242.61984536082474 1219.374447717231,244.17709867452135 1279,244 C 1338.625552282769,243.82290132547865 1389.3127761413843,241.91145066273933 1440,240 C 1440,240 1440,400 1440,400 Z");
}
100% {
d: path("M 0,400 C 0,400 0,240 0,240 C 72.96778350515464,245.45342415316642 145.93556701030928,250.90684830633285 210,249 C 274.0644329896907,247.09315169366715 329.22551546391753,237.82603092783506 375,241 C 420.77448453608247,244.17396907216494 457.16237113402053,259.78902798232696 521,261 C 584.8376288659795,262.21097201767304 676.1250000000001,249.01785714285714 739,246 C 801.8749999999999,242.98214285714286 836.3376288659792,250.1395434462445 883,247 C 929.6623711340208,243.8604565537555 988.5244845360826,230.4239690721649 1053,229 C 1117.4755154639174,227.5760309278351 1187.5644329896907,238.16458026509574 1253,242 C 1318.4355670103093,245.83541973490426 1379.2177835051548,242.91770986745212 1440,240 C 1440,240 1440,400 1440,400 Z");
}
}
.path-3 {
animation: pathAnim-3 4s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes pathAnim-3 {
0% {
d: path("M 0,400 C 0,400 0,320 0,320 C 65.7428203240059,326.45379234167893 131.4856406480118,332.90758468335787 192,339 C 252.5143593519882,345.09241531664213 307.80025773195877,350.82345360824746 372,347 C 436.19974226804123,343.17654639175254 509.31332842415316,329.7986008836524 566,322 C 622.6866715758468,314.2013991163476 662.9464285714286,311.9821428571429 718,311 C 773.0535714285714,310.0178571428571 842.9009572901325,310.2728276877761 906,308 C 969.0990427098675,305.7271723122239 1025.449742268041,300.9265463917526 1082,309 C 1138.550257731959,317.0734536082474 1195.3000736377026,338.0209867452136 1255,342 C 1314.6999263622974,345.9790132547864 1377.3499631811487,332.9895066273932 1440,320 C 1440,320 1440,400 1440,400 Z");
}
25% {
d: path("M 0,400 C 0,400 0,320 0,320 C 72.41402798232696,315.3726067746686 144.8280559646539,310.7452135493373 197,305 C 249.1719440353461,299.2547864506627 281.1018041237113,292.3917525773196 329,295 C 376.8981958762887,297.6082474226804 440.76472754050076,309.6877761413844 519,310 C 597.2352724594992,310.3122238586156 689.8392857142857,298.85714285714283 750,305 C 810.1607142857143,311.14285714285717 837.8781296023566,334.88365243004415 891,340 C 944.1218703976434,345.11634756995585 1022.6481958762884,331.6082474226804 1087,331 C 1151.3518041237116,330.3917525773196 1201.5290868924892,342.6833578792342 1258,343 C 1314.4709131075108,343.3166421207658 1377.2354565537553,331.6583210603829 1440,320 C 1440,320 1440,400 1440,400 Z");
}
50% {
d: path("M 0,400 C 0,400 0,320 0,320 C 57.35162002945506,306.69311487481593 114.70324005891013,293.3862297496318 175,300 C 235.29675994108987,306.6137702503682 298.5386597938145,333.14819587628864 363,338 C 427.4613402061855,342.85180412371136 493.14212076583203,326.0209867452136 542,325 C 590.857879234168,323.9790132547864 622.8928571428571,338.7678571428571 689,344 C 755.1071428571429,349.2321428571429 855.2864506627394,344.90758468335787 920,341 C 984.7135493372606,337.09241531664213 1013.9613402061855,333.60180412371136 1065,330 C 1116.0386597938145,326.39819587628864 1188.8681885125186,322.6851988217968 1255,321 C 1321.1318114874814,319.3148011782032 1380.5659057437406,319.6574005891016 1440,320 C 1440,320 1440,400 1440,400 Z");
}
75% {
d: path("M 0,400 C 0,400 0,320 0,320 C 47.39745949926362,301.8530927835052 94.79491899852724,283.7061855670103 160,291 C 225.20508100147276,298.2938144329897 308.21778350515467,331.02835051546396 382,343 C 455.78221649484533,354.97164948453604 520.3339469808542,346.180412371134 567,329 C 613.6660530191458,311.819587628866 642.4464285714286,286.25 697,291 C 751.5535714285714,295.75 831.8803387334315,330.819587628866 901,341 C 970.1196612665685,351.180412371134 1028.0322164948452,336.4716494845361 1086,323 C 1143.9677835051548,309.5283505154639 1201.990795287187,297.2938144329897 1261,297 C 1320.009204712813,296.7061855670103 1380.0046023564064,308.3530927835052 1440,320 C 1440,320 1440,400 1440,400 Z");
}
100% {
d: path("M 0,400 C 0,400 0,320 0,320 C 65.7428203240059,326.45379234167893 131.4856406480118,332.90758468335787 192,339 C 252.5143593519882,345.09241531664213 307.80025773195877,350.82345360824746 372,347 C 436.19974226804123,343.17654639175254 509.31332842415316,329.7986008836524 566,322 C 622.6866715758468,314.2013991163476 662.9464285714286,311.9821428571429 718,311 C 773.0535714285714,310.0178571428571 842.9009572901325,310.2728276877761 906,308 C 969.0990427098675,305.7271723122239 1025.449742268041,300.9265463917526 1082,309 C 1138.550257731959,317.0734536082474 1195.3000736377026,338.0209867452136 1255,342 C 1314.6999263622974,345.9790132547864 1377.3499631811487,332.9895066273932 1440,320 C 1440,320 1440,400 1440,400 Z");
}
}
.weizhi {
position: fixed;
bottom: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: flex-end;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div class="moon">
<img src="https://img95.699pic.com/element/40161/6685.png_300.png" alt="月亮是古人寄托思念,就像你在我心里的位置一样">
</div>
<div class="verse">
<p>同从弟南斋玩月忆山阴崔少府</p>
<p>王昌龄(唐)</p>
<p>高卧南斋时,开帷月初吐。</p>
<p>清辉澹水木,演漾在窗户。</p>
<p>荏苒几盈虚,澄澄变今古。</p>
<p>美人清江畔,是夜越吟苦。</p>
<p>千里共如何,微风吹兰杜。</p>
</div>
<svg width="100%" id="svg" viewBox="0 0 1440 400" xmlns="http://www.w3.org/2000/svg"
class="transition weizhi duration-300 ease-in-out delay-150">
<defs>
<linearGradient id="gradient" x1="48%" y1="0%" x2="52%" y2="100%">
<stop offset="5%" stop-color="#00000044"></stop>
<stop offset="95%" stop-color="#9900ef44"></stop>
</linearGradient>
</defs>
<path
d="M 0,400 C 0,400 0,80 0,80 C 56.809462444771725,71.1209499263623 113.61892488954345,62.2418998527246 169,64 C 224.38107511045655,65.7581001472754 278.3337628865979,78.15335051546391 337,81 C 395.6662371134021,83.84664948453609 459.04602356406485,77.14469808541973 517,82 C 574.9539764359351,86.85530191458027 627.4821428571429,103.26785714285714 701,102 C 774.5178571428571,100.73214285714286 869.0254050073638,81.78387334315168 932,73 C 994.9745949926362,64.21612665684832 1026.416237113402,65.59664948453609 1082,73 C 1137.583762886598,80.40335051546391 1217.309646539028,93.82952871870398 1281,96 C 1344.690353460972,98.17047128129602 1392.345176730486,89.08523564064801 1440,80 C 1440,80 1440,400 1440,400 Z"
stroke="none" stroke-width="0" fill="url(#gradient)"
class="transition-all duration-300 ease-in-out delay-150 path-0"></path>
<defs>
<linearGradient id="gradient" x1="48%" y1="0%" x2="52%" y2="100%">
<stop offset="5%" stop-color="#00000066"></stop>
<stop offset="95%" stop-color="#9900ef66"></stop>
</linearGradient>
</defs>
<path
d="M 0,400 C 0,400 0,160 0,160 C 54.34149484536083,145.6104565537555 108.68298969072166,131.22091310751105 168,135 C 227.31701030927834,138.77908689248895 291.60953608247416,160.7268041237113 358,159 C 424.39046391752584,157.2731958762887 492.87886597938154,131.87187039764362 547,131 C 601.1211340206185,130.12812960235638 640.875,153.78571428571428 701,164 C 761.125,174.21428571428572 841.6211340206188,170.98527245949924 904,176 C 966.3788659793812,181.01472754050076 1010.6404639175255,194.27319587628867 1073,186 C 1135.3595360824745,177.72680412371133 1215.8170103092784,147.92194403534612 1280,140 C 1344.1829896907216,132.07805596465388 1392.0914948453608,146.03902798232696 1440,160 C 1440,160 1440,400 1440,400 Z"
stroke="none" stroke-width="0" fill="url(#gradient)"
class="transition-all duration-300 ease-in-out delay-150 path-1"></path>
<defs>
<linearGradient id="gradient" x1="48%" y1="0%" x2="52%" y2="100%">
<stop offset="5%" stop-color="#00000088"></stop>
<stop offset="95%" stop-color="#9900ef88"></stop>
</linearGradient>
</defs>
<path
d="M 0,400 C 0,400 0,240 0,240 C 72.96778350515464,245.45342415316642 145.93556701030928,250.90684830633285 210,249 C 274.0644329896907,247.09315169366715 329.22551546391753,237.82603092783506 375,241 C 420.77448453608247,244.17396907216494 457.16237113402053,259.78902798232696 521,261 C 584.8376288659795,262.21097201767304 676.1250000000001,249.01785714285714 739,246 C 801.8749999999999,242.98214285714286 836.3376288659792,250.1395434462445 883,247 C 929.6623711340208,243.8604565537555 988.5244845360826,230.4239690721649 1053,229 C 1117.4755154639174,227.5760309278351 1187.5644329896907,238.16458026509574 1253,242 C 1318.4355670103093,245.83541973490426 1379.2177835051548,242.91770986745212 1440,240 C 1440,240 1440,400 1440,400 Z"
stroke="none" stroke-width="0" fill="url(#gradient)"
class="transition-all duration-300 ease-in-out delay-150 path-2"></path>
<defs>
<linearGradient id="gradient" x1="48%" y1="0%" x2="52%" y2="100%">
<stop offset="5%" stop-color="#000000ff"></stop>
<stop offset="95%" stop-color="#9900efff"></stop>
</linearGradient>
</defs>
<path
d="M 0,400 C 0,400 0,320 0,320 C 65.7428203240059,326.45379234167893 131.4856406480118,332.90758468335787 192,339 C 252.5143593519882,345.09241531664213 307.80025773195877,350.82345360824746 372,347 C 436.19974226804123,343.17654639175254 509.31332842415316,329.7986008836524 566,322 C 622.6866715758468,314.2013991163476 662.9464285714286,311.9821428571429 718,311 C 773.0535714285714,310.0178571428571 842.9009572901325,310.2728276877761 906,308 C 969.0990427098675,305.7271723122239 1025.449742268041,300.9265463917526 1082,309 C 1138.550257731959,317.0734536082474 1195.3000736377026,338.0209867452136 1255,342 C 1314.6999263622974,345.9790132547864 1377.3499631811487,332.9895066273932 1440,320 C 1440,320 1440,400 1440,400 Z"
stroke="none" stroke-width="0" fill="url(#gradient)"
class="transition-all duration-300 ease-in-out delay-150 path-3"></path>
</svg>
</body>
<script>
// 坐标
class Crood {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
setCrood(x, y) {
this.x = x;
this.y = y;
}
copy() {
return new Crood(this.x, this.y);
}
}
// 流星
class ShootingStar {
constructor(init = new Crood, final = new Crood, size = 3, speed = 200, onDistory = null) {
this.init = init; // 初始位置
this.final = final; // 最终位置
this.size = size; // 大小
this.speed = speed; // 速度:像素/s
// 飞行总时间
this.dur = Math.sqrt(Math.pow(this.final.x - this.init.x, 2) + Math.pow(this.final.y - this.init.y, 2)) * 1000 / this.speed;
this.pass = 0; // 已过去的时间
this.prev = this.init.copy(); // 上一帧位置
this.now = this.init.copy(); // 当前位置
this.onDistory = onDistory;
}
draw(ctx, delta) {
this.pass += delta;
this.pass = Math.min(this.pass, this.dur);
let percent = this.pass / this.dur;
this.now.setCrood(
this.init.x + (this.final.x - this.init.x) * percent,
this.init.y + (this.final.y - this.init.y) * percent
);
// canvas
ctx.strokeStyle = '#fff';
ctx.lineCap = 'round';
ctx.lineWidth = this.size;
ctx.beginPath();
ctx.moveTo(this.now.x, this.now.y);
ctx.lineTo(this.prev.x, this.prev.y);
ctx.stroke();
this.prev.setCrood(this.now.x, this.now.y);
if (this.pass === this.dur) {
this.distory();
}
}
distory() {
this.onDistory && this.onDistory();
}
}
// 流星雨
class MeteorShower {
constructor(cvs, ctx) {
this.cvs = cvs;
this.ctx = ctx;
this.stars = [];
this.T;
this.stop = false;
this.playing = false;
}
// 生成随机位置的流星
createStar() {
let angle = Math.PI / 3;
let distance = Math.random() * 800;
let init = new Crood((Math.random() * 1.2 * this.cvs.width - 50), Math.random() * 300 | 0);
let final = new Crood(init.x + distance * Math.cos(angle), init.y + distance * Math.sin(angle));
let size = Math.random() * 4;
let speed = Math.random() * 400 + 100;
let star = new ShootingStar(
init, final, size, speed,
() => { this.remove(star) }
);
return star;
}
remove(star) {
this.stars = this.stars.filter((s) => { return s !== star });
}
update(delta) {
if (!this.stop && this.stars.length < 40) {
this.stars.push(this.createStar());
}
this.stars.forEach((star) => {
star.draw(this.ctx, delta);
});
}
tick() {
if (this.playing) return;
this.playing = true;
let now = (new Date()).getTime();
let last = now;
let delta;
let _tick = () => {
if (this.stop && this.stars.length === 0) {
cancelAnimationFrame(this.T);
this.playing = false;
return;
}
delta = now - last;
delta = delta > 500 ? 30 : (delta < 16 ? 16 : delta);
last = now;
// console.log(delta);
this.T = requestAnimationFrame(_tick);
ctx.save();
ctx.globalCompositeOperation = "destination-in";
ctx.fillStyle = 'rgba(0,0,0,0.8)'; // 每一帧用 “半透明” 的背景色清除画布
ctx.fillRect(0, 0, cvs.width, cvs.height);
ctx.restore();
this.update(delta);
}
_tick();
}
// 开始
start() {
this.stop = false;
this.tick();
}
// 暂停
stop() {
this.stop = true;
}
}
let cvs = document.querySelector('canvas');
let ctx = cvs.getContext('2d');
let meteorShower = new MeteorShower(cvs, ctx);
meteorShower.start();
</script>
<script>
// 当在画布上动画时,最好使用requestAnimationFrame而不是setTimeout或setInterval
// 但并非所有浏览器都支持,有时需要一个前缀,所以我们需要一个垫片
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
// 现在,我们将为演示设置基本变量
var canvas = document.getElementById('canvas'),
ctxyi = canvas.getContext('2d'),
// 全屏幕尺寸
cw = window.innerWidth,
ch = window.innerHeight,
// 烟花集合
fireworks = [],
// 粒子集合
particles = [],
// 从色调
hue = 120,
// 当使用点击方式发射烟花爆竹时,如果一次性发射过多烟花爆竹,则没有限制,每5个循环发射一次
limiterTotal = 5,
limiterTick = 0,
// 这将计时烟花的自动发射,每80个循环滴答一次发射
timerTotal = 80,
timerTick = 0,
mousedown = false,
// 鼠标x坐标,
mx,
// 鼠标y坐标
my;
// 设置画布尺寸
canvas.width = cw;
canvas.height = ch;
// 现在我们将为整个演示设置函数占位符
// get a random number within a range
function random(min, max) {
return Math.random() * (max - min) + min;
}
// 计算两点之间的距离
function calculateDistance(p1x, p1y, p2x, p2y) {
var xDistance = p1x - p2x,
yDistance = p1y - p2y;
return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
}
// 创建烟花
function Firework(sx, sy, tx, ty) {
//实际的坐标
this.x = sx;
this.y = sy;
// 起始坐标
this.sx = sx;
this.sy = sy;
// 目标坐标
this.tx = tx;
this.ty = ty;
// 从起点到目标的距离
this.distanceToTarget = calculateDistance(sx, sy, tx, ty);
this.distanceTraveled = 0;
// 跟踪每一个烟花的过去的坐标来创建一个步道效果,增加坐标计数来创建更突出的步道
this.coordinates = [];
this.coordinateCount = 3;
// 用当前坐标填充初始坐标集合
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
this.angle = Math.atan2(ty - sy, tx - sx);
this.speed = 2;
this.acceleration = 1.05;
this.brightness = random(50, 70);
// 圆形目标指示器半径
this.targetRadius = 1;
}
// 更新烟花
Firework.prototype.update = function (index) {
// 移除坐标数组中的最后一项
this.coordinates.pop();
// 将当前坐标添加到数组的开头
this.coordinates.unshift([this.x, this.y]);
// 循环圆形目标指示器半径
if (this.targetRadius < 8) {
this.targetRadius += 0.3;
} else {
this.targetRadius = 1;
}
// 加快燃放速度
this.speed *= this.acceleration;
// 根据角度和速度得到当前速度
var vx = Math.cos(this.angle) * this.speed,
vy = Math.sin(this.angle) * this.speed;
// 在施加的速度下,烟花会飞多远?
this.distanceTraveled = calculateDistance(this.sx, this.sy, this.x + vx, this.y + vy);
// 如果移动的距离(包括速度)大于到目标的初始距离,那么就已经到达目标
if (this.distanceTraveled >= this.distanceToTarget) {
createParticles(this.tx, this.ty);
// 删除烟花,使用传递给更新函数的索引来确定要删除哪个
fireworks.splice(index, 1);
} else {
// 目标未到达,继续前进
this.x += vx;
this.y += vy;
}
}
// 画烟花
Firework.prototype.draw = function () {
ctxyi.beginPath();
//移动到集合中最后一个跟踪的坐标,然后画一条线到cunront vond v
ctxyi.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
ctxyi.lineTo(this.x, this.y);
ctxyi.strokeStyle = 'hsl(' + hue + ', 100%, ' + this.brightness + '%)';
ctxyi.stroke();
ctxyi.beginPath();
// 用一个跳动的圆圈画出这个烟花的目标
ctxyi.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2);
ctxyi.stroke();
}
// 创建粒子
function Particle(x, y) {
this.x = x;
this.y = y;
// 跟踪每个粒子的过去坐标来创建一个轨迹效果,增加坐标计数来创建更突出的轨迹
this.coordinates = [];
this.coordinateCount = 5;
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
// 以弧度为单位,在所有可能的方向上设置一个随机角度
this.angle = random(0, Math.PI * 2);
this.speed = random(1, 10);
// 摩擦会使粒子减速
this.friction = 0.95;
// 重力会将粒子向下拉
this.gravity = 1;
//将色调设置为整体色调变量的随机数+-20
this.hue = random(hue - 20, hue + 20);
this.brightness = random(50, 80);
this.alpha = 1;
// 设置粒子淡出的速度
this.decay = random(0.015, 0.03);
}
// 更新粒子
Particle.prototype.update = function (index) {
// 移除坐标数组中的最后一项
this.coordinates.pop();
// 将当前坐标添加到数组的开头
this.coordinates.unshift([this.x, this.y]);
// 使粒子减速
this.speed *= this.friction;
// 适用于速度
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed + this.gravity;
// 让粒子淡出
this.alpha -= this.decay;
// 根据传入的索引,在alpha足够低的时候移除粒子
if (this.alpha <= this.decay) {
particles.splice(index, 1);
}
}
// 得出粒子
Particle.prototype.draw = function () {
ctxyi.beginPath();
// 移动到集合中最后一个被跟踪的坐标,然后画一条到当前x和y的直线
ctxyi.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
ctxyi.lineTo(this.x, this.y);
ctxyi.strokeStyle = 'hsla(' + this.hue + ', 100%, ' + this.brightness + '%, ' + this.alpha + ')';
ctxyi.stroke();
}
// 创建粒子组/爆炸
function createParticles(x, y) {
// 增加粒子数更大的爆炸,小心帆布性能打击与增加粒子尽管
var particleCount = 30;
while (particleCount--) {
particles.push(new Particle(x, y));
}
}
// 主要演示循环
function loop() {
// 这个函数将无休止地运行requestAnimationFrame
requestAnimFrame(loop);
// 随着时间的推移,增加色调以获得不同颜色的烟花
hue += 0.5;
// 规则v. clearRect()将用于清除画布
// 我们想要创建一个拖尾效果
// 将复合操作设置为destination-out将允许我们以特定的不透明度清除画布,而不是完全擦拭它
ctxyi.globalCompositeOperation = 'destination-out';
// 减小alpha属性以创建更突出的轨迹
ctxyi.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctxyi.fillRect(0, 0, cw, ch);
// 将复合操作更改回主模式
// 打火机创造明亮的亮点,因为烟花和粒子相互重叠
ctxyi.globalCompositeOperation = 'lighter';
// 循环遍历每个烟花,绘制它,更新它
var i = fireworks.length;
while (i--) {
fireworks[i].draw();
fireworks[i].update(i);
}
// 循环遍历每个粒子,绘制它,更新它
var i = particles.length;
while (i--) {
particles[i].draw();
particles[i].update(i);
}
// 当鼠标不按下时,自动向随机坐标发射烟花
if (timerTick >= timerTotal) {
if (!mousedown) {
// 在屏幕底部中间开始放烟花,然后设置随机目标坐标,随机y坐标将在屏幕上半部分范围内设置
fireworks.push(new Firework(cw / 2, ch, random(0, cw), random(0, ch / 2)));
timerTick = 0;
}
} else {
timerTick++;
}
// 当鼠标按下时,限制烟花的发射速度
if (limiterTick >= limiterTotal) {
if (mousedown) {
// 在屏幕底部中间启动烟花,然后将当前鼠标坐标设置为目标
fireworks.push(new Firework(cw / 2, ch, mx, my));
limiterTick = 0;
}
} else {
limiterTick++;
}
}
// 鼠标事件绑定
// 取消鼠标移动上的鼠标坐标的日期
canvas.addEventListener('mousemove', function (e) {
mx = e.pageX - canvas.offsetLeft;
my = e.pageY - canvas.offsetTop;
});
// 切换鼠标按下状态并防止画布被选中
canvas.addEventListener('mousedown', function (e) {
e.preventDefault();
mousedown = true;
});
canvas.addEventListener('mouseup', function (e) {
e.preventDefault();
mousedown = false;
});
// 一旦窗户装好,我们就可以放烟花了!
window.onload = loop;
</script>
</html>
代码效果