【html】圣诞树

codepen

musical christmas lights

在这里插入图片描述

<!DOCTYPE HEML PUBLIC>
<html xmlns="http://www.w3.org/1999/html">
    <head>
    <meta charset="utf-8">
        <style>
            * {
                box-sizing: border-box;
            }

            body {
                margin: 0;
                height: 100vh;
                overflow: hidden;
                display: flex;
                align-items: center;
                justify-content: center;
                background: #161616;
                color: #c5a880;
                font-family: sans-serif;
            }

            label {
                display: inline-block;
                background-color: #161616;
                padding: 16px;
                border-radius: 0.3rem;
                cursor: pointer;
                margin-top: 1rem;
                width: 300px;
                border-radius: 10px;
                border: 1px solid #c5a880;
                text-align: center;
            }

            ul {
                list-style-type: none;
                padding: 0;
                margin: 0;
            }

            .btn {
                background-color: #161616;
                border-radius: 10px;
                color: #c5a880;
                border: 1px solid #c5a880;
                padding: 16px;
                width: 300px;
                margin-bottom: 16px;
                line-height: 1.5;
                cursor: pointer;
            }
            .separator {
                font-weight: bold;
                text-align: center;
                width: 300px;
                margin: 16px 0px;
                color: #a07676;
            }

            .title {
                color: #a07676;
                font-weight: bold;
                font-size: 1.25rem;
                margin-bottom: 16px;
            }

            .text-loading {
                font-size: 2rem;
            }

        </style>
    </head>
<body>

<script src="https://cdn.jsdelivr.net/npm/three@0.115.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/EffectComposer.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/RenderPass.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/ShaderPass.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/CopyShader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/UnrealBloomPass.js"></script>

<div id="overlay">
    <ul>
        <li class="title">Select Music</li>
        <li>
            <button class="btn" id="btnA" type="button">
                Snowflakes Falling Down by Simon Panrucker
            </button>
        </li>
        <li><button class="btn" id="btnB" type="button">This Christmas by Dott</button></li>
        <li><button class="btn" id="btnC" type="button">No room at the inn by TRG Banks</button></li>
        <li><button class="btn" id="btnD" type="button">Jingle Bell Swing by Mark Smeby</button></li>
        <li class="separator">OR</li>
        <li>
            <input type="file" id="upload" hidden />
            <label for="upload">Upload File</label>
        </li>
    </ul>
</div>

</body>
    <script>
        const { PI, sin, cos } = Math;
        const TAU = 2 * PI;

        const map = (value, sMin, sMax, dMin, dMax) => {
            return dMin + ((value - sMin) / (sMax - sMin)) * (dMax - dMin);
        };

        const range = (n, m = 0) =>
            Array(n)
                .fill(m)
                .map((i, j) => i + j);

        const rand = (max, min = 0) => min + Math.random() * (max - min);
        const randInt = (max, min = 0) => Math.floor(min + Math.random() * (max - min));
        const randChoise = (arr) => arr[randInt(arr.length)];
        const polar = (ang, r = 1) => [r * cos(ang), r * sin(ang)];

        let scene, camera, renderer, analyser;
        let step = 0;
        const uniforms = {
            time: { type: "f", value: 0.0 },
            step: { type: "f", value: 0.0 },
        };
        const params = {
            exposure: 1,
            bloomStrength: 0.9,
            bloomThreshold: 0,
            bloomRadius: 0.5,
        };
        let composer;

        const fftSize = 2048;
        const totalPoints = 4000;

        const listener = new THREE.AudioListener();

        const audio = new THREE.Audio(listener);

        document.querySelector("input").addEventListener("change", uploadAudio, false);

        const buttons = document.querySelectorAll(".btn");
        buttons.forEach((button, index) =>
            button.addEventListener("click", () => loadAudio(index))
        );

        function init() {
            const overlay = document.getElementById("overlay");
            overlay.remove();

            scene = new THREE.Scene();
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            camera = new THREE.PerspectiveCamera(
                60,
                window.innerWidth / window.innerHeight,
                1,
                1000
            );
            camera.position.set(-0.09397456774197047,-2.5597086635726947,24.420789670889008)
            camera.rotation.set(0.10443543723052419,-0.003827152981119352,0.0004011488708739715)

            const format = renderer.capabilities.isWebGL2
                ? THREE.RedFormat
                : THREE.LuminanceFormat;

            uniforms.tAudioData = {
                value: new THREE.DataTexture(analyser.data, fftSize / 2, 1, format),
            };

            addPlane(scene, uniforms, 3000);
            addSnow(scene, uniforms);

            range(10).map((i) => {
                addTree(scene, uniforms, totalPoints, [20, 0, -20 * i]);
                addTree(scene, uniforms, totalPoints, [-20, 0, -20 * i]);
            });

            const renderScene = new THREE.RenderPass(scene, camera);

            const bloomPass = new THREE.UnrealBloomPass(
                new THREE.Vector2(window.innerWidth, window.innerHeight),
                1.5,
                0.4,
                0.85
            );
            bloomPass.threshold = params.bloomThreshold;
            bloomPass.strength = params.bloomStrength;
            bloomPass.radius = params.bloomRadius;

            composer = new THREE.EffectComposer(renderer);
            composer.addPass(renderScene);
            composer.addPass(bloomPass);

            addListners(camera, renderer, composer);
            animate();
        }

        function animate(time) {
            analyser.getFrequencyData();
            uniforms.tAudioData.value.needsUpdate = true;
            step = (step + 1) % 1000;
            uniforms.time.value = time;
            uniforms.step.value = step;
            composer.render();
            requestAnimationFrame(animate);
        }

        function loadAudio(i) {
            document.getElementById("overlay").innerHTML =
                '<div class="text-loading">Please Wait...</div>';
            const files = [
                "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Simon_Panrucker/Happy_Christmas_You_Guys/Simon_Panrucker_-_01_-_Snowflakes_Falling_Down.mp3",
                "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Dott/This_Christmas/Dott_-_01_-_This_Christmas.mp3",
                "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/TRG_Banks/TRG_Banks_Christmas_Album/TRG_Banks_-_12_-_No_room_at_the_inn.mp3",
                "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/Mark_Smeby/En_attendant_Nol/Mark_Smeby_-_07_-_Jingle_Bell_Swing.mp3",
            ];
            const file = files[i];

            const loader = new THREE.AudioLoader();
            loader.load(file, function (buffer) {
                audio.setBuffer(buffer);
                audio.play();
                analyser = new THREE.AudioAnalyser(audio, fftSize);
                init();
            });




        }


        function uploadAudio(event) {
            document.getElementById("overlay").innerHTML =
                '<div class="text-loading">Please Wait...</div>';
            const files = event.target.files;
            const reader = new FileReader();

            reader.onload = function (file) {
                var arrayBuffer = file.target.result;

                listener.context.decodeAudioData(arrayBuffer, function (audioBuffer) {
                    audio.setBuffer(audioBuffer);
                    audio.play();
                    analyser = new THREE.AudioAnalyser(audio, fftSize);
                    init();
                });
            };

            reader.readAsArrayBuffer(files[0]);
        }

        function addTree(scene, uniforms, totalPoints, treePosition) {
            const vertexShader = `
  attribute float mIndex;
  varying vec3 vColor;
  varying float opacity;
  uniform sampler2D tAudioData;

  float norm(float value, float min, float max ){
      return (value - min) / (max - min);
  }
  float lerp(float norm, float min, float max){
  return (max - min) * norm + min;
  }

  float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
  return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
  }


  void main() {
      vColor = color;
      vec3 p = position;
      vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
      float amplitude = texture2D( tAudioData, vec2( mIndex, 0.1 ) ).r;
      float amplitudeClamped = clamp(amplitude-0.4,0.0, 0.6 );
      float sizeMapped = map(amplitudeClamped, 0.0, 0.6, 1.0, 20.0);
      opacity = map(mvPosition.z , -200.0, 15.0, 0.0, 1.0);
      gl_PointSize = sizeMapped * ( 100.0 / -mvPosition.z );
      gl_Position = projectionMatrix * mvPosition;
  }
`;
            const fragmentShader = `
  varying vec3 vColor;
  varying float opacity;
  uniform sampler2D pointTexture;
  void main() {
      gl_FragColor = vec4( vColor, opacity );
      gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
  }
  `;
            const shaderMaterial = new THREE.ShaderMaterial({
                uniforms: {
                    ...uniforms,
                    pointTexture: {
                        value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`),
                    },
                },
                vertexShader,
                fragmentShader,
                blending: THREE.AdditiveBlending,
                depthTest: false,
                transparent: true,
                vertexColors: true,
            });

            const geometry = new THREE.BufferGeometry();
            const positions = [];
            const colors = [];
            const sizes = [];
            const phases = [];
            const mIndexs = [];

            const color = new THREE.Color();

            for (let i = 0; i < totalPoints; i++) {
                const t = Math.random();
                const y = map(t, 0, 1, -8, 10);
                const ang = map(t, 0, 1, 0, 6 * TAU) + (TAU / 2) * (i % 2);
                const [z, x] = polar(ang, map(t, 0, 1, 5, 0));

                const modifier = map(t, 0, 1, 1, 0);
                positions.push(x + rand(-0.3 * modifier, 0.3 * modifier));
                positions.push(y + rand(-0.3 * modifier, 0.3 * modifier));
                positions.push(z + rand(-0.3 * modifier, 0.3 * modifier));

                color.setHSL(map(i, 0, totalPoints, 1.0, 0.0), 1.0, 0.5);

                colors.push(color.r, color.g, color.b);
                phases.push(rand(1000));
                sizes.push(1);
                const mIndex = map(i, 0, totalPoints, 1.0, 0.0);
                mIndexs.push(mIndex);
            }

            geometry.setAttribute(
                "position",
                new THREE.Float32BufferAttribute(positions, 3).setUsage(
                    THREE.DynamicDrawUsage
                )
            );
            geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
            geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
            geometry.setAttribute("phase", new THREE.Float32BufferAttribute(phases, 1));
            geometry.setAttribute("mIndex", new THREE.Float32BufferAttribute(mIndexs, 1));

            const tree = new THREE.Points(geometry, shaderMaterial);

            const [px, py, pz] = treePosition;

            tree.position.x = px;
            tree.position.y = py;
            tree.position.z = pz;

            scene.add(tree);
        }

        function addSnow(scene, uniforms) {
            const vertexShader = `
  attribute float size;
  attribute float phase;
  attribute float phaseSecondary;

  varying vec3 vColor;
  varying float opacity;


  uniform float time;
  uniform float step;

  float norm(float value, float min, float max ){
      return (value - min) / (max - min);
  }
  float lerp(float norm, float min, float max){
      return (max - min) * norm + min;
  }

  float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
      return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
  }
  void main() {
      float t = time* 0.0006;

      vColor = color;

      vec3 p = position;

      p.y = map(mod(phase+step, 1000.0), 0.0, 1000.0, 25.0, -8.0);

      p.x += sin(t+phase);
      p.z += sin(t+phaseSecondary);

      opacity = map(p.z, -150.0, 15.0, 0.0, 1.0);

      vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );

      gl_PointSize = size * ( 100.0 / -mvPosition.z );

      gl_Position = projectionMatrix * mvPosition;

  }
  `;

            const fragmentShader = `
  uniform sampler2D pointTexture;
  varying vec3 vColor;
  varying float opacity;

  void main() {
      gl_FragColor = vec4( vColor, opacity );
      gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
  }
  `;
            function createSnowSet(sprite) {
                const totalPoints = 300;
                const shaderMaterial = new THREE.ShaderMaterial({
                    uniforms: {
                        ...uniforms,
                        pointTexture: {
                            value: new THREE.TextureLoader().load(sprite),
                        },
                    },
                    vertexShader,
                    fragmentShader,
                    blending: THREE.AdditiveBlending,
                    depthTest: false,
                    transparent: true,
                    vertexColors: true,
                });

                const geometry = new THREE.BufferGeometry();
                const positions = [];
                const colors = [];
                const sizes = [];
                const phases = [];
                const phaseSecondaries = [];

                const color = new THREE.Color();

                for (let i = 0; i < totalPoints; i++) {
                    const [x, y, z] = [rand(25, -25), 0, rand(15, -150)];
                    positions.push(x);
                    positions.push(y);
                    positions.push(z);

                    color.set(randChoise(["#f1d4d4", "#f1f6f9", "#eeeeee", "#f1f1e8"]));

                    colors.push(color.r, color.g, color.b);
                    phases.push(rand(1000));
                    phaseSecondaries.push(rand(1000));
                    sizes.push(rand(4, 2));
                }

                geometry.setAttribute(
                    "position",
                    new THREE.Float32BufferAttribute(positions, 3)
                );
                geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
                geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
                geometry.setAttribute("phase", new THREE.Float32BufferAttribute(phases, 1));
                geometry.setAttribute(
                    "phaseSecondary",
                    new THREE.Float32BufferAttribute(phaseSecondaries, 1)
                );

                const mesh = new THREE.Points(geometry, shaderMaterial);

                scene.add(mesh);
            }
            const sprites = [
                "https://assets.codepen.io/3685267/snowflake1.png",
                "https://assets.codepen.io/3685267/snowflake2.png",
                "https://assets.codepen.io/3685267/snowflake3.png",
                "https://assets.codepen.io/3685267/snowflake4.png",
                "https://assets.codepen.io/3685267/snowflake5.png",
            ];
            sprites.forEach((sprite) => {
                createSnowSet(sprite);
            });
        }

        function addPlane(scene, uniforms, totalPoints) {
            const vertexShader = `
  attribute float size;
  attribute vec3 customColor;
  varying vec3 vColor;

  void main() {
      vColor = customColor;
      vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
      gl_PointSize = size * ( 300.0 / -mvPosition.z );
      gl_Position = projectionMatrix * mvPosition;

  }
  `;
            const fragmentShader = `
  uniform vec3 color;
  uniform sampler2D pointTexture;
  varying vec3 vColor;

  void main() {
      gl_FragColor = vec4( vColor, 1.0 );
      gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );

  }
  `;
            const shaderMaterial = new THREE.ShaderMaterial({
                uniforms: {
                    ...uniforms,
                    pointTexture: {
                        value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`),
                    },
                },
                vertexShader,
                fragmentShader,
                blending: THREE.AdditiveBlending,
                depthTest: false,
                transparent: true,
                vertexColors: true,
            });

            const geometry = new THREE.BufferGeometry();
            const positions = [];
            const colors = [];
            const sizes = [];

            const color = new THREE.Color();

            for (let i = 0; i < totalPoints; i++) {
                const [x, y, z] = [rand(-25, 25), 0, rand(-150, 15)];
                positions.push(x);
                positions.push(y);
                positions.push(z);

                color.set(randChoise(["#93abd3", "#f2f4c0", "#9ddfd3"]));

                colors.push(color.r, color.g, color.b);
                sizes.push(1);
            }

            geometry.setAttribute(
                "position",
                new THREE.Float32BufferAttribute(positions, 3).setUsage(
                    THREE.DynamicDrawUsage
                )
            );
            geometry.setAttribute(
                "customColor",
                new THREE.Float32BufferAttribute(colors, 3)
            );
            geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));

            const plane = new THREE.Points(geometry, shaderMaterial);

            plane.position.y = -8;
            scene.add(plane);
        }

        function addListners(camera, renderer, composer) {
            document.addEventListener("keydown", (e) => {
                const { x, y, z } = camera.position;
                console.log(`camera.position.set(${x},${y},${z})`);
                const { x: a, y: b, z: c } = camera.rotation;
                console.log(`camera.rotation.set(${a},${b},${c})`);
            });

            window.addEventListener(
                "resize",
                () => {
                    const width = window.innerWidth;
                    const height = window.innerHeight;

                    camera.aspect = width / height;
                    camera.updateProjectionMatrix();

                    renderer.setSize(width, height);
                    composer.setSize(width, height);
                },
                false
            );
        }


    </script>
</html>

样例一

在这里插入图片描述

<!DOCTYPE HEML PUBLIC>
<html>
    <head>
    <meta charset="utf-8">
        <style>
            html, body
            {
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
                border: 0;
            }
            
            div
            {
                margin: 0;
                padding: 0;
                border: 0;
            }
            .nav
            {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 27px;
                background-color: white;
                color: black;
                text-align: center;
                line-height: 25px;
            }
            a
            {
                color: black;
                text-decoration: none;
                border-bottom: 1px dashed black;
            }
            a:hover
            {
                border-bottom: 1px solid red;
            }
            .previous
            {
                float: left;
                margin-left: 10px;
            }
            .next
            {
                float: right;
                margin-right: 10px;
            }
            .green
            {
                color: green;
            }
            .red
            {
                color: red;
            }
            textarea
            {
                width: 100%;
                height: 100%;
                border: 0;                
                padding: 0;                
                margin: 0;                
                padding-bottom: 20px;              
            }            
            .block-outer            
            {                
                float: left;                
                width: 22%;                
                height: 100%;                
                padding: 5px;                
                border-left: 1px solid black;                
                margin: 30px 3px 3px 3px;                
            }            
            .block-inner            
            {                
                height: 68%;                
            }            
            .one            
            {                
                border: 0;                
            }
        </style>      
    </head>      
<body marginwidth="0" marginheight="0">
    <canvas id="c" height="356" width="446">
    <script>              
        var collapsed = true;            
        function toggle()            
        {                  
            var fs = top.document.getElementsByTagName('frameset')[0];                
            var f = fs.getElementsByTagName('frame');                
            if (collapsed)                
            {                      
                fs.rows = '250px,*';                    
                fs.noResize = false;                    
                f[0].noResize = false;                      
                f[1].noResize = false;
            }                 
            else
            {                      
                fs.rows = '30px,*';
                fs.noResize = true;
                f[0].noResize = true;
                f[1].noResize = true;
            }                  
            collapsed = !collapsed;            
        }
    </script>  
    <script>              
        var b = document.body;            
        var c = document.getElementsByTagName('canvas')[0];            
        var a = c.getContext('2d');            
        document.body.clientWidth;
    </script>  
    <script>
        M=Math;
        Q=M.random;J=[];
        U=16;
        T=M.sin;
        E=M.sqrt;
        for(O=k=0;x=z=j=i=k<200;)
        with(M[k]=k?c.cloneNode(0):c)
        {    
            width=height=k?32:W=446;        
            with(getContext('2d'))        
            if(k>10|!k)        
            for(        
            font='60px Impact',        
            V='rgba(';I=i*U,fillStyle=k?k==13?V+'205,205,215,.15)':        
            V+(147+I)+','+(k%2?128+I:0)+','+I+',.5)':'#cca',i<7;        
            )    
            beginPath(        
            fill(            
            arc(                
            U-i/3,                
            24-i/2,                
            k==13?4-(i++)/2:8-i++,                
            0,                
            M.PI*2,1                
            )            
            )            
            );
            else for(;
            x=T(i),        
            y=Q()*2-1,        
            D=x*x+y*y,        
            B=E(D-x/.9-1.5*y+1),        
            R=67*(B+1)*(L=k/9+.8)>>1,        
            i++<W;        
            )
            if(D<1)    
            beginPath(        
            strokeStyle=V+R+','+(R+B*L>>0)+',40,.1)'        
            ),        
            moveTo(U+x*8,U+y*8),        
            lineTo(U+x*U,U+y*U),        
            stroke();
            for(        
            y=H=k+E(k++)*25,        
            R=Q()*W;        
            P=3,j<H;        
            )    
            J[O++]=[x+=T(R)*P+Q()*6-3,y+=Q()*U-8,z+=T(R-11)*P+Q()*6-3,j/H*20+((j+=U)>H&Q()>.8?Q(P=9)*4:0)>>1]
        }
        setInterval(function G(m,l)
        {    
            A=T(D-11);    
            if(l)
            return(        
            m[2]-l[2])*A+(l[0]-m[0])*T(D);        
            a.clearRect(0,0,W,W);        
            J.sort(G);
            for(        
            i=0;        
            L=J[i++];        
            a.drawImage        
            (            
            M[L[3]+1],207+L[0]*A+L[2]*T(D)>>0,L[1]>>1)    )    
            {        
                if(i==2e3)        
                a.fillText        
                (            
                'Happy Christmas!',            
                U,345);
                if(!(i%7))        
                a.drawImage        
                (
                M[13],
                ((157*(i*i)+T(D*5+i*i)*5)%W)>>0,
                ((113*i+(D*i)/60)%(290+i/99))>>0
                );
            }    
            D+=.02
        },1)
    </script>
</body>
</html>

样例二

在这里插入图片描述

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<title>html5写的3D逼真圣诞树效果</title>
<meta charset="utf-8" >
<style>
body {
  margin: 0;
  background-image: url("http://all4desktop.com/data_images/1280%20x%20800/4227335-waiting-for-the-xmas.jpg");
  background-color: #111;
  background-position: 50% 50%;
  background-size: cover;


 
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
}

.txt {
  color: #fff;
  font-family: "Oleo Script", sans-serif;
  width: 100%;
  height: 10vw;
  overflow: hidden;
  position: relative;
  text-shadow: 0.5vw 0.5vw 0px #000;
}

p {
  font-size: 7.2vw;
  line-height: 10vw;
  position: absolute;
  margin: 0;
  text-align: center;
  width: 100%;
  transform: translateY(10vw);
  animation: slideUp 14s 0s linear infinite;
}
p.reset-anim {
  animation: none;
}
p:nth-of-type(1) {
  animation-delay: 0s;
}
p:nth-of-type(2) {
  animation-delay: 2s;
}
p:nth-of-type(3) {
  animation-delay: 4s;
}
p:nth-of-type(4) {
  animation-delay: 6s;
}
p:nth-of-type(5) {
  animation-delay: 8s;
}
p:nth-of-type(6) {
  animation-delay: 10s;
}
p:nth-of-type(7) {
  animation-delay: 12s;
}

@keyframes slideUp {
  from {
    transform: translateY(100%);
  }
  7.1428571429%, 14.2857142857% {
    transform: translateY(0);
  }
  21.4285714286%, to {
    transform: translateY(-100%);
  }
}
.snow {
  position: relative;
  width: 100vw;
  height: 100vh;
}

.snow__item {
  position: absolute;
  width: 5px;
  height: 5px;
  margin: auto;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border-radius: 50%;
  -webkit-animation: snow 10000ms linear infinite;
          animation: snow 10000ms linear infinite;
}
.snow__item:nth-child(2) {
  left: 25vw;
  -webkit-animation-delay: 6666ms;
          animation-delay: 6666ms;
}
.snow__item:nth-child(3) {
  right: 25vw;
  -webkit-animation-delay: 3333ms;
          animation-delay: 3333ms;
}
@-webkit-keyframes snow {
  0% {
    -webkit-box-shadow: 0 0 0 transparent, 56vw -76vh 8px 2px #fff, -71vw -96vh 4px 4px #fff, 20vw -142vh 8px 1px #fff, -18vw -80vh 2px 4px #fff, 86vw -124vh 7px 2px #fff, -25vw -69vh 8px 1px #fff, 43vw -117vh 4px 4px #fff, -23vw -60vh 7px 3px #fff, 56vw -78vh 1px 5px #fff, -6vw -123vh 1px 5px #fff, 40vw -69vh 6px 5px #fff, -60vw -50vh 2px 5px #fff, 86vw -137vh 8px 4px #fff, -47vw -139vh 1px 5px #fff, 71vw -122vh 4px 2px #fff, -71vw -100vh 6px 4px #fff, 17vw -106vh 7px 4px #fff, -36vw -137vh 4px 1px #fff, 55vw -67vh 5px 5px #fff, -56vw -53vh 8px 1px #fff, 88vw -130vh 7px 5px #fff, -55vw -110vh 2px 1px #fff, 72vw -83vh 5px 5px #fff, -59vw -69vh 6px 3px #fff, 31vw -87vh 1px 4px #fff, -4vw -85vh 1px 3px #fff, 62vw -108vh 1px 3px #fff, -16vw -146vh 2px 3px #fff, 23vw -108vh 6px 1px #fff, -5vw -65vh 6px 5px #fff, 87vw -103vh 7px 4px #fff, -45vw -110vh 4px 4px #fff, 94vw -106vh 1px 5px #fff, -20vw -115vh 8px 1px #fff, 48vw -58vh 3px 1px #fff, -66vw -83vh 6px 5px #fff, 19vw -68vh 6px 3px #fff, -45vw -65vh 1px 2px #fff, 59vw -139vh 3px 1px #fff, -60vw -94vh 6px 2px #fff, 65vw -134vh 5px 2px #fff, -8vw -51vh 3px 5px #fff, 69vw -144vh 2px 2px #fff, -71vw -120vh 5px 5px #fff, 2vw -76vh 4px 2px #fff, -49vw -96vh 2px 2px #fff, 47vw -148vh 1px 2px #fff, -80vw -140vh 4px 1px #fff, 90vw -127vh 5px 5px #fff, -40vw -53vh 1px 5px #fff, 29vw -142vh 5px 1px #fff, -87vw -97vh 6px 1px #fff, 92vw -124vh 7px 4px #fff, -7vw -127vh 3px 5px #fff, 47vw -87vh 1px 1px #fff, -15vw -104vh 7px 4px #fff, 28vw -119vh 3px 3px #fff, -97vw -58vh 7px 5px #fff, 86vw -120vh 8px 4px #fff, -35vw -140vh 7px 3px #fff, 20vw -75vh 5px 3px #fff, -22vw -73vh 7px 3px #fff, 50vw -59vh 1px 5px #fff, -5vw -134vh 5px 3px #fff, 65vw -59vh 2px 1px #fff, -8vw -53vh 1px 2px #fff, 87vw -116vh 3px 5px #fff, -39vw -133vh 5px 5px #fff, 93vw -99vh 2px 1px #fff, -21vw -135vh 2px 3px #fff, 3vw -56vh 8px 2px #fff, -30vw -100vh 5px 3px #fff, 77vw -110vh 1px 4px #fff, -98vw -124vh 4px 1px #fff, 82vw -106vh 4px 2px #fff, -19vw -126vh 6px 4px #fff, 98vw -122vh 2px 1px #fff, -16vw -93vh 2px 4px #fff, 75vw -70vh 7px 4px #fff, -15vw -112vh 1px 4px #fff, 21vw -136vh 7px 5px #fff, -96vw -131vh 8px 5px #fff, 14vw -105vh 2px 5px #fff, -96vw -149vh 1px 4px #fff, 41vw -141vh 5px 4px #fff, -22vw -104vh 5px 2px #fff, 31vw -72vh 8px 1px #fff, -86vw -65vh 7px 4px #fff, 88vw -77vh 2px 3px #fff, -84vw -96vh 6px 3px #fff, 63vw -86vh 6px 5px #fff, -33vw -69vh 5px 5px #fff, 69vw -108vh 2px 3px #fff, -75vw -132vh 6px 5px #fff, 40vw -140vh 7px 2px #fff, -34vw -134vh 4px 1px #fff, 63vw -114vh 8px 4px #fff, -12vw -101vh 8px 3px #fff, 11vw -75vh 3px 5px #fff, -61vw -73vh 8px 2px #fff;
            box-shadow: 0 0 0 transparent, 56vw -76vh 8px 2px #fff, -71vw -96vh 4px 4px #fff, 20vw -142vh 8px 1px #fff, -18vw -80vh 2px 4px #fff, 86vw -124vh 7px 2px #fff, -25vw -69vh 8px 1px #fff, 43vw -117vh 4px 4px #fff, -23vw -60vh 7px 3px #fff, 56vw -78vh 1px 5px #fff, -6vw -123vh 1px 5px #fff, 40vw -69vh 6px 5px #fff, -60vw -50vh 2px 5px #fff, 86vw -137vh 8px 4px #fff, -47vw -139vh 1px 5px #fff, 71vw -122vh 4px 2px #fff, -71vw -100vh 6px 4px #fff, 17vw -106vh 7px 4px #fff, -36vw -137vh 4px 1px #fff, 55vw -67vh 5px 5px #fff, -56vw -53vh 8px 1px #fff, 88vw -130vh 7px 5px #fff, -55vw -110vh 2px 1px #fff, 72vw -83vh 5px 5px #fff, -59vw -69vh 6px 3px #fff, 31vw -87vh 1px 4px #fff, -4vw -85vh 1px 3px #fff, 62vw -108vh 1px 3px #fff, -16vw -146vh 2px 3px #fff, 23vw -108vh 6px 1px #fff, -5vw -65vh 6px 5px #fff, 87vw -103vh 7px 4px #fff, -45vw -110vh 4px 4px #fff, 94vw -106vh 1px 5px #fff, -20vw -115vh 8px 1px #fff, 48vw -58vh 3px 1px #fff, -66vw -83vh 6px 5px #fff, 19vw -68vh 6px 3px #fff, -45vw -65vh 1px 2px #fff, 59vw -139vh 3px 1px #fff, -60vw -94vh 6px 2px #fff, 65vw -134vh 5px 2px #fff, -8vw -51vh 3px 5px #fff, 69vw -144vh 2px 2px #fff, -71vw -120vh 5px 5px #fff, 2vw -76vh 4px 2px #fff, -49vw -96vh 2px 2px #fff, 47vw -148vh 1px 2px #fff, -80vw -140vh 4px 1px #fff, 90vw -127vh 5px 5px #fff, -40vw -53vh 1px 5px #fff, 29vw -142vh 5px 1px #fff, -87vw -97vh 6px 1px #fff, 92vw -124vh 7px 4px #fff, -7vw -127vh 3px 5px #fff, 47vw -87vh 1px 1px #fff, -15vw -104vh 7px 4px #fff, 28vw -119vh 3px 3px #fff, -97vw -58vh 7px 5px #fff, 86vw -120vh 8px 4px #fff, -35vw -140vh 7px 3px #fff, 20vw -75vh 5px 3px #fff, -22vw -73vh 7px 3px #fff, 50vw -59vh 1px 5px #fff, -5vw -134vh 5px 3px #fff, 65vw -59vh 2px 1px #fff, -8vw -53vh 1px 2px #fff, 87vw -116vh 3px 5px #fff, -39vw -133vh 5px 5px #fff, 93vw -99vh 2px 1px #fff, -21vw -135vh 2px 3px #fff, 3vw -56vh 8px 2px #fff, -30vw -100vh 5px 3px #fff, 77vw -110vh 1px 4px #fff, -98vw -124vh 4px 1px #fff, 82vw -106vh 4px 2px #fff, -19vw -126vh 6px 4px #fff, 98vw -122vh 2px 1px #fff, -16vw -93vh 2px 4px #fff, 75vw -70vh 7px 4px #fff, -15vw -112vh 1px 4px #fff, 21vw -136vh 7px 5px #fff, -96vw -131vh 8px 5px #fff, 14vw -105vh 2px 5px #fff, -96vw -149vh 1px 4px #fff, 41vw -141vh 5px 4px #fff, -22vw -104vh 5px 2px #fff, 31vw -72vh 8px 1px #fff, -86vw -65vh 7px 4px #fff, 88vw -77vh 2px 3px #fff, -84vw -96vh 6px 3px #fff, 63vw -86vh 6px 5px #fff, -33vw -69vh 5px 5px #fff, 69vw -108vh 2px 3px #fff, -75vw -132vh 6px 5px #fff, 40vw -140vh 7px 2px #fff, -34vw -134vh 4px 1px #fff, 63vw -114vh 8px 4px #fff, -12vw -101vh 8px 3px #fff, 11vw -75vh 3px 5px #fff, -61vw -73vh 8px 2px #fff;
  }
  100% {
    -webkit-box-shadow: 0 0 0 transparent, 58vw 95vh 1px 2px #fff, -74vw 137vh 2px 4px #fff, 56vw 147vh 2px 1px #fff, -55vw 96vh 7px 4px #fff, 23vw 127vh 7px 1px #fff, -58vw 134vh 1px 2px #fff, 62vw 137vh 2px 3px #fff, -59vw 123vh 1px 4px #fff, 35vw 149vh 3px 2px #fff, -74vw 58vh 5px 1px #fff, 78vw 95vh 4px 4px #fff, -25vw 134vh 6px 1px #fff, 19vw 79vh 4px 5px #fff, -3vw 67vh 4px 5px #fff, 5vw 123vh 7px 5px #fff, -51vw 139vh 4px 3px #fff, 5vw 142vh 8px 1px #fff, -73vw 109vh 8px 2px #fff, 44vw 148vh 6px 1px #fff, -32vw 137vh 2px 1px #fff, 6vw 150vh 1px 2px #fff, -16vw 80vh 1px 3px #fff, 61vw 57vh 8px 2px #fff, -73vw 110vh 1px 3px #fff, 50vw 95vh 5px 2px #fff, -26vw 80vh 2px 5px #fff, 23vw 134vh 2px 5px #fff, -1vw 134vh 6px 2px #fff, 40vw 58vh 8px 3px #fff, -45vw 61vh 8px 4px #fff, 73vw 120vh 6px 1px #fff, -85vw 65vh 6px 3px #fff, 5vw 111vh 8px 5px #fff, -2vw 150vh 4px 2px #fff, 78vw 64vh 4px 5px #fff, -64vw 129vh 1px 3px #fff, 67vw 85vh 4px 3px #fff, -9vw 59vh 2px 4px #fff, 71vw 57vh 3px 4px #fff, -28vw 86vh 8px 5px #fff, 84vw 95vh 8px 4px #fff, -80vw 52vh 4px 3px #fff, 94vw 147vh 7px 4px #fff, -20vw 75vh 5px 5px #fff, 63vw 80vh 8px 4px #fff, -7vw 100vh 1px 4px #fff, 67vw 61vh 4px 1px #fff, -88vw 59vh 8px 2px #fff, 67vw 98vh 3px 2px #fff, -19vw 142vh 3px 1px #fff, 86vw 75vh 5px 4px #fff, -57vw 131vh 4px 3px #fff, 13vw 102vh 6px 3px #fff, -65vw 136vh 4px 1px #fff, 70vw 86vh 1px 1px #fff, -22vw 103vh 5px 1px #fff, 59vw 123vh 6px 1px #fff, -70vw 57vh 7px 5px #fff, 1vw 113vh 1px 4px #fff, -1vw 55vh 1px 2px #fff, 34vw 77vh 5px 2px #fff, -63vw 100vh 2px 1px #fff, 30vw 92vh 2px 1px #fff, -71vw 150vh 3px 1px #fff, 38vw 105vh 3px 2px #fff, -38vw 115vh 1px 1px #fff, 27vw 128vh 7px 4px #fff, -13vw 74vh 4px 2px #fff, 77vw 150vh 6px 3px #fff, -76vw 120vh 1px 1px #fff, 78vw 62vh 5px 2px #fff, -44vw 55vh 1px 2px #fff, 95vw 98vh 6px 2px #fff, -83vw 65vh 5px 5px #fff, 51vw 117vh 6px 4px #fff, -41vw 148vh 4px 3px #fff, 92vw 65vh 8px 2px #fff, -68vw 70vh 3px 2px #fff, 18vw 96vh 3px 3px #fff, -89vw 101vh 8px 5px #fff, 71vw 129vh 2px 3px #fff, -54vw 77vh 1px 2px #fff, 23vw 72vh 3px 1px #fff, -60vw 92vh 4px 2px #fff, 7vw 104vh 1px 3px #fff, -12vw 123vh 2px 4px #fff, 42vw 53vh 5px 2px #fff, -15vw 103vh 1px 5px #fff, 94vw 110vh 2px 3px #fff, -24vw 116vh 6px 1px #fff, 42vw 65vh 3px 3px #fff, -61vw 67vh 5px 4px #fff, 94vw 138vh 1px 3px #fff, -8vw 108vh 4px 2px #fff, 57vw 87vh 8px 4px #fff, -15vw 84vh 3px 3px #fff, 9vw 82vh 6px 2px #fff, -88vw 94vh 2px 3px #fff, 24vw 81vh 6px 3px #fff, -40vw 101vh 8px 3px #fff;
            box-shadow: 0 0 0 transparent, 58vw 95vh 1px 2px #fff, -74vw 137vh 2px 4px #fff, 56vw 147vh 2px 1px #fff, -55vw 96vh 7px 4px #fff, 23vw 127vh 7px 1px #fff, -58vw 134vh 1px 2px #fff, 62vw 137vh 2px 3px #fff, -59vw 123vh 1px 4px #fff, 35vw 149vh 3px 2px #fff, -74vw 58vh 5px 1px #fff, 78vw 95vh 4px 4px #fff, -25vw 134vh 6px 1px #fff, 19vw 79vh 4px 5px #fff, -3vw 67vh 4px 5px #fff, 5vw 123vh 7px 5px #fff, -51vw 139vh 4px 3px #fff, 5vw 142vh 8px 1px #fff, -73vw 109vh 8px 2px #fff, 44vw 148vh 6px 1px #fff, -32vw 137vh 2px 1px #fff, 6vw 150vh 1px 2px #fff, -16vw 80vh 1px 3px #fff, 61vw 57vh 8px 2px #fff, -73vw 110vh 1px 3px #fff, 50vw 95vh 5px 2px #fff, -26vw 80vh 2px 5px #fff, 23vw 134vh 2px 5px #fff, -1vw 134vh 6px 2px #fff, 40vw 58vh 8px 3px #fff, -45vw 61vh 8px 4px #fff, 73vw 120vh 6px 1px #fff, -85vw 65vh 6px 3px #fff, 5vw 111vh 8px 5px #fff, -2vw 150vh 4px 2px #fff, 78vw 64vh 4px 5px #fff, -64vw 129vh 1px 3px #fff, 67vw 85vh 4px 3px #fff, -9vw 59vh 2px 4px #fff, 71vw 57vh 3px 4px #fff, -28vw 86vh 8px 5px #fff, 84vw 95vh 8px 4px #fff, -80vw 52vh 4px 3px #fff, 94vw 147vh 7px 4px #fff, -20vw 75vh 5px 5px #fff, 63vw 80vh 8px 4px #fff, -7vw 100vh 1px 4px #fff, 67vw 61vh 4px 1px #fff, -88vw 59vh 8px 2px #fff, 67vw 98vh 3px 2px #fff, -19vw 142vh 3px 1px #fff, 86vw 75vh 5px 4px #fff, -57vw 131vh 4px 3px #fff, 13vw 102vh 6px 3px #fff, -65vw 136vh 4px 1px #fff, 70vw 86vh 1px 1px #fff, -22vw 103vh 5px 1px #fff, 59vw 123vh 6px 1px #fff, -70vw 57vh 7px 5px #fff, 1vw 113vh 1px 4px #fff, -1vw 55vh 1px 2px #fff, 34vw 77vh 5px 2px #fff, -63vw 100vh 2px 1px #fff, 30vw 92vh 2px 1px #fff, -71vw 150vh 3px 1px #fff, 38vw 105vh 3px 2px #fff, -38vw 115vh 1px 1px #fff, 27vw 128vh 7px 4px #fff, -13vw 74vh 4px 2px #fff, 77vw 150vh 6px 3px #fff, -76vw 120vh 1px 1px #fff, 78vw 62vh 5px 2px #fff, -44vw 55vh 1px 2px #fff, 95vw 98vh 6px 2px #fff, -83vw 65vh 5px 5px #fff, 51vw 117vh 6px 4px #fff, -41vw 148vh 4px 3px #fff, 92vw 65vh 8px 2px #fff, -68vw 70vh 3px 2px #fff, 18vw 96vh 3px 3px #fff, -89vw 101vh 8px 5px #fff, 71vw 129vh 2px 3px #fff, -54vw 77vh 1px 2px #fff, 23vw 72vh 3px 1px #fff, -60vw 92vh 4px 2px #fff, 7vw 104vh 1px 3px #fff, -12vw 123vh 2px 4px #fff, 42vw 53vh 5px 2px #fff, -15vw 103vh 1px 5px #fff, 94vw 110vh 2px 3px #fff, -24vw 116vh 6px 1px #fff, 42vw 65vh 3px 3px #fff, -61vw 67vh 5px 4px #fff, 94vw 138vh 1px 3px #fff, -8vw 108vh 4px 2px #fff, 57vw 87vh 8px 4px #fff, -15vw 84vh 3px 3px #fff, 9vw 82vh 6px 2px #fff, -88vw 94vh 2px 3px #fff, 24vw 81vh 6px 3px #fff, -40vw 101vh 8px 3px #fff;
  }
}
@keyframes snow {
  0% {
    -webkit-box-shadow: 0 0 0 transparent, 56vw -76vh 8px 2px #fff, -71vw -96vh 4px 4px #fff, 20vw -142vh 8px 1px #fff, -18vw -80vh 2px 4px #fff, 86vw -124vh 7px 2px #fff, -25vw -69vh 8px 1px #fff, 43vw -117vh 4px 4px #fff, -23vw -60vh 7px 3px #fff, 56vw -78vh 1px 5px #fff, -6vw -123vh 1px 5px #fff, 40vw -69vh 6px 5px #fff, -60vw -50vh 2px 5px #fff, 86vw -137vh 8px 4px #fff, -47vw -139vh 1px 5px #fff, 71vw -122vh 4px 2px #fff, -71vw -100vh 6px 4px #fff, 17vw -106vh 7px 4px #fff, -36vw -137vh 4px 1px #fff, 55vw -67vh 5px 5px #fff, -56vw -53vh 8px 1px #fff, 88vw -130vh 7px 5px #fff, -55vw -110vh 2px 1px #fff, 72vw -83vh 5px 5px #fff, -59vw -69vh 6px 3px #fff, 31vw -87vh 1px 4px #fff, -4vw -85vh 1px 3px #fff, 62vw -108vh 1px 3px #fff, -16vw -146vh 2px 3px #fff, 23vw -108vh 6px 1px #fff, -5vw -65vh 6px 5px #fff, 87vw -103vh 7px 4px #fff, -45vw -110vh 4px 4px #fff, 94vw -106vh 1px 5px #fff, -20vw -115vh 8px 1px #fff, 48vw -58vh 3px 1px #fff, -66vw -83vh 6px 5px #fff, 19vw -68vh 6px 3px #fff, -45vw -65vh 1px 2px #fff, 59vw -139vh 3px 1px #fff, -60vw -94vh 6px 2px #fff, 65vw -134vh 5px 2px #fff, -8vw -51vh 3px 5px #fff, 69vw -144vh 2px 2px #fff, -71vw -120vh 5px 5px #fff, 2vw -76vh 4px 2px #fff, -49vw -96vh 2px 2px #fff, 47vw -148vh 1px 2px #fff, -80vw -140vh 4px 1px #fff, 90vw -127vh 5px 5px #fff, -40vw -53vh 1px 5px #fff, 29vw -142vh 5px 1px #fff, -87vw -97vh 6px 1px #fff, 92vw -124vh 7px 4px #fff, -7vw -127vh 3px 5px #fff, 47vw -87vh 1px 1px #fff, -15vw -104vh 7px 4px #fff, 28vw -119vh 3px 3px #fff, -97vw -58vh 7px 5px #fff, 86vw -120vh 8px 4px #fff, -35vw -140vh 7px 3px #fff, 20vw -75vh 5px 3px #fff, -22vw -73vh 7px 3px #fff, 50vw -59vh 1px 5px #fff, -5vw -134vh 5px 3px #fff, 65vw -59vh 2px 1px #fff, -8vw -53vh 1px 2px #fff, 87vw -116vh 3px 5px #fff, -39vw -133vh 5px 5px #fff, 93vw -99vh 2px 1px #fff, -21vw -135vh 2px 3px #fff, 3vw -56vh 8px 2px #fff, -30vw -100vh 5px 3px #fff, 77vw -110vh 1px 4px #fff, -98vw -124vh 4px 1px #fff, 82vw -106vh 4px 2px #fff, -19vw -126vh 6px 4px #fff, 98vw -122vh 2px 1px #fff, -16vw -93vh 2px 4px #fff, 75vw -70vh 7px 4px #fff, -15vw -112vh 1px 4px #fff, 21vw -136vh 7px 5px #fff, -96vw -131vh 8px 5px #fff, 14vw -105vh 2px 5px #fff, -96vw -149vh 1px 4px #fff, 41vw -141vh 5px 4px #fff, -22vw -104vh 5px 2px #fff, 31vw -72vh 8px 1px #fff, -86vw -65vh 7px 4px #fff, 88vw -77vh 2px 3px #fff, -84vw -96vh 6px 3px #fff, 63vw -86vh 6px 5px #fff, -33vw -69vh 5px 5px #fff, 69vw -108vh 2px 3px #fff, -75vw -132vh 6px 5px #fff, 40vw -140vh 7px 2px #fff, -34vw -134vh 4px 1px #fff, 63vw -114vh 8px 4px #fff, -12vw -101vh 8px 3px #fff, 11vw -75vh 3px 5px #fff, -61vw -73vh 8px 2px #fff;
            box-shadow: 0 0 0 transparent, 56vw -76vh 8px 2px #fff, -71vw -96vh 4px 4px #fff, 20vw -142vh 8px 1px #fff, -18vw -80vh 2px 4px #fff, 86vw -124vh 7px 2px #fff, -25vw -69vh 8px 1px #fff, 43vw -117vh 4px 4px #fff, -23vw -60vh 7px 3px #fff, 56vw -78vh 1px 5px #fff, -6vw -123vh 1px 5px #fff, 40vw -69vh 6px 5px #fff, -60vw -50vh 2px 5px #fff, 86vw -137vh 8px 4px #fff, -47vw -139vh 1px 5px #fff, 71vw -122vh 4px 2px #fff, -71vw -100vh 6px 4px #fff, 17vw -106vh 7px 4px #fff, -36vw -137vh 4px 1px #fff, 55vw -67vh 5px 5px #fff, -56vw -53vh 8px 1px #fff, 88vw -130vh 7px 5px #fff, -55vw -110vh 2px 1px #fff, 72vw -83vh 5px 5px #fff, -59vw -69vh 6px 3px #fff, 31vw -87vh 1px 4px #fff, -4vw -85vh 1px 3px #fff, 62vw -108vh 1px 3px #fff, -16vw -146vh 2px 3px #fff, 23vw -108vh 6px 1px #fff, -5vw -65vh 6px 5px #fff, 87vw -103vh 7px 4px #fff, -45vw -110vh 4px 4px #fff, 94vw -106vh 1px 5px #fff, -20vw -115vh 8px 1px #fff, 48vw -58vh 3px 1px #fff, -66vw -83vh 6px 5px #fff, 19vw -68vh 6px 3px #fff, -45vw -65vh 1px 2px #fff, 59vw -139vh 3px 1px #fff, -60vw -94vh 6px 2px #fff, 65vw -134vh 5px 2px #fff, -8vw -51vh 3px 5px #fff, 69vw -144vh 2px 2px #fff, -71vw -120vh 5px 5px #fff, 2vw -76vh 4px 2px #fff, -49vw -96vh 2px 2px #fff, 47vw -148vh 1px 2px #fff, -80vw -140vh 4px 1px #fff, 90vw -127vh 5px 5px #fff, -40vw -53vh 1px 5px #fff, 29vw -142vh 5px 1px #fff, -87vw -97vh 6px 1px #fff, 92vw -124vh 7px 4px #fff, -7vw -127vh 3px 5px #fff, 47vw -87vh 1px 1px #fff, -15vw -104vh 7px 4px #fff, 28vw -119vh 3px 3px #fff, -97vw -58vh 7px 5px #fff, 86vw -120vh 8px 4px #fff, -35vw -140vh 7px 3px #fff, 20vw -75vh 5px 3px #fff, -22vw -73vh 7px 3px #fff, 50vw -59vh 1px 5px #fff, -5vw -134vh 5px 3px #fff, 65vw -59vh 2px 1px #fff, -8vw -53vh 1px 2px #fff, 87vw -116vh 3px 5px #fff, -39vw -133vh 5px 5px #fff, 93vw -99vh 2px 1px #fff, -21vw -135vh 2px 3px #fff, 3vw -56vh 8px 2px #fff, -30vw -100vh 5px 3px #fff, 77vw -110vh 1px 4px #fff, -98vw -124vh 4px 1px #fff, 82vw -106vh 4px 2px #fff, -19vw -126vh 6px 4px #fff, 98vw -122vh 2px 1px #fff, -16vw -93vh 2px 4px #fff, 75vw -70vh 7px 4px #fff, -15vw -112vh 1px 4px #fff, 21vw -136vh 7px 5px #fff, -96vw -131vh 8px 5px #fff, 14vw -105vh 2px 5px #fff, -96vw -149vh 1px 4px #fff, 41vw -141vh 5px 4px #fff, -22vw -104vh 5px 2px #fff, 31vw -72vh 8px 1px #fff, -86vw -65vh 7px 4px #fff, 88vw -77vh 2px 3px #fff, -84vw -96vh 6px 3px #fff, 63vw -86vh 6px 5px #fff, -33vw -69vh 5px 5px #fff, 69vw -108vh 2px 3px #fff, -75vw -132vh 6px 5px #fff, 40vw -140vh 7px 2px #fff, -34vw -134vh 4px 1px #fff, 63vw -114vh 8px 4px #fff, -12vw -101vh 8px 3px #fff, 11vw -75vh 3px 5px #fff, -61vw -73vh 8px 2px #fff;
  }
  100% {
    -webkit-box-shadow: 0 0 0 transparent, 58vw 95vh 1px 2px #fff, -74vw 137vh 2px 4px #fff, 56vw 147vh 2px 1px #fff, -55vw 96vh 7px 4px #fff, 23vw 127vh 7px 1px #fff, -58vw 134vh 1px 2px #fff, 62vw 137vh 2px 3px #fff, -59vw 123vh 1px 4px #fff, 35vw 149vh 3px 2px #fff, -74vw 58vh 5px 1px #fff, 78vw 95vh 4px 4px #fff, -25vw 134vh 6px 1px #fff, 19vw 79vh 4px 5px #fff, -3vw 67vh 4px 5px #fff, 5vw 123vh 7px 5px #fff, -51vw 139vh 4px 3px #fff, 5vw 142vh 8px 1px #fff, -73vw 109vh 8px 2px #fff, 44vw 148vh 6px 1px #fff, -32vw 137vh 2px 1px #fff, 6vw 150vh 1px 2px #fff, -16vw 80vh 1px 3px #fff, 61vw 57vh 8px 2px #fff, -73vw 110vh 1px 3px #fff, 50vw 95vh 5px 2px #fff, -26vw 80vh 2px 5px #fff, 23vw 134vh 2px 5px #fff, -1vw 134vh 6px 2px #fff, 40vw 58vh 8px 3px #fff, -45vw 61vh 8px 4px #fff, 73vw 120vh 6px 1px #fff, -85vw 65vh 6px 3px #fff, 5vw 111vh 8px 5px #fff, -2vw 150vh 4px 2px #fff, 78vw 64vh 4px 5px #fff, -64vw 129vh 1px 3px #fff, 67vw 85vh 4px 3px #fff, -9vw 59vh 2px 4px #fff, 71vw 57vh 3px 4px #fff, -28vw 86vh 8px 5px #fff, 84vw 95vh 8px 4px #fff, -80vw 52vh 4px 3px #fff, 94vw 147vh 7px 4px #fff, -20vw 75vh 5px 5px #fff, 63vw 80vh 8px 4px #fff, -7vw 100vh 1px 4px #fff, 67vw 61vh 4px 1px #fff, -88vw 59vh 8px 2px #fff, 67vw 98vh 3px 2px #fff, -19vw 142vh 3px 1px #fff, 86vw 75vh 5px 4px #fff, -57vw 131vh 4px 3px #fff, 13vw 102vh 6px 3px #fff, -65vw 136vh 4px 1px #fff, 70vw 86vh 1px 1px #fff, -22vw 103vh 5px 1px #fff, 59vw 123vh 6px 1px #fff, -70vw 57vh 7px 5px #fff, 1vw 113vh 1px 4px #fff, -1vw 55vh 1px 2px #fff, 34vw 77vh 5px 2px #fff, -63vw 100vh 2px 1px #fff, 30vw 92vh 2px 1px #fff, -71vw 150vh 3px 1px #fff, 38vw 105vh 3px 2px #fff, -38vw 115vh 1px 1px #fff, 27vw 128vh 7px 4px #fff, -13vw 74vh 4px 2px #fff, 77vw 150vh 6px 3px #fff, -76vw 120vh 1px 1px #fff, 78vw 62vh 5px 2px #fff, -44vw 55vh 1px 2px #fff, 95vw 98vh 6px 2px #fff, -83vw 65vh 5px 5px #fff, 51vw 117vh 6px 4px #fff, -41vw 148vh 4px 3px #fff, 92vw 65vh 8px 2px #fff, -68vw 70vh 3px 2px #fff, 18vw 96vh 3px 3px #fff, -89vw 101vh 8px 5px #fff, 71vw 129vh 2px 3px #fff, -54vw 77vh 1px 2px #fff, 23vw 72vh 3px 1px #fff, -60vw 92vh 4px 2px #fff, 7vw 104vh 1px 3px #fff, -12vw 123vh 2px 4px #fff, 42vw 53vh 5px 2px #fff, -15vw 103vh 1px 5px #fff, 94vw 110vh 2px 3px #fff, -24vw 116vh 6px 1px #fff, 42vw 65vh 3px 3px #fff, -61vw 67vh 5px 4px #fff, 94vw 138vh 1px 3px #fff, -8vw 108vh 4px 2px #fff, 57vw 87vh 8px 4px #fff, -15vw 84vh 3px 3px #fff, 9vw 82vh 6px 2px #fff, -88vw 94vh 2px 3px #fff, 24vw 81vh 6px 3px #fff, -40vw 101vh 8px 3px #fff;
            box-shadow: 0 0 0 transparent, 58vw 95vh 1px 2px #fff, -74vw 137vh 2px 4px #fff, 56vw 147vh 2px 1px #fff, -55vw 96vh 7px 4px #fff, 23vw 127vh 7px 1px #fff, -58vw 134vh 1px 2px #fff, 62vw 137vh 2px 3px #fff, -59vw 123vh 1px 4px #fff, 35vw 149vh 3px 2px #fff, -74vw 58vh 5px 1px #fff, 78vw 95vh 4px 4px #fff, -25vw 134vh 6px 1px #fff, 19vw 79vh 4px 5px #fff, -3vw 67vh 4px 5px #fff, 5vw 123vh 7px 5px #fff, -51vw 139vh 4px 3px #fff, 5vw 142vh 8px 1px #fff, -73vw 109vh 8px 2px #fff, 44vw 148vh 6px 1px #fff, -32vw 137vh 2px 1px #fff, 6vw 150vh 1px 2px #fff, -16vw 80vh 1px 3px #fff, 61vw 57vh 8px 2px #fff, -73vw 110vh 1px 3px #fff, 50vw 95vh 5px 2px #fff, -26vw 80vh 2px 5px #fff, 23vw 134vh 2px 5px #fff, -1vw 134vh 6px 2px #fff, 40vw 58vh 8px 3px #fff, -45vw 61vh 8px 4px #fff, 73vw 120vh 6px 1px #fff, -85vw 65vh 6px 3px #fff, 5vw 111vh 8px 5px #fff, -2vw 150vh 4px 2px #fff, 78vw 64vh 4px 5px #fff, -64vw 129vh 1px 3px #fff, 67vw 85vh 4px 3px #fff, -9vw 59vh 2px 4px #fff, 71vw 57vh 3px 4px #fff, -28vw 86vh 8px 5px #fff, 84vw 95vh 8px 4px #fff, -80vw 52vh 4px 3px #fff, 94vw 147vh 7px 4px #fff, -20vw 75vh 5px 5px #fff, 63vw 80vh 8px 4px #fff, -7vw 100vh 1px 4px #fff, 67vw 61vh 4px 1px #fff, -88vw 59vh 8px 2px #fff, 67vw 98vh 3px 2px #fff, -19vw 142vh 3px 1px #fff, 86vw 75vh 5px 4px #fff, -57vw 131vh 4px 3px #fff, 13vw 102vh 6px 3px #fff, -65vw 136vh 4px 1px #fff, 70vw 86vh 1px 1px #fff, -22vw 103vh 5px 1px #fff, 59vw 123vh 6px 1px #fff, -70vw 57vh 7px 5px #fff, 1vw 113vh 1px 4px #fff, -1vw 55vh 1px 2px #fff, 34vw 77vh 5px 2px #fff, -63vw 100vh 2px 1px #fff, 30vw 92vh 2px 1px #fff, -71vw 150vh 3px 1px #fff, 38vw 105vh 3px 2px #fff, -38vw 115vh 1px 1px #fff, 27vw 128vh 7px 4px #fff, -13vw 74vh 4px 2px #fff, 77vw 150vh 6px 3px #fff, -76vw 120vh 1px 1px #fff, 78vw 62vh 5px 2px #fff, -44vw 55vh 1px 2px #fff, 95vw 98vh 6px 2px #fff, -83vw 65vh 5px 5px #fff, 51vw 117vh 6px 4px #fff, -41vw 148vh 4px 3px #fff, 92vw 65vh 8px 2px #fff, -68vw 70vh 3px 2px #fff, 18vw 96vh 3px 3px #fff, -89vw 101vh 8px 5px #fff, 71vw 129vh 2px 3px #fff, -54vw 77vh 1px 2px #fff, 23vw 72vh 3px 1px #fff, -60vw 92vh 4px 2px #fff, 7vw 104vh 1px 3px #fff, -12vw 123vh 2px 4px #fff, 42vw 53vh 5px 2px #fff, -15vw 103vh 1px 5px #fff, 94vw 110vh 2px 3px #fff, -24vw 116vh 6px 1px #fff, 42vw 65vh 3px 3px #fff, -61vw 67vh 5px 4px #fff, 94vw 138vh 1px 3px #fff, -8vw 108vh 4px 2px #fff, 57vw 87vh 8px 4px #fff, -15vw 84vh 3px 3px #fff, 9vw 82vh 6px 2px #fff, -88vw 94vh 2px 3px #fff, 24vw 81vh 6px 3px #fff, -40vw 101vh 8px 3px #fff;
  }
}

</style>
</head>
<body marginwidth="0" marginheight="0">
<div class="snow">
  
  <div class="snow__item"></div>
  <div class="snow__item"></div>
  <div class="snow__item"></div>
  <div class="txt">
  <!-- English -->
  <p>Merry Christmas!</p>
  <!-- Dutch -->
  <p>Vrolijk kerstfeest!</p>
  <!-- German -->
  <p>Fröhliche Weihnachten!</p>
  <!-- Chinese -->
  <p>圣诞节快乐!</p>
  <!-- Japanese -->
  <p>メリークリスマス!</p>
  <!-- Turkish -->
  <p>Mutlu Noeller!</p>
  <!-- Arabic-->
  <p>!عيد ميلاد سعيد</p>
</div>

			
</body>
</html>

样例三

在这里插入图片描述

<!DOCTYPE HEML PUBLIC>
<html xmlns="http://www.w3.org/1999/html">
    <head>
    <meta charset="utf-8">
        <style>
            html, body, canvas{
                font-family: "Playfair Display SC", sans-serif;
                font-weight: 900;
                font-size: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
                padding: 0;
                margin: 0;
                left: 0;
                top: 0;
            }


        </style>
    </head>
<body marginwidth="0" marginheight="0">
    <script>
        var _seed = new Date().getTime();
        var __seed = _seed;

        var $canvas;
        var _width, _height;
        var _color, _tree;
        var _c, _scale = 1;

        var _message = 0;

        const _messages = [
            "Merry Christmas",
            "عيد ميلاد%مجيد",
            "圣诞快乐",
            "Čestit Božić",
            "Veselé Vánoce",
            "Glædelig Jul",
            "Prettige Kerstdagen",
            "Häid jõule",
            "Hauskaa joulua",
            "Joyeux Noël",
            "Frohe Weihnachten",
            "Χαρούμενα Χριστούγεννα",
            "Buon Natale",
            "メリー クリスマス",
            "메리 크리스마스",
            "Priecīgus Ziemassvētkus",
            "Linksmų%šv. Kalėdų",
            "Среќен Божиќ",
            "God%jul",
            "Wesołych Świąt!",
            "Feliz Natal",
            "Crăciun fericit",
            "Счастливого Рождества!",
            "Srećan Božić",
            "Kirismas Wanaagsan",
            "Feliz Navidad",
            "Heri%ya krismas",
            "God%jul",
            "Веселого Різдва",
            "Bon Nadal"
        ];

        // utils

        function random() {
            let x = Math.sin(__seed++) * 10000;
            return x - Math.floor(x);
        }

        function range( v = 0, omin = 0, omax = 1, nmin = 0, nmax = 1, clamp = false ) {
            let result = ( v - omin ) * ( nmax - nmin) / ( omax - omin ) + nmin;
            if ( clamp ) result = Math.min( Math.max( result, nmin ), nmax );
            return result;
        }

        function radians( degrees = 0 ) {
            return degrees * (Math.PI / 180);
        }

        function angleTo( p1, p2 ) {
            return Math.atan2(p2.y - p1.y, p2.x - p1.x);
        }

        function distance( p1, p2 ) {
            return Math.sqrt( Math.pow( p1.x - p2.x, 2 ) + Math.pow( p1.y - p2.y, 2 ));
        }

        function vectorOnCurve( time, p1, p2, p3 ) {
            let x = (1 - time) * ((1 - time) * p1.x + (time * p2.x)) + time * (((1 - time) * p2.x + (time * p3.x)));
            let y = (1 - time) * ((1 - time) * p1.y + (time * p2.y)) + time * (((1 - time) * p2.y + (time * p3.y)));
            return { x , y };
        }

        // constructor

        ( _ => {
            initCanvas();
            addHandlers();
            resize();

            setInterval( _ => {
                _seed = new Date().getTime();
                resize();
            }, 1000 );

        })();

        // setup

        function initCanvas() {
            $canvas = document.createElement('canvas');
            document.body.appendChild( $canvas );
            _c = $canvas.getContext('2d');
        }

        function addHandlers() {
            window.addEventListener( 'resize', resize );
        }

        function resize() {
            let ratio = window.devicePixelRatio || 1;
            __seed = _seed;
            _width = window.innerWidth * ratio;
            _height = window.innerHeight * ratio;
            $canvas.setAttribute( 'width', _width );
            $canvas.setAttribute( 'height', _height );
            $canvas.style.width = `${_width / ratio }px`;
            $canvas.style.height = `${_height / ratio }px`;
            render();
        }

        // draw call

        function render() {
            setColors();
            generateTree();
            drawBackground();
            drawBaubels();
            drawTrunk();
            drawPresents();
            drawNeedles( 2.0 );
            drawGarland( 10 );
            drawNeedles( 0.75 );
            drawGarland( -3 );
            drawBaubels();
            drawNeedles( 0.125 );
            drawStar();
            drawMessage();
        }

        function setColors() {
            _color = {};

            let wh = range( random(), 0, 1, 13, 60 );
            let ws = range( random(), 0, 1, 5, 25 );
            let wl = range( random(), 0, 1, 25, 32 );
            _color.branch = `hsla(${wh},${ws}%,${wl}%,1)`;

            let nh = range( random(), 0, 1, 90, 175 );
            let ns = range( random(), 0, 1, 15, 45 );
            let nl = range( random(), 0, 1, 25, 42 );
            _color.needle = `hsla(${nh},${ns}%,${nl}%,0.6)`;

            let bh = range( random(), 0, 1, -90, 90 );
            let bs = range( random(), 0, 1, 45, 55 );
            let bl = range( random(), 0, 1, 50, 65 );

            _color.bauble = `hsla(${bh},${bs}%,${bl}%,1.0)`;
            _color.garland = `hsla(${bh + 120},${bs}%,${bl + 15}%,0.75)`;
            _color.presents = `hsla(${bh - 120},${bs}%,${bl - 25}%,1.0)`;
            _color.star = `hsla(${bh + 120},${bs}%,90%,1.0)`;
            _color.background = `hsla(${nh},${ns * 0.5}%,85%,1.0)`
        }

        function generateTree() {
            _tree = {};
            generateTrunk();
            generateBranches();
        }

        function generateTrunk() {
            _tree.trunk = [];
            _tree.thickness = range( random(), 0, 1, 15, 21 );

            let steps = Math.floor( range( random(), 0, 1, 7, 16 ));
            let step = 0;

            let x = _width * 0.5;
            let y = 0;

            _tree.trunk.push({ x, y });
            while ( step < steps ) {
                let angle = radians( range( random(), 0, 1, 75, 105 ));
                let mult = range( steps - step, 0, steps, 35, 60 );
                let dist = range( random(), 0, 1, mult * 0.666, mult * 1.333 ) * _scale;
                x += Math.round( Math.cos( angle ) * dist );
                y -= Math.floor( Math.sin( angle ) * dist ) + 1;
                _tree.trunk.push({ x, y });
                step++;
            }

            let offset = Math.floor(( _height + Math.abs( y )) * 0.5 );
            for ( let step of _tree.trunk ) {
                step.y += offset;
            }

        }

        function generateBranches() {
            _tree.branches = [];

            let index = 0;
            for ( let step of _tree.trunk ) {
                let mult = Math.abs( range( index - _tree.trunk.length, 0, _tree.trunk.length, 0.1, 1 )) * _scale;
                let total = Math.round( range( random(), 0, 1, 4, range( mult, 0, 1, 4, 12 )));
                if ( index <= 1 ) total = 0;

                let i = 0;
                while ( i < total ) {
                    let ox = step.x;
                    let oy = step.y;
                    let angle = range( mult, 0, 1, 45, 5 );
                    let dist = range( random(), 0, 1, 100, 200 ) * range( mult, 0, 1, 0.35, 1.5 ) * _scale;
                    angle += range( random(), 0, 1, -15, 15 );
                    angle = radians( angle );

                    let dx = ox + ( Math.cos( angle ) * dist ) * ( i / 2 === Math.round( i / 2) ? 1 : -1 );
                    let dy = oy + Math.sin( angle ) * dist;

                    _tree.branches.push({
                        p1: { x: ox, y: oy },
                        p2: { x: ox + ( dx - ox ) * 0.5, y: dy + ( dy - oy ) * 0.35 },
                        p3: { x: dx, y: dy },
                        thickness: _tree.thickness * ( 1 - (( index + 1 ) / _tree.trunk.length ))
                    });

                    i++;
                }

                index++;
            }

        }

        function drawBackground() {
            let fill = _color.background;
            _c.fillStyle = fill;
            _c.fillRect( 0, 0, _width, _height );
        }

        function drawTrunk() {
            let index = 0;
            _c.fillStyle = _color.branch;
            _c.strokeStyle = '';

            for ( let segment of _tree.trunk ) {
                let next = _tree.trunk[ index + 1 ];
                if ( !next ) break;

                let tThick = _tree.thickness * ( 1 - (( index + 1 ) / _tree.trunk.length ));
                let bThick = _tree.thickness * ( 1 - ( index / _tree.trunk.length ));

                _c.beginPath();
                _c.moveTo( segment.x - bThick, segment.y );
                _c.lineTo( next.x - tThick, next.y );
                _c.lineTo( next.x + tThick, next.y );
                _c.lineTo( segment.x + bThick, segment.y );
                _c.closePath();
                _c.fill();
                index++;
            }
        }

        function drawBranches() {
            let index = 0;
            _c.fillStyle = '';
            _c.strokeStyle = _color.branch;

            for ( let branch of _tree.branches ) {
                _c.beginPath();
                _c.moveTo( branch.p1.x, branch.p1.y );
                _c.quadraticCurveTo( branch.p2.x, branch.p2.y, branch.p3.x, branch.p3.y );
                _c.lineWidth = Math.max( branch.thickness * 0.8, 3 ) * _scale;
                _c.stroke();
            }
        }

        function drawNeedles( mult = 1 ) {
            _c.fillStyle = '';
            _c.strokeStyle = _color.needle;

            for ( let branch of _tree.branches ) {
                let total = distance( branch.p1, branch.p3 ) * mult;
                let i = 0;
                while ( i < total ) {
                    let origin = vectorOnCurve( i / total, branch.p1, branch.p2, branch.p3 );
                    let angle = radians( range( random(), 0, 1, 0, 360 ));
                    let length = range( random(), 0, 1, 6, 18 ) * _scale;

                    origin.x += Math.cos( angle ) * ( 5 + branch.thickness ) * _scale;
                    origin.y += Math.sin( angle ) * ( 5 + branch.thickness ) * _scale;

                    let x = origin.x + Math.cos( angle ) * length;
                    let y = origin.y + Math.sin( angle ) * length;
                    let thickness = range( random(), 0, 1, 1.5, 2 ) * _scale;

                    _c.beginPath();
                    _c.lineWidth = thickness;
                    _c.moveTo( origin.x, origin.y );
                    _c.lineTo( x, y );
                    _c.stroke();

                    i++;
                }
            }
        }

        function drawBaubels() {
            let total = _tree.branches.length;
            let index = 0;

            _c.strokeStyle = '';

            while ( index < total ) {

                if ( random() > 0.75 ) {
                    let branch = _tree.branches[ index ];
                    let point = vectorOnCurve( random(), branch.p1, branch.p2, branch.p3 );
                    let radius = range( random(), 0, 1, 8, 10 ) * _scale;


                    _c.fillStyle = '';
                    _c.strokeStyle = _color.background;
                    _c.lineWidth = 1;

                    _c.beginPath();
                    _c.moveTo( point.x, point.y + 10 );
                    _c.lineTo( point.x, point.y - 5 );
                    _c.stroke();

                    _c.fillStyle = _color.bauble;

                    _c.beginPath();
                    _c.arc( point.x, point.y + 10, radius, 0, Math.PI * 2 );
                    _c.fill();
                }

                index++;
            }
        }

        function drawGarland( mult = 1 ) {
            let index = Math.floor( range( random(), 0, 1, 5, 12 )) + mult;
            let past = _tree.branches[index];

            _c.fillStyle = '';
            _c.strokeStyle = _color.garland;
            _c.lineWidth = 4 * _scale;
            _c.lineCap = 'round';

            while ( index < _tree.branches.length ) {
                let current = _tree.branches[ index ];
                let p1 = vectorOnCurve( 1, past.p1, past.p2, past.p3 );
                let p3 = vectorOnCurve( 1, current.p1, current.p2, current.p3 );

                if (
                    distance( p1, p3 ) > 100 &&
                    (( p1.x < _width / 2 && p3.x > _width / 2 ) ||
                        ( p1.x > _width / 2 && p3.x < _width / 2 ))
                ) {
                    let p2 = {
                        x: ( p1.x + p3.x ) / 2,
                        y: Math.max( p1.y, p3.y )
                    }

                    _c.beginPath();
                    _c.moveTo( p1.x, p1.y );
                    _c.quadraticCurveTo( p2.x, p2.y, p3.x, p3.y );
                    _c.stroke();

                    past = current;
                    index += Math.floor( _tree.branches.length * 0.25 );
                } else {
                    index++;
                }
            }

            _c.lineCap = 'butt';
        }

        function drawPresents() {
            let i = 0;
            let ox = _width * 0.5;
            let oy = _tree.trunk[0].y;
            let offset = 0;

            _c.fillStyle = _color.presents;
            _c.strokeStyle = '';


            let bs = range( random(), 0, 1, 35, 45 );
            let bh = range( random(), 0, 1, -120, 120 );

            while ( i < range( random(), 0, 1, 10, 16 )) {
                let w = Math.floor( range( random(), 0, 1, 30, 110 )) * _scale;
                let h = Math.floor( range( random(), 0, 1, 30, 110 )) * _scale;
                let x = Math.floor( ox + range( random(), 0, 1, -140, 140 ) - w * 0.5 ) * _scale;
                let y = Math.floor( oy - h );
                y += offset;

                let bl = range( random(), 0, 1, 35, 85 );
                _color.presents = `hsla(${bh - 120 },${bs}%,${bl - 15}%,1.0)`;

                _c.beginPath();
                _c.fillStyle = _color.presents;
                _c.fillRect( x, y, w, h );

                let ribbon = 5;
                _c.fillStyle = _color.garland;

                _c.fillRect( x, y + ( h - ribbon ) * 0.5, w, ribbon );
                _c.fillRect( x + ( w - ribbon ) * 0.5, y, ribbon, h );

                offset += range( random(), 0, 1, 3, 8 );

                i++;
            }
        }

        function drawStar() {
            let points = Math.floor( range( random(), 0, 1, 5, 12 ));
            let point = _tree.trunk[_tree.trunk.length - 1];
            let inner = range( random(), 0, 1, 15, 20 ) * _scale;
            let outer = inner + range( random(), 0, 1, 15, 25 ) * _scale;
            let step = 360 / points;

            _c.fillStyle = _color.star;
            _c.strokeStyle = _color.star;
            _c.lineWidth = 5;
            _c.lineCap = 'round';

            let angle = -90;
            while ( angle < 270 ) {

                let x = point.x + Math.cos( radians( angle )) * outer;
                let y = point.y + Math.sin( radians( angle )) * outer;

                let x2 = point.x + Math.cos( radians( angle + step * 0.5 )) * inner;
                let y2 = point.y + Math.sin( radians( angle + step * 0.5 )) * inner;

                let x3 = point.x + Math.cos( radians( angle - step * 0.5 )) * inner;
                let y3 = point.y + Math.sin( radians( angle - step * 0.5 )) * inner;

                _c.beginPath();
                _c.moveTo( x, y );
                _c.lineTo( x2, y2 );
                _c.lineTo( point.x, point.y );
                _c.lineTo( x3, y3 );
                _c.lineTo( x, y );
                //_c.fill();

                _c.beginPath();
                _c.moveTo( x, y );
                _c.lineTo( x2, y2 );
                _c.stroke();

                _c.beginPath();
                _c.moveTo( x, y );
                _c.lineTo( x3, y3 );
                _c.stroke();

                angle += step;
            }

            // _c.beginPath();
            // _c.moveTo( point.x, point.y );
            // _c.arc( point.x, point.y, inner, 0, Math.PI * 2 );
            // _c.fill();

            _c.lineCap = 'butt';
        }

        function drawMessage() {
            let size = range( _width, 600 * 2, 1400 * 2, 95, 120 );

            _c.globalCompositeOperation = 'multiply';
            _c.fillStyle = 'hsl(12, 85%, 56%)';
            _c.textAlign = 'center';
            _c.font = `normal 900 ${size}px "Playfair Display SC", Serif`;

            let string = _messages[ _message ];
            _message++;
            if ( _message > _messages.length - 1 ) _message = 0;


            let words = string.split(' ');

            let spacing = size * 0.85;
            let offset = words.length * ( 0.5 * spacing ) - size;

            let x = _width * 0.5;
            let y = _height * 0.5 - offset;

            let i = 0;
            for ( let word of words ) {
                word = word.replace(/%/g, " ");
                _c.fillText( word, x, y + i * spacing );
                i++;
            }

            _c.globalCompositeOperation = 'source-over';
        }
    </script>
</body>
</html>

样例四

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Codepen-challenge-christmas-tree</title>
   <style>
    .text {
      color: whitesmoke;
      font-size: 45px;
      text-align: center;
      font-family: 'Fantasy';
      text-shadow: 5px 5px 5px yellow;
    }

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      background-color: #020024;
    }

    .bgg {
      position: fixed;
      display: grid;
      align-content: center;
      z-index: 1;
      height: 100vh;
      left: 50%;
      margin-left: -315px;
    }

    .bgg li.sphere {
      width: 650px;
      height: 650px;
      background: #020024;
      background: radial-gradient(rgba(2, 0, 36, 0.5) 47%, rgba(108, 108, 142, 0.7) 51%, rgba(171, 171, 255, 0.7) 52%, #020024 53%);
    }

    ul {
      list-style-type: none;
    }

    .tree {
      z-index: 2;
      position: fixed;
      left: 50%;
      margin-left: -160px;
      display: grid;
      height: 97vh;
      align-content: center;
      grid-template-areas: ". tree-top ."". tree-middle ."". tree-bottom ."". tree-stem .";
      grid-template-columns: 100px auto 100px;
      transform: rotateY(50deg) scaley(1.5);
    }

    .tree>li {
      position: relative;
      display: block;
    }

    .tree .top,
    .tree .top-star {
      grid-area: tree-top;
    }

    .tree .top li,
    .tree .top-star li {
      border-color: green;
    }

    .tree .top-star {
      grid-area: tree-top;
      width: 130px;
      height: 55px;
      position: absolute;
      background-color: #fff;
      border-radius: 50%;
      top: -48px;
      z-index: 10;
      left: 4px;
      animation: starLight 1.5s ease-out infinite alternate;
    }

    .tree .middle {
      grid-area: tree-middle;
    }

    .tree .bottom {
      grid-area: tree-bottom;
    }

    .tree .stem {
      grid-area: tree-stem;
    }

    .tree .tree-pts {
      margin: 0 auto;
      display: flex;
      justify-content: center;
    }

    .tree .tree-pts .pts {
      top: 0;
      position: absolute;
    }

    .tree li:nth-of-type(1) .pts {
      border-left: 10px solid #049c04;
      z-index: calc(8 - 1);
    }

    .tree li:nth-of-type(2) .pts {
      border-left: 10px solid #13a313;
      z-index: calc(8 - 2);
    }

    .tree li:nth-of-type(3) .pts {
      border-left: 10px solid #067806;
      z-index: calc(8 - 3);
    }

    .tree li:nth-of-type(4) .pts {
      border-left: 10px solid #0f6b0f;
      z-index: calc(8 - 4);
    }

    .tree li:nth-of-type(5) .pts {
      border-left: 10px solid #0f5f0f;
      z-index: calc(8 - 5);
    }

    .tree li:nth-of-type(6) .pts {
      border-left: 10px solid #0f4f0f;
      z-index: calc(8 - 6);
    }

    .tree li:nth-of-type(7) .stem {
      border-bottom-color: #0f4f0f;
      z-index: calc(8 - 7);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(1) {
      width: 1.7em;
      height: 2em;
      border-radius: 100% 0 0 0;
      transform: rotate(219.5deg) rotatey(28.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(2) {
      width: 1.7em;
      height: 2em;
      border-radius: 100% 0 0 0;
      transform: rotate(218.5deg) rotatey(36.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(3) {
      width: 1.7em;
      height: 2em;
      border-radius: 100% 0 0 0;
      transform: rotate(217.5deg) rotatey(44.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(4) {
      width: 1.7em;
      height: 2em;
      border-radius: 100% 0 0 0;
      transform: rotate(216.5deg) rotatey(52.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(5) {
      width: 1.7em;
      height: 2em;
      border-radius: 100% 0 0 0;
      transform: rotate(215.5deg) rotatey(60.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(6) {
      width: 1.7em;
      height: 2em;
      border-radius: 100% 0 0 0;
      transform: rotate(214.5deg) rotatey(68.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(7) {
      width: 1.7em;
      height: 2em;
      border-radius: 100% 0 0 0;
      transform: rotate(213.5deg) rotatey(76.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(8) {
      width: 1.7em;
      height: 2em;
      border-radius: 100% 0 0 0;
      transform: rotate(212.5deg) rotatey(84.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(9) {
      width: 1.7em;
      height: 2em;
      border-radius: 0 0 0 100%;
      transform: rotate(-40.5deg) rotatey(28.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(10) {
      width: 1.7em;
      height: 2em;
      border-radius: 0 0 0 100%;
      transform: rotate(-41.5deg) rotatey(37deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(11) {
      width: 1.7em;
      height: 2em;
      border-radius: 0 0 0 100%;
      transform: rotate(-42.5deg) rotatey(45.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(12) {
      width: 1.7em;
      height: 2em;
      border-radius: 0 0 0 100%;
      transform: rotate(-43.5deg) rotatey(54deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(13) {
      width: 1.7em;
      height: 2em;
      border-radius: 0 0 0 100%;
      transform: rotate(-44.5deg) rotatey(62.5deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(14) {
      width: 1.7em;
      height: 2em;
      border-radius: 0 0 0 100%;
      transform: rotate(-45.5deg) rotatey(71deg) translateX(4em);
    }

    .tree li:nth-child(1) .tree-pts .pts:nth-of-type(15) {
      width: 1.7em;
      height: 2em;
      border-radius: 0 0 0 100%;
      transform: rotate(-46.5deg) rotatey(79.5deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(1) {
      width: 3.4em;
      height: 4em;
      border-radius: 100% 0 0 0;
      transform: rotate(220deg) rotatey(29deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(2) {
      width: 3.4em;
      height: 4em;
      border-radius: 100% 0 0 0;
      transform: rotate(219deg) rotatey(37deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(3) {
      width: 3.4em;
      height: 4em;
      border-radius: 100% 0 0 0;
      transform: rotate(218deg) rotatey(45deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(4) {
      width: 3.4em;
      height: 4em;
      border-radius: 100% 0 0 0;
      transform: rotate(217deg) rotatey(53deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(5) {
      width: 3.4em;
      height: 4em;
      border-radius: 100% 0 0 0;
      transform: rotate(216deg) rotatey(61deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(6) {
      width: 3.4em;
      height: 4em;
      border-radius: 100% 0 0 0;
      transform: rotate(215deg) rotatey(69deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(7) {
      width: 3.4em;
      height: 4em;
      border-radius: 100% 0 0 0;
      transform: rotate(214deg) rotatey(77deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(8) {
      width: 3.4em;
      height: 4em;
      border-radius: 100% 0 0 0;
      transform: rotate(213deg) rotatey(85deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(9) {
      width: 3.4em;
      height: 4em;
      border-radius: 0 0 0 100%;
      transform: rotate(-40deg) rotatey(29deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(10) {
      width: 3.4em;
      height: 4em;
      border-radius: 0 0 0 100%;
      transform: rotate(-41deg) rotatey(38deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(11) {
      width: 3.4em;
      height: 4em;
      border-radius: 0 0 0 100%;
      transform: rotate(-42deg) rotatey(47deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(12) {
      width: 3.4em;
      height: 4em;
      border-radius: 0 0 0 100%;
      transform: rotate(-43deg) rotatey(56deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(13) {
      width: 3.4em;
      height: 4em;
      border-radius: 0 0 0 100%;
      transform: rotate(-44deg) rotatey(65deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(14) {
      width: 3.4em;
      height: 4em;
      border-radius: 0 0 0 100%;
      transform: rotate(-45deg) rotatey(74deg) translateX(4em);
    }

    .tree li:nth-child(2) .tree-pts .pts:nth-of-type(15) {
      width: 3.4em;
      height: 4em;
      border-radius: 0 0 0 100%;
      transform: rotate(-46deg) rotatey(83deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(1) {
      width: 5.1em;
      height: 6em;
      border-radius: 100% 0 0 0;
      transform: rotate(220.5deg) rotatey(29.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(2) {
      width: 5.1em;
      height: 6em;
      border-radius: 100% 0 0 0;
      transform: rotate(219.5deg) rotatey(37.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(3) {
      width: 5.1em;
      height: 6em;
      border-radius: 100% 0 0 0;
      transform: rotate(218.5deg) rotatey(45.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(4) {
      width: 5.1em;
      height: 6em;
      border-radius: 100% 0 0 0;
      transform: rotate(217.5deg) rotatey(53.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(5) {
      width: 5.1em;
      height: 6em;
      border-radius: 100% 0 0 0;
      transform: rotate(216.5deg) rotatey(61.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(6) {
      width: 5.1em;
      height: 6em;
      border-radius: 100% 0 0 0;
      transform: rotate(215.5deg) rotatey(69.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(7) {
      width: 5.1em;
      height: 6em;
      border-radius: 100% 0 0 0;
      transform: rotate(214.5deg) rotatey(77.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(8) {
      width: 5.1em;
      height: 6em;
      border-radius: 100% 0 0 0;
      transform: rotate(213.5deg) rotatey(85.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(9) {
      width: 5.1em;
      height: 6em;
      border-radius: 0 0 0 100%;
      transform: rotate(-39.5deg) rotatey(29.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(10) {
      width: 5.1em;
      height: 6em;
      border-radius: 0 0 0 100%;
      transform: rotate(-40.5deg) rotatey(39deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(11) {
      width: 5.1em;
      height: 6em;
      border-radius: 0 0 0 100%;
      transform: rotate(-41.5deg) rotatey(48.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(12) {
      width: 5.1em;
      height: 6em;
      border-radius: 0 0 0 100%;
      transform: rotate(-42.5deg) rotatey(58deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(13) {
      width: 5.1em;
      height: 6em;
      border-radius: 0 0 0 100%;
      transform: rotate(-43.5deg) rotatey(67.5deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(14) {
      width: 5.1em;
      height: 6em;
      border-radius: 0 0 0 100%;
      transform: rotate(-44.5deg) rotatey(77deg) translateX(4em);
    }

    .tree li:nth-child(3) .tree-pts .pts:nth-of-type(15) {
      width: 5.1em;
      height: 6em;
      border-radius: 0 0 0 100%;
      transform: rotate(-45.5deg) rotatey(86.5deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(1) {
      width: 6.8em;
      height: 8em;
      border-radius: 100% 0 0 0;
      transform: rotate(221deg) rotatey(30deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(2) {
      width: 6.8em;
      height: 8em;
      border-radius: 100% 0 0 0;
      transform: rotate(220deg) rotatey(38deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(3) {
      width: 6.8em;
      height: 8em;
      border-radius: 100% 0 0 0;
      transform: rotate(219deg) rotatey(46deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(4) {
      width: 6.8em;
      height: 8em;
      border-radius: 100% 0 0 0;
      transform: rotate(218deg) rotatey(54deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(5) {
      width: 6.8em;
      height: 8em;
      border-radius: 100% 0 0 0;
      transform: rotate(217deg) rotatey(62deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(6) {
      width: 6.8em;
      height: 8em;
      border-radius: 100% 0 0 0;
      transform: rotate(216deg) rotatey(70deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(7) {
      width: 6.8em;
      height: 8em;
      border-radius: 100% 0 0 0;
      transform: rotate(215deg) rotatey(78deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(8) {
      width: 6.8em;
      height: 8em;
      border-radius: 100% 0 0 0;
      transform: rotate(214deg) rotatey(86deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(9) {
      width: 6.8em;
      height: 8em;
      border-radius: 0 0 0 100%;
      transform: rotate(-39deg) rotatey(30deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(10) {
      width: 6.8em;
      height: 8em;
      border-radius: 0 0 0 100%;
      transform: rotate(-40deg) rotatey(40deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(11) {
      width: 6.8em;
      height: 8em;
      border-radius: 0 0 0 100%;
      transform: rotate(-41deg) rotatey(50deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(12) {
      width: 6.8em;
      height: 8em;
      border-radius: 0 0 0 100%;
      transform: rotate(-42deg) rotatey(60deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(13) {
      width: 6.8em;
      height: 8em;
      border-radius: 0 0 0 100%;
      transform: rotate(-43deg) rotatey(70deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(14) {
      width: 6.8em;
      height: 8em;
      border-radius: 0 0 0 100%;
      transform: rotate(-44deg) rotatey(80deg) translateX(4em);
    }

    .tree li:nth-child(4) .tree-pts .pts:nth-of-type(15) {
      width: 6.8em;
      height: 8em;
      border-radius: 0 0 0 100%;
      transform: rotate(-45deg) rotatey(90deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(1) {
      width: 8.5em;
      height: 10em;
      border-radius: 100% 0 0 0;
      transform: rotate(221.5deg) rotatey(30.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(2) {
      width: 8.5em;
      height: 10em;
      border-radius: 100% 0 0 0;
      transform: rotate(220.5deg) rotatey(38.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(3) {
      width: 8.5em;
      height: 10em;
      border-radius: 100% 0 0 0;
      transform: rotate(219.5deg) rotatey(46.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(4) {
      width: 8.5em;
      height: 10em;
      border-radius: 100% 0 0 0;
      transform: rotate(218.5deg) rotatey(54.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(5) {
      width: 8.5em;
      height: 10em;
      border-radius: 100% 0 0 0;
      transform: rotate(217.5deg) rotatey(62.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(6) {
      width: 8.5em;
      height: 10em;
      border-radius: 100% 0 0 0;
      transform: rotate(216.5deg) rotatey(70.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(7) {
      width: 8.5em;
      height: 10em;
      border-radius: 100% 0 0 0;
      transform: rotate(215.5deg) rotatey(78.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(8) {
      width: 8.5em;
      height: 10em;
      border-radius: 100% 0 0 0;
      transform: rotate(214.5deg) rotatey(86.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(9) {
      width: 8.5em;
      height: 10em;
      border-radius: 0 0 0 100%;
      transform: rotate(-38.5deg) rotatey(30.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(10) {
      width: 8.5em;
      height: 10em;
      border-radius: 0 0 0 100%;
      transform: rotate(-39.5deg) rotatey(41deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(11) {
      width: 8.5em;
      height: 10em;
      border-radius: 0 0 0 100%;
      transform: rotate(-40.5deg) rotatey(51.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(12) {
      width: 8.5em;
      height: 10em;
      border-radius: 0 0 0 100%;
      transform: rotate(-41.5deg) rotatey(62deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(13) {
      width: 8.5em;
      height: 10em;
      border-radius: 0 0 0 100%;
      transform: rotate(-42.5deg) rotatey(72.5deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(14) {
      width: 8.5em;
      height: 10em;
      border-radius: 0 0 0 100%;
      transform: rotate(-43.5deg) rotatey(83deg) translateX(4em);
    }

    .tree li:nth-child(5) .tree-pts .pts:nth-of-type(15) {
      width: 8.5em;
      height: 10em;
      border-radius: 0 0 0 100%;
      transform: rotate(-44.5deg) rotatey(93.5deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(1) {
      width: 10.2em;
      height: 12em;
      border-radius: 100% 0 0 0;
      transform: rotate(222deg) rotatey(31deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(2) {
      width: 10.2em;
      height: 12em;
      border-radius: 100% 0 0 0;
      transform: rotate(221deg) rotatey(39deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(3) {
      width: 10.2em;
      height: 12em;
      border-radius: 100% 0 0 0;
      transform: rotate(220deg) rotatey(47deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(4) {
      width: 10.2em;
      height: 12em;
      border-radius: 100% 0 0 0;
      transform: rotate(219deg) rotatey(55deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(5) {
      width: 10.2em;
      height: 12em;
      border-radius: 100% 0 0 0;
      transform: rotate(218deg) rotatey(63deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(6) {
      width: 10.2em;
      height: 12em;
      border-radius: 100% 0 0 0;
      transform: rotate(217deg) rotatey(71deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(7) {
      width: 10.2em;
      height: 12em;
      border-radius: 100% 0 0 0;
      transform: rotate(216deg) rotatey(79deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(8) {
      width: 10.2em;
      height: 12em;
      border-radius: 100% 0 0 0;
      transform: rotate(215deg) rotatey(87deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(9) {
      width: 10.2em;
      height: 12em;
      border-radius: 0 0 0 100%;
      transform: rotate(-38deg) rotatey(31deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(10) {
      width: 10.2em;
      height: 12em;
      border-radius: 0 0 0 100%;
      transform: rotate(-39deg) rotatey(42deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(11) {
      width: 10.2em;
      height: 12em;
      border-radius: 0 0 0 100%;
      transform: rotate(-40deg) rotatey(53deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(12) {
      width: 10.2em;
      height: 12em;
      border-radius: 0 0 0 100%;
      transform: rotate(-41deg) rotatey(64deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(13) {
      width: 10.2em;
      height: 12em;
      border-radius: 0 0 0 100%;
      transform: rotate(-42deg) rotatey(75deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(14) {
      width: 10.2em;
      height: 12em;
      border-radius: 0 0 0 100%;
      transform: rotate(-43deg) rotatey(86deg) translateX(4em);
    }

    .tree li:nth-child(6) .tree-pts .pts:nth-of-type(15) {
      width: 10.2em;
      height: 12em;
      border-radius: 0 0 0 100%;
      transform: rotate(-44deg) rotatey(97deg) translateX(4em);
    }

    .left {
      right: 50%;
      margin-right: -38px;
    }

    .right {
      left: 50%;
      margin-left: -38px;
    }

    .tree-stem .stem {
      width: 0;
      height: 0;
      border-left: 70px solid transparent;
      border-right: 70px solid transparent;
      border-bottom: 120px solid #0f4f0f;
      margin: 0 auto;
    }

    .gift {
      position: absolute;
      width: 50px;
      height: 30px;
      margin: 5px;
      background-color: #ffc0cb;
      border: 1px dotted #42161e;
      z-index: 20;
      box-shadow: 1px -1px 2px #f5b0bc, 2px -2px 2px #e89daa, 3px -3px 2px #da8a98, 4px -4px 2px #ce7a89, 5px -5px 2px #bb6676, 6px -6px 2px #af5969, 7px -7px 2px #a04a5a, 8px -8px 2px #943e4e, 9px -9px 2px #803442, 10px -10px 2px #6b2834, 11px -11px 2px #541e28, 12px -12px 2px #42161e;
    }

    .g1 {
      left: -10px;
      top: 110px;
    }

    .g2 {
      left: 33px;
      top: 120px;
      height: 15px;
    }

    .g3 {
      left: 85px;
      top: 125px;
      width: 70px;
      height: 22px;
    }

    .g4 {
      left: -45px;
      top: 130px;
    }

    .g5 {
      left: 45px;
      top: 130px;
    }

    .g6 {
      left: 0px;
      top: 130px;
    }

    .g7 {
      left: 65px;
      top: 130px;
    }

    .g8 {
      left: 120px;
      top: 150px;
      height: 13px;
      width: 123px;
    }

    .g9 {
      left: 50px;
      top: 150px;
    }

    .shadow {
      width: 400px;
      height: 50px;
      background-color: rgba(42, 41, 68, 0.5);
      position: absolute;
      border-radius: 50%;
      top: 126px;
      left: -128px;
    }

    .toys {
      display: grid;
      position: absolute;
      gap: 5px;
      grid-template-columns: repeat(9, 20px);
      grid-template-rows: repeat(12, 20px);
      left: calc(50% - 100px);
      top: calc(50% - 135px);
      z-index: 2;
    }

    .toys .star {
      top: -30px;
      left: 10px;
      position: relative;
      border-right: 100px solid transparent;
      border-bottom: 70px solid gold;
      border-left: 100px solid transparent;
      transform: rotate(35deg) scale(0.2);
    }

    .toys .star:before {
      border-bottom: 80px solid gold;
      border-left: 30px solid transparent;
      border-right: 30px solid transparent;
      position: absolute;
      top: -45px;
      left: -65px;
      content: '';
      transform: rotate(-35deg);
    }

    .toys .star:after {
      position: absolute;
      top: 3px;
      left: -105px;
      border-right: 100px solid transparent;
      border-bottom: 70px solid gold;
      border-left: 100px solid transparent;
      transform: rotate(-70deg);
      content: '';
    }

    .toys .ball {
      width: 20px;
      height: 20px;
      background-color: #f00;
      border-radius: 50%;
      z-index: 1;
      position: absolute;
    }

    .toys .b1,
    .toys .b4,
    .toys .b5,
    .toys .b8,
    .toys .b11,
    .toys .b13,
    .toys .b16,
    .toys .b18 {
      background-color: red;
      box-shadow: -1px -1px 6px inset #600, 1px 1px 8px inset #ffc9c9;
    }

    .toys .b2,
    .toys .b6,
    .toys .b9,
    .toys .b12,
    .toys .b14,
    .toys .b17,
    .toys .b20 {
      background-color: gold;
      box-shadow: -1px -1px 6px inset #3a3101, 1px 1px 8px inset #ffffff;
    }

    .toys .b3,
    .toys .b7,
    .toys .b10,
    .toys .b15,
    .toys .b19 {
      background-color: #ececec;
      box-shadow: -1px -1px 6px inset #615f5f, 1px 1px 8px inset #ffffff;
    }

    .toys .b1 {
      grid-area: 3 / 5;
      top: -5px;
      left: 10px;
    }

    .toys .b2 {
      grid-area: 4 / 4;
      top: -5px;
      left: -5px;
    }

    .toys .b3 {
      grid-area: 4 / 6;
      top: -1px;
      left: 5px;
    }

    .toys .b4 {
      grid-area: 5 / 5;
      top: -8px;
      left: -3px;
    }

    .toys .b5 {
      grid-area: 6 / 2;
    }

    .toys .b6 {
      grid-area: 6 / 4;
      top: -10px;
      left: -10px;
    }

    .toys .b7 {
      grid-area: 6 / 6;
      top: -10px;
      left: -5px;
    }

    .toys .b8 {
      grid-area: 6 / 8;
      top: 2px;
      left: 5px;
    }

    .toys .b9 {
      grid-area: 7 / 1;
      top: 4px;
      left: 0px;
    }

    .toys .b10 {
      grid-area: 7 / 3;
      top: 3px;
      left: 3px;
    }

    .toys .b11 {
      grid-area: 7 / 5;
      top: -10px;
      left: -10px;
    }

    .toys .b12 {
      grid-area: 7 / 7;
      top: -4px;
      left: 3px;
    }

    .toys .b13 {
      grid-area: 8 / 2;
      top: 8px;
      left: 0px;
    }

    .toys .b14 {
      grid-area: 8 / 4;
      top: 5px;
      left: 5px;
    }

    .toys .b15 {
      grid-area: 8 / 6;
      top: -10px;
      left: -10px;
    }

    .toys .b16 {
      grid-area: 8 / 8;
      top: -3px;
      left: 17px;
    }

    .toys .b17 {
      grid-area: 9 / 1;
      top: 20px;
      left: 8px;
    }

    .toys .b18 {
      grid-area: 9 / 6;
      top: -5px;
      left: 20px;
    }

    .toys .b19 {
      grid-area: 9 / 10;
      top: 26px;
      left: -30px;
    }

    .toys .b20 {
      grid-area: 8 / 10;
      top: 24px;
      left: 0px;
    }

    .light {
      width: 3px;
      height: 3px;
      border-radius: 50%;
      position: absolute;
      background-color: #fff;
      animation: lights 1.5s ease-in infinite alternate;
    }

    .l1 {
      grid-area: 2 / 5;
      top: 5px;
      left: 5px;
    }

    .l2 {
      grid-area: 3 / 4;
      animation-delay: 0.4s;
    }

    .l3 {
      grid-area: 3/ 5;
      top: -5px;
      left: -5px;
      animation-delay: 0.6s;
    }

    .l4 {
      grid-area: 3 / 5;
      top: 15px;
      left: 0px;
      animation-delay: 0.8s;
    }

    .l5 {
      grid-area: 2 / 5;
      top: 5px;
      left: 5px;
      animation-delay: 1s;
    }

    .l7 {
      grid-area: 4 / 5;
      top: 5px;
      left: 15px;
    }

    .l8 {
      animation-delay: 0.4s;
      grid-area: 5 / 7;
      top: -10px;
      left: 10px;
    }

    .l9 {
      animation-delay: 0.6s;
      grid-area: 5 / 6;
    }

    .l10 {
      animation-delay: 0.8s;
      grid-area: 5 / 3;
      top: -5px;
      left: 15px;
    }

    .l11 {
      animation-delay: 1s;
      grid-area: 5 / 4;
      top: 5px;
      left: 10px;
    }

    .l12 {
      grid-area: 6 / 5;
      left: 5px;
    }

    .l13 {
      animation-delay: 0.4s;
      grid-area: 6 / 7;
      left: 5px;
      top: 3px;
    }

    .l14 {
      animation-delay: 0.6s;
      grid-area: 7 / 6;
      left: 5px;
    }

    .l15 {
      animation-delay: 0.8s;
      grid-area: 6 / 3;
      top: 8px;
    }

    .l16 {
      animation-delay: 1s;
      grid-area: 7 / 4;
    }

    .l17 {
      grid-area: 8 / 5;
    }

    .l18 {
      animation-delay: 0.4s;
      grid-area: 9 / 6;
    }

    .l19 {
      animation-delay: 0.6s;
      grid-area: 8 / 7;
      top: 5px;
      left: 7px;
    }

    .l20 {
      animation-delay: 0.8s;
      grid-area: 8 / 2;
      top: -15px;
      left: 5px;
    }

    .l21 {
      animation-delay: 1s;
      grid-area: 8/ 3;
      left: 5px;
      top: 5px;
    }

    .l22 {
      animation-delay: 0.4s;
      grid-area: 7 / 8;
      top: 15px;
      left: 20px;
    }

    .l23 {
      animation-delay: 0.6s;
      grid-area: 9 / 1;
      left: 15px;
      top: 15px;
    }

    .l24 {
      animation-delay: 0.8s;
      grid-area: 9 / 3;
    }

    .l25 {
      animation-delay: 1s;
      grid-area: 9 / 8;
      top: 5px;
      left: 15px;
    }

    .l6 {
      grid-area: 2 / 5;
      top: 10px;
      left: 20px;
    }

    @keyframes starLight {
      0% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 42%, rgba(255, 242, 173, 0.2) 58%, rgba(255, 255, 255, 0.1) 100%);
      }

      15% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 41%, rgba(255, 242, 173, 0.2) 59%, rgba(255, 255, 255, 0.1) 100%);
      }

      25% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 40%, rgba(255, 242, 173, 0.2) 60%, rgba(255, 255, 255, 0.1) 100%);
      }

      35% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 39%, rgba(255, 242, 173, 0.2) 61%, rgba(255, 255, 255, 0.1) 100%);
      }

      50% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 38%, rgba(255, 242, 173, 0.2) 62%, rgba(255, 255, 255, 0.1) 100%);
      }

      65% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 37%, rgba(255, 242, 173, 0.2) 63%, rgba(255, 255, 255, 0.1) 100%);
      }

      75% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 36%, rgba(255, 242, 173, 0.2) 64%, rgba(255, 255, 255, 0.1) 100%);
      }

      85% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 35%, rgba(255, 242, 173, 0.2) 65%, rgba(255, 255, 255, 0.1) 100%);
      }

      100% {
        background: radial-gradient(ellipse at center, gold 0%, rgba(255, 240, 158, 0.5) 34%, rgba(255, 242, 173, 0.2) 66%, rgba(255, 255, 255, 0.1) 100%);
      }
    }

    @keyframes lights {
      0% {
        box-shadow: 0 0 0px 0px #fff;
      }

      25% {
        box-shadow: 0 0 1px 1px #fff;
      }

      50% {
        box-shadow: 0 0 2px 2px #fff;
      }

      75% {
        box-shadow: 0 0 3px 3px #fff;
      }

      100% {
        box-shadow: 0 0 4px 4px #fff;
      }
    }
  </style>
</head>

<body>
    <ul class="bgg">
      <li class="sphere"></li>
      <p class="text">hangover~圣诞快乐</p>
    </ul>
    <ul class="tree">
      <li class="top-star"> </li>
      <li class="top">
        <ul class="tree-pts">
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
        </ul>
      </li>
      <li class="middle first">
        <ul class="tree-pts">
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
        </ul>
      </li>
      <li class="middle second">
        <ul class="tree-pts">
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
        </ul>
      </li>
      <li class="middle third">
        <ul class="tree-pts">
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
        </ul>
      </li>
      <li class="bottom outer">
        <ul class="tree-pts">
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts left"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
          <li class="pts right"></li>
        </ul>
      </li>
      <li class="stem">
        <ul class="tree-stem">
          <li class="stem"></li>
          <li class="gift g1"></li>
          <li class="gift g2"></li>
          <li class="gift g3"></li>
          <li class="gift g4"></li>
          <li class="gift g5"></li>
          <li class="gift g6"></li>
          <li class="gift g7"></li>
          <li class="gift g8"></li>
          <li class="gift g9"></li>
          <li class="shadow"></li>
        </ul>
      </li>
    </ul>
    <ul class="toys">
      <li class="star"></li>
      <li class="ball b1"></li>
      <li class="ball b2"></li>
      <li class="ball b3"></li>
      <li class="ball b4"></li>
      <li class="ball b5"></li>
      <li class="ball b6"></li>
      <li class="ball b7"></li>
      <li class="ball b8"></li>
      <li class="ball b9"></li>
      <li class="ball b10"></li>
      <li class="ball b11"></li>
      <li class="ball b12"></li>
      <li class="ball b13"></li>
      <li class="ball b14"></li>
      <li class="ball b15"></li>
      <li class="ball b16"></li>
      <li class="ball b17"></li>
      <li class="ball b18"></li>
      <li class="ball b19"></li>
      <li class="ball b20"></li>
      <li class="light l1"></li>
      <li class="light l2"></li>
      <li class="light l3"></li>
      <li class="light l4"></li>
      <li class="light l5"></li>
      <li class="light l6"></li>
      <li class="light l7"></li>
      <li class="light l8"></li>
      <li class="light l9"></li>
      <li class="light l10"></li>
      <li class="light l11"></li>
      <li class="light l12"></li>
      <li class="light l13"></li>
      <li class="light l14"></li>
      <li class="light l15"></li>
      <li class="light l16"></li>
      <li class="light l17"></li>
      <li class="light l18"></li>
      <li class="light l19"></li>
      <li class="light l20"></li>
      <li class="light l21"></li>
      <li class="light l22"></li>
      <li class="light l23"></li>
      <li class="light l24"></li>
      <li class="light l25"></li>
    </ul>
</body>

</html>
  • 50
    点赞
  • 279
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值