前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用coding向你最爱的人说圣诞快乐

用coding向你最爱的人说圣诞快乐

作者头像
鱼找水需要时间
发布2023-02-16 20:15:33
3590
发布2023-02-16 20:15:33
举报
文章被收录于专栏:SpringBoot教程

文章目录

🎄🎄🎄圣诞节即将到来,今天让我们用编码的方式向你最爱的人表达圣诞节快乐

圣诞节的起源

 圣诞节源自古罗马人迎接新年的农神节,与基督教本无关系。在基督教盛行罗马帝国后,教廷将这种民俗节日纳入基督教体系,同时以庆祝耶稣的降生。但在圣诞节这天不是耶稣的生辰,因为《圣经》未记载耶稣具体出生时间,同样没提到过有此种节日,是基督教吸收了古罗马神话的结果。

 圣诞节是西方传统节日,也是许多西方国家一年中最重要的节日。每年这一天,欢快的圣诞歌在大街小巷飘扬,商场里流光溢彩,琳琅满目,到处弥漫着温馨欢乐的气息。孩子们在甜美的梦乡中,盼望着圣诞老人从天而降,带来梦寐以求的礼物。

 平安夜和圣诞节现在很多人都在过,对于很多人而言,并不是在做一个所谓的洋节,而是在这一天让自己爱的人和爱我们的人开心,正如网络上流行的一句话:“ 世界上本没有圣诞老人,所有的惊喜和礼物都来自于爱你的人。

圣诞祝福语

🎄 Merry Christmas

🎄今年圣诞老人🎅🏻也很忙喔

所以轮到我把圣诞惊喜给你咯!

🎄今天扎了个蝴蝶结,像不像你的圣诞礼物。

圣诞节没有领到礼物的到我这里领个37°的拥抱吧🎅🏻

🎄蟹蟹圣诞老公公,送礼全世界最棒的礼物给我,就是把你放进我心里。

麋鹿不会迷路,圣诞之礼,终将准时送达。🎅🏻

多少人,一夜之间,没穿圣诞装,却成了圣诞老人。🎅🏻

把我的小心思,偷偷塞进礼物盒,在圣诞节那一天,通通送给你

圣诞有我,要开心哦(• . •)

我想和你一起看夜景 一起吃热热的烤火鸡 一起许愿 看着那会发光的圣诞树 一起倒数

你快跳进圣诞老人的背包里 一觉醒来你就是我的礼物

想给每个善良的人一顶圣诞帽 愿这顶帽子成为他们的睡帽 从此每个安睡的日子都叫平安夜

希望圣诞树 和你一起到来🎄

圣诞快乐,喜乐长安。🎄

用 coding 说圣诞快乐

Canvas 渲染 圣诞树特效

index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ChristmasTree</title>
    <style>
        html,
        body {
            margin: 0;
            width: 100%;
            height: 100%
        }
        body {
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: black;
            position: relative;
            overflow-x: hidden;
            overflow-y: hidden;
        }
        .snow-container {
            position: absolute;
            width: 400px;
            height: 550px;
            color: white;
        }
        @media screen and (max-width: 450px) {
            .snow-container {
                width: 100%;
            }
        }
        .snow-box {
            position: relative;
            width: 100%;
            height: 100%;
        }
        .snow {
            position: absolute;
            animation: 5s snow linear infinite;
        }
        @keyframes snow {
            0% {
                left: 0;
                top: 0
            }
            80% {
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow2 {
            left: 5%;
            top: 2%;
            position: absolute;
            animation: 10s snow2 ease-in infinite;
        }
        @keyframes snow2 {
            0% {
                left: 5%;
                top: 2%;
            }
            80% {
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow3 {
            left: 10%;
            top: 8%;
            position: absolute;
            animation: 8s snow3 ease-out infinite;
        }
        @keyframes snow3 {
            0% {
                left: 5%;
                top: 2%;
            }
            80% {
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow4 {
            left: 18%;
            top: 18%;
            position: absolute;
            animation: 7s snow4 ease-out infinite;
        }
        @keyframes snow4 {
            0% {
                left: 18%;
                top: 18%;
            }
            80% {
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow5 {
            left: 59%;
            top: 1%;
            position: absolute;
            animation: 6s snow4 ease infinite;
        }
        @keyframes snow5 {
            0% {
                left: 75%;
                top: 18%;
            }
            80% {
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow6 {
            left: 65%;
            top: 5%;
            position: absolute;
            animation: 6s snow6 ease-in infinite;
        }
        @keyframes snow6 {
            0% {
                left: 75%;
                top: 18%;
            }
            80% {
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow7 {
            left: 75%;
            top: 18%;
            position: absolute;
            animation: 11s snow5 ease infinite;
        }
        @keyframes snow7 {
            0% {
                left: 75%;
                top: 18%;
            }
            80% {
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow8 {
            left: 90%;
            top: 40%;
            position: absolute;
            animation: 5s snow8 ease-out infinite;
        }
        @keyframes snow8 {
            0% {
                left: 90%;
                top: 20%;
            }
            80% {
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow9 {
            left: 50%;
            top: 10%;
            position: absolute;
            animation: 5s snow9 ease-out infinite;
        }
        @keyframes snow9 {
            0% {
                left: 85%;
                top: 20%;
            }
            80% {
                left: 50%;
                top: 90%
            }
            100% {
                top: 90%
            }
        }
        .snow10 {
            left: 100%;
            top: 10%;
            position: absolute;
            animation: 7s snow10 ease infinite;
        }
        @keyframes snow10 {
            0% {
                left: 100%;
                top: 10%;
            }
            80% {
                left: 50%;
                top: 90%
            }
            100% {
                left: 50%;
                top: 90%
            }
        }
        .text {
            font-size: 40px;
            color: #f1ebe5;
            text-shadow: 0 8px 9px #c4b59d, 0px -2px 1px #fff;
            font-weight: bold;
            letter-spacing: 2px;
            text-align: center;
            position: absolute;
            white-space: nowrap;
            left: 50%;
            transform: translate(-50%, -50%);
        }
    </style>
</head>

<body>
    <div class="snow-container">
        <div class="snow-box">
            <span class="snow">*</span>
            <span class="snow2">*</span>
            <span class="snow3">*</span>
            <span class="snow4">*</span>
            <span class="snow5">*</span>
            <span class="snow6">*</span>
            <span class="snow7">*</span>
            <span class="snow8">*</span>
            <span class="snow9">*</span>
            <span class="snow10">*</span>
        </div>

        <div class="text">鱼找水的🎄</div>
    </div>
    <canvas id="canvas" width="375" height="500"></canvas>
    <script src="./assets/index.js">
    </script>
    <script>
        new ChristmasTree().renderTree()
    </script>
</body>

</html>

index.js

代码语言:javascript
复制
class ChristmasTree {
    constructor() {
        this.side = 20
        this.gap = 6 + this.side
        this.init()
        this.treeData = []
    }

    init() {
        this.canvas = document.querySelector('#canvas')
        this.ctx = this.canvas.getContext('2d')
        const { width, height } = this.canvas
        this.width = width
        this.height = height
        this.ctx.fillStyle = 'rgb(0, 0, 0)'
        this.ctx.fillRect(0, 0, width, height)
    }

    createArc(x, y, color) {
        this.ctx.beginPath()
        this.ctx.fillStyle = color
        this.ctx.arc(x, y, this.side / 2, 0, Math.PI * 2, false)
        this.ctx.fill()
    }

    createRect(x, y, color) {
        this.ctx.fillStyle = color
        this.ctx.fillRect(x, y, this.side, this.side)
    }

    createPentastar(x, y, color) {
        this.ctx.beginPath()
        const R = this.gap / 2,
            r = this.gap / 5

        for (var i = 0; i < 5; i++) {
            this.ctx.lineTo(
                Math.cos(((18 + i * 72) / 180) * Math.PI) * R + x, -Math.sin(((18 + i * 72) / 180) * Math.PI) * R + y
            )
            this.ctx.lineTo(
                Math.cos(((54 + i * 72) / 180) * Math.PI) * r + x, -Math.sin(((54 + i * 72) / 180) * Math.PI) * r + y
            )
        }
        this.ctx.closePath()
        this.ctx.lineWidth = '3'
        this.ctx.fillStyle = color
        this.ctx.fill()
    }

    buildTreeCrown(startNodeNum, rowsNum, startHeight) {
        const arr = []
        const midRect = this.width / 2 - this.side / 2
        const midArc = this.width / 2
        for (let i = 0; i < rowsNum; i++) {
            for (let j = 0; j < startNodeNum; j++) {
                if (rowsNum - i === 2 && startNodeNum - j <= 2) {
                    arr.push({
                        type: 'start',
                        x: midArc + (j % 2 === 0 ? (-this.gap * j) / 2 : (+(j + 1) / 2) * this.gap),
                        y: startHeight + this.gap * i + this.side / 2,
                        color: rowsNum - i === 1 ? 'red' : 'yellow'
                    })
                } else if (rowsNum - i === 1 && startNodeNum - j <= 2) {
                    arr.push({
                        type: 'arc',
                        x: midArc + (j % 2 === 0 ? (-this.gap * j) / 2 : (+(j + 1) / 2) * this.gap),
                        y: startHeight + this.gap * i + this.side / 2,
                        color: 'red'
                    })
                } else {
                    arr.push({
                        type: 'rect',
                        x: midRect + (j % 2 === 0 ? (-this.gap * j) / 2 : (+(j + 1) / 2) * this.gap),
                        y: startHeight + this.gap * i,
                        color: i === rowsNum - 1 && startNodeNum - j >= 7 ? 'red' : 'green'
                    })
                }
            }
            if (i === rowsNum - 3) {
                startNodeNum += 4
            } else {
                startNodeNum += 2
            }
        }
        return arr
    }

    buildTreeStump(row, col, gapRow) {
        const arr = []
        const midRect = this.width / 2 - this.side / 2
        for (let i = 0; i < row; i++) {
            for (let j = 0; j < col; j++) {
                arr.push({
                    type: 'rect',
                    x: midRect + (j % 2 === 0 ? (-this.gap * j) / 2 : (+(j + 1) / 2) * this.gap),
                    y: (gapRow + i) * this.gap,
                    color: 'rgb(67, 11, 0)'
                })
            }
        }
        return arr
    }

    setTreeData() {
        const _this = this
        let gapRow = 1

        this.treeData = [{
                type: 'start',
                x: this.width / 2,
                y: this.side / 2 + 2,
                color: 'yellow'
            },
            ...setTreeCrownData(3),
            ...this.buildTreeStump(5, 3, gapRow)
        ]

        function setTreeCrownData(crownNum) {
            const arr = []
            let indexNode = 1
            let rowsNum = 4

            for (let i = 0; i < crownNum; i++) {
                arr.push(..._this.buildTreeCrown(indexNode, rowsNum, _this.gap * gapRow))
                indexNode += 2
                gapRow += rowsNum
            }
            return arr
        }
    }

    renderTree() {
        this.setTreeData()
        for (const item of this.treeData) {
            if (item.type === 'arc') {
                const { x, y, color } = item
                this.createArc(x, y, color)
            } else if (item.type === 'rect') {
                const { x, y, color } = item
                this.createRect(x, y, color)
            } else if (item.type === 'start') {
                const { x, y, color } = item
                this.createPentastar(x, y, color)
            }
        }
    }
}

唯美圣诞树

在线演示,加载比较慢

里边用到的音乐自己下载,修改变量const files为对应mp3的路径

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <title>Musical Christmas Lights</title>

  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

  <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;
    }

    #tree-text {
      position: absolute;
      top: 18vh;

      width: 100vw;
      line-height: 5vh;

      text-align: center;
      color: #fab1a0;
      font-size: x-large;
      font-family: "Lucida Console", "Courier New", monospace;
      opacity: 1;
      font-weight: bold;

      color: transparent;
      background: linear-gradient(45deg, #fab1a0 35%, #ff7675, #e17055 60%);
      background-size: cover;
      -webkit-background-clip: text;
      -ms-background-clip: text;
      -moz-background-clip: text;
      -o-background-clip: text;
    }

    @keyframes gradually-appear {
      from {
        opacity: 0;
      }

      to {
        opacity: 1;
      }
    }

    .show {
      display: block;
      animation-name: gradually-appear;
      animation-duration: 8s;
    }

    .hide {
      display: none;
    }
  </style>

  <script>
    window.console = window.console || function (t) { };
  </script>



  <script>
    if (document.location.search.match(/type=embed/gi)) {
      window.parent.postMessage("resize", "*");
    }
  </script>


</head>

<body translate="no">
  <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">宝贝,选一首喜欢的歌吧</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  style="display: none;" class="separator">或者</li>
      <li style="display: none;">
        <input type="file" id="upload" hidden />
        <label for="upload">Upload File</label>
      </li>
    </ul>
  </div>

  <div id="tree-text" class="hide">
    祝我最爱的girl圣诞节快乐
    <br />
    希望能与你度过以后的每一个圣诞节,I ❤️ you~
  </div>

  <script id="rendered-js">
    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();
      document.getElementById("tree-text").className = "show";

      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">正在下载音乐,请稍等...</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 files = ["./music/Simon_Panrucker_-_01_-_Snowflakes_Falling_Down.mp3",
        "./music/Dott_-_01_-_This_Christmas.mp3",
        "./music/TRG_Banks_-_12_-_No_room_at_the_inn.mp3",
        "./music/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">请稍等...</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>

</body>

</html>

CSS实现圣诞树

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width= , initial-scale=1.0">
    <title>圣诞树</title>
    <!-- <link rel="stylesheet" href="index.css"> -->
    <style>
        html,
        body {
            width: 100%;
            height: 100%;
        }
        * {
            margin: 0;
            padding: 0;
        }
        body {
            background-color: #020024;
        }
        .word {
            font-size: 22px;
            text-align: center;
            color: gold;
            padding-top: 50px;
            letter-spacing: 5px;
            text-shadow: 2px 4px 9px rgba(255, 255, 255, 0.7);
        }
        /* 圣诞树外层div */
        .tree {
            width: 200px;
            height: 300px;
            margin: 80px auto 0 auto;
            position: relative;
            /*相对定位*/
            /* border: 1px solid #fff; */
        }
        .star {
            width: 50px;
            height: 50px;
            position: absolute;
            background-color: #fff;
            border-radius: 50%;
            -webkit-border-radius: 50%;
            -moz-border-radius: 50%;
            -ms-border-radius: 50%;
            -o-border-radius: 50%;
            top: -25px;
            z-index: 1000;
            left: 50%;
            transform: translate(-50%);
            -webkit-transform: translate(-50%);
            -moz-transform: translate(-50%);
            -ms-transform: translate(-50%);
            -o-transform: translate(-50%);
            animation: starLight 1.5s ease infinite alternate;
            -webkit-animation: starLight 1.5s ease infinite alternate;
        }
        .star-in {
            position: absolute;
            left: 50%;
            top: 50%;
            border-right: 100px solid transparent;
            border-bottom: 70px solid gold;
            border-left: 100px solid transparent;
            transform: translateX(-50%) translateY(-50%) rotate(35deg) scale(0.14);
            -webkit-transform: translateX(-50%) translateY(-50%) rotate(35deg) scale(0.14);
            -moz-transform: translateX(-50%) translateY(-50%) rotate(35deg) scale(0.14);
            -ms-transform: translateX(-50%) translateY(-50%) rotate(35deg) scale(0.14);
            -o-transform: translateX(-50%) translateY(-50%) rotate(35deg) scale(0.14);
        }
        .star-in::before {
            border-right: 30px solid transparent;
            border-bottom: 80px solid gold;
            border-left: 30px solid transparent;
            position: absolute;
            top: -45px;
            left: -65px;
            content: '';
            transform: rotate(-35deg);
            -webkit-transform: rotate(-35deg);
            -moz-transform: rotate(-35deg);
            -ms-transform: rotate(-35deg);
            -o-transform: rotate(-35deg);
        }
        .star-in::after {
            border-right: 100px solid transparent;
            border-bottom: 70px solid gold;
            border-left: 100px solid transparent;
            position: absolute;
            top: 3px;
            left: -105px;
            content: '';
            transform: rotate(-70deg);
            -webkit-transform: rotate(-70deg);
            -moz-transform: rotate(-70deg);
            -ms-transform: rotate(-70deg);
            -o-transform: rotate(-70deg);
        }
        @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%);
            }

            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%);
            }

            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%);
            }

            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%);
            }

            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%);
            }

        }
        .leaf {
            position: absolute;
            left: 50%;
            top: 3%;
            margin-left: -30px;
            background-color: rgba(14, 110, 14);
            width: 60px;
            height: 60px;
            border-radius: 0 10px 35px 10px;
            -webkit-border-radius: 0 10px 35px 10px;
            -moz-border-radius: 0 10px 35px 10px;
            -ms-border-radius: 0 10px 35px 10px;
            -o-border-radius: 0 10px 35px 10px;
            transform: rotate(45deg);
            -webkit-transform: rotate(45deg);
            -moz-transform: rotate(45deg);
            -ms-transform: rotate(45deg);
            -o-transform: rotate(45deg);
            box-shadow: 2px 7px 2px rgba(43, 43, 43, 0.2);
        }
        .edge {
            position: absolute;
            left: 0;
            bottom: 0;
            background: rgba(14, 110, 14);
            width: 25px;
            height: 30px;
            border-radius: 0 10px 35px 10px;
            -webkit-border-radius: 0 10px 35px 10px;
            -moz-border-radius: 0 10px 35px 10px;
            -ms-border-radius: 0 10px 35px 10px;
            -o-border-radius: 0 10px 35px 10px;
            transform: translateY(50%) translateX(0);
            -webkit-transform: translateY(50%) translateX(0);
            -moz-transform: translateY(50%) translateX(0);
            -ms-transform: translateY(50%) translateX(0);
            -o-transform: translateY(50%) translateX(0);
        }
        .edge.right {
            position: absolute;
            left: unset;
            bottom: unset;
            top: 0;
            right: 0;
            background: rgba(14, 110, 14);
            width: 25px;
            height: 30px;
            border-radius: 0 10px 35px 10px;
            -webkit-border-radius: 0 10px 35px 10px;
            -moz-border-radius: 0 10px 35px 10px;
            -ms-border-radius: 0 10px 35px 10px;
            -o-border-radius: 0 10px 35px 10px;
            transform: translateY(0) translateX(50%);
            -webkit-transform: translateY(0) translateX(50%);
            -moz-transform: translateY(0) translateX(50%);
            -ms-transform: translateY(0) translateX(50%);
            -o-transform: translateY(0) translateX(50%);
        }
        /* 双数修改背景颜色 */
        .leaf:nth-child(even) {
            background-color: #0f880f;
        }
        .leaf:nth-child(even) .edge {
            background-color: #0f880f;
        }
        /* 最上面 */
        .leaf:nth-child(1) {
            z-index: 100;
            transform: rotate(45deg) scale(0.8);
            -webkit-transform: rotate(45deg) scale(0.8);
            -moz-transform: rotate(45deg) scale(0.8);
            -ms-transform: rotate(45deg) scale(0.8);
            -o-transform: rotate(45deg) scale(0.8);
        }
        /* 第二 */
        .leaf:nth-child(2) {
            z-index: 99;
            top: 15%;
            transform: rotate(45deg) scale(1.3);
            -webkit-transform: rotate(45deg) scale(1.3);
            -moz-transform: rotate(45deg) scale(1.3);
            -ms-transform: rotate(45deg) scale(1.3);
            -o-transform: rotate(45deg) scale(1.3);
        }
        .leaf:nth-child(3) {
            z-index: 98;
            top: 28%;
            transform: rotate(45deg) scale(1.6);
            -webkit-transform: rotate(45deg) scale(1.6);
            -moz-transform: rotate(45deg) scale(1.6);
            -ms-transform: rotate(45deg) scale(1.6);
            -o-transform: rotate(45deg) scale(1.6);
        }
        .leaf:nth-child(4) {
            z-index: 97;
            top: 41%;
            transform: rotate(45deg) scale(1.9);
            -webkit-transform: rotate(45deg) scale(1.9);
            -moz-transform: rotate(45deg) scale(1.9);
            -ms-transform: rotate(45deg) scale(1.9);
            -o-transform: rotate(45deg) scale(1.9);
        }
        .leaf:nth-child(5) {
            z-index: 96;
            top: 54%;
            transform: rotate(45deg) scale(2.2);
            -webkit-transform: rotate(45deg) scale(2.2);
            -moz-transform: rotate(45deg) scale(2.2);
            -ms-transform: rotate(45deg) scale(2.2);
            -o-transform: rotate(45deg) scale(2.2);
        }
        .trunk {
            width: 25px;
            height: 45px;
            border-radius: 0 0 3px 3px;
            -webkit-border-radius: 0 0 3px 3px;
            -moz-border-radius: 0 0 3px 3px;
            -ms-border-radius: 0 0 3px 3px;
            -o-border-radius: 0 0 3px 3px;
            position: absolute;
            left: 50%;
            transform: translateX(-50%);
            -webkit-transform: translateX(-50%);
            -moz-transform: translateX(-50%);
            -ms-transform: translateX(-50%);
            -o-transform: translateX(-50%);
            bottom: 20px;
            z-index: 1;
            box-shadow: 0 0 10px 5px rgb(19, 19, 19);
            background: linear-gradient(0deg, #6d411b 0%, #5a341d 64%);
        }
        .ball {
            width: 20px;
            height: 20px;
            background: #f00;
            box-shadow: -1px -1px 6px inset #600, 1px 1px 8px inset #ffc9c9;
            border-radius: 50%;
            -webkit-border-radius: 50%;
            -moz-border-radius: 50%;
            -ms-border-radius: 50%;
            -o-border-radius: 50%;
            z-index: 101;
            position: absolute;
        }
        .b1 {
            left: 25%;
            top: 30%;
        }
        .b2 {
            left: 35%;
            top: 50%;
        }
        .b3 {
            left: 65%;
            top: 20%;
        }
        .b4 {
            left: 45%;
            top: 22%;
        }
        .b5 {
            left: 40%;
            top: 72%;
        }
        .b6 {
            left: 60%;
            top: 52%;
        }
        .b7 {
            left: 50%;
            top: 62%;
        }
        .b8 {
            left: 80%;
            top: 42%;
        }
        .b9 {
            left: 10%;
            top: 62%;
        }
        .b4,
        .b5,
        .b6 {
            background: #ececec;
            box-shadow: -1px -1px 6px inset #615f5f, 1px 1px 8px inset #fff;
        }
        .b7,
        .b8,
        .b9 {
            background: gold;
            box-shadow: -1px -1px 6px inset #3a3101, 1px 1px 8px inset #fff;
        }
        .sparkle span {
            display: block;
            position: absolute;
            font-size: 20px;
            z-index: 101;
            color: #fff;
            animation: lights 1.5s ease infinite alternate;
            -webkit-animation: lights 1.5s ease infinite alternate;
        }
        /* 闪烁动画 */
        @keyframes lights {

            0%,
            100% {
                transform: scale(1);
                -webkit-transform: scale(1);
                -moz-transform: scale(1);
                -ms-transform: scale(1);
                -o-transform: scale(1);
            }

            50% {
                transform: scale(1.5);
                -webkit-transform: scale(1.5);
                -moz-transform: scale(1.5);
                -ms-transform: scale(1.5);
                -o-transform: scale(1.5);
            }
        }
        .sparkle span:nth-child(1) {
            left: 30%;
            top: 40%;
        }
        .sparkle span:nth-child(2) {
            left: 40%;
            top: 27%;
            font-size: 15px;
        }
        .sparkle span:nth-child(3) {
            left: 50%;
            top: 57%;
            font-size: 12px;
        }
        .sparkle span:nth-child(4) {
            left: 70%;
            top: 67%;
            font-size: 14px;
        }
        .sparkle span:nth-child(5) {
            left: 74%;
            top: 13%;
            font-size: 16px;
        }
        .blink div {
            width: 3px;
            height: 3px;
            background: #fff;
            z-index: 101;
            position: absolute;
            border-radius: 50%;
            -webkit-border-radius: 50%;
            -moz-border-radius: 50%;
            -ms-border-radius: 50%;
            -o-border-radius: 50%;
            animation: blink 1.5s ease infinite alternate;
            -webkit-animation: blink 1.5s ease infinite alternate;
        }
        .blink div:nth-child(2) {
            left: 34%;
            top: 13%;
            transform: scale(1.2);
            -webkit-transform: scale(1.2);
            -moz-transform: scale(1.2);
            -ms-transform: scale(1.2);
            -o-transform: scale(1.2);
        }
        .blink div:nth-child(3) {
            left: 54%;
            top: 43%;
            transform: scale(0.6);
            -webkit-transform: scale(0.6);
            -moz-transform: scale(0.6);
            -ms-transform: scale(0.6);
            -o-transform: scale(0.6);
        }
        .blink div:nth-child(4) {
            left: 64%;
            top: 33%;
            transform: scale(1.4);
            -webkit-transform: scale(1.4);
            -moz-transform: scale(1.4);
            -ms-transform: scale(1.4);
            -o-transform: scale(1.4);
        }
        .blink div:nth-child(5) {
            left: 34%;
            top: 63%;
            transform: scale(1.8);
            -webkit-transform: scale(1.8);
            -moz-transform: scale(1.8);
            -ms-transform: scale(1.8);
            -o-transform: scale(1.8);
        }
        .blink div:nth-child(6) {
            left: 14%;
            top: 76%;
            transform: scale(1.5);
            -webkit-transform: scale(1.5);
            -moz-transform: scale(1.5);
            -ms-transform: scale(1.5);
            -o-transform: scale(1.5);
        }
        @keyframes blink {
            0% {
                box-shadow: 0 0 0 0 #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;
            }
        }

        .yy {
            position: absolute;
            top: 80%;
            right: 0%;
        }
    </style>

</head>

<body>
    <p class="word">
        圣诞树
    </p>
    <div class="tree">
        <div class="star">
            <div class="star-in"></div>
        </div>
        <!-- 树叶 -->
        <div class="leaf-box">
            <div class="leaf">
                <div class="edge"></div>
                <div class="edge right"></div>
            </div>
            <div class="leaf">
                <div class="edge"></div>
                <div class="edge right"></div>
            </div>
            <div class="leaf">
                <div class="edge"></div>
                <div class="edge right"></div>
            </div>
            <div class="leaf">
                <div class="edge"></div>
                <div class="edge right"></div>
            </div>
            <div class="leaf">
                <div class="edge"></div>
                <div class="edge right"></div>
            </div>
        </div>
        <!-- 树干 -->
        <div class="trunk"></div>
        <!-- 彩色的球 -->
        <div class="ball-box">
            <div class="ball b1"></div>
            <div class="ball b2"></div>
            <div class="ball b3"></div>
            <div class="ball b4"></div>
            <div class="ball b5"></div>
            <div class="ball b6"></div>
            <div class="ball b7"></div>
            <div class="ball b8"></div>
            <div class="ball b9"></div>
        </div>
        <!-- 闪烁 -->
        <div class="sparkle">
            <span>★</span>
            <span>★</span>
            <span>★</span>
            <span>★</span>
            <span>★</span>
            <span>★</span>
        </div>
        <div class="blink">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>

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

简易的圣诞树

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <title>鱼找水的圣诞树</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
    <style type="text/css">
        body{
            background-color: #020024;
        }
        #app{
            display:flex;
            justify-content:center;
            height: 100vh;
        }
        .shendanshu {
            display: flex;
            justify-content: center;
            width: 1000px;
            max-width: 100vw;
            flex-direction: column;
            align-items: center;
        }

        .shuceng {
            display: flex;
            flex-direction: row;
            overflow: hidden;
            justify-content: center;
        }

        .shuye {
            position: relative;
            height: 46px;
        }

        .ye {
            width: 0;
            height: 0;
            border: 30px solid;
            border-color: transparent transparent green;
            border-top-width: 6px;
        }

        .caideng {
            position: absolute;
            bottom: 0px;
            left: 22px;
            width: 16px;
            height: 16px;
            background: red;
            border-radius: 40px;
            animation: dengguangxiaoguo 1s linear infinite alternate;
        }
        .caideng1{
            animation-delay:-0.25s;
        }
        .caideng2{
            animation-delay:-0.5s;
        }
        .caideng3{
            animation-delay:-0.75s;
        }

        .shugan {
            background-color: #795548;
            height: 60px;
            width: 100px;
        }

        .tudi {
            background: #FFC107;
            height: 20px;
            width: 500px;
            max-width: 80vw;
            border-radius: 20px 20px 0px 0px;
        }

        @keyframes dengguangxiaoguo {
            0% {
                background-color: #fff;
            }

            25% {
                background-color: blue;
            }

            50% {
                background-color: red;
            }

            75% {
                background-color: yellow;
            }

            100% {
                background-color: #fff;
            }
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 圣诞树 -->
        <div class="shendanshu">
            <!-- 树叶区域 -->
            <div class="shuceng" v-for="arr_shuye in arr_shengdanshu">
                <div class="shuye" v-for="shuye in arr_shuye">
                    <div class="ye"></div>
                    <div class="caideng" v-bind:class="shuye.caideng"></div>
                </div>
            </div>
            <!-- 树干 -->
            <div class="shugan"></div>
            <!-- 土地 -->
            <div class="tudi">
                <a style="width:100%;text-align:center;display: inline-block;" href="https://github.com/mengmeng1009/shengdanshu"></a>
            </div>
        </div>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                arr_shengdanshu: []
            },
            created: function () {
                for (let i = 0; i < 9; i++) {
                    let arr_shuye = [];
                    for (let j = 0; j < i + 1; j++) {
                        let shuye = { js: j, caideng: "caideng" + Math.ceil(Math.random() * 4) }
                        arr_shuye.push(shuye)
                    }
                    this.arr_shengdanshu.push(arr_shuye)
                }
            }
        })
    </script>
</body>
</html>

线性树

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>🎄</title>
    <script type='text/javascript'>
      onload = function() {
        var click_cnt = 0;
        var $html = document.getElementsByTagName("html")[0];
        var $body = document.getElementsByTagName("body")[0];
        $html.onclick = function(e) {
          var $elem = document.createElement("b");
          $elem.style.color = "#E94F06";
          $elem.style.zIndex = 9999;
          $elem.style.position = "absolute";
          $elem.style.select = "none";
          var x = e.pageX;
          var y = e.pageY;
          $elem.style.left = (x - 10) + "px";
          $elem.style.top = (y - 20) + "px";
          clearInterval(anim);
          switch (++click_cnt) {
            case 10:
              $elem.innerText = "OωO";
              break;
            case 20:
              $elem.innerText = "(๑•́ ∀ •̀๑)";
              break;
            case 30:
              $elem.innerText = "(๑•́ ₃ •̀๑)";
              break;
            case 40:
              $elem.innerText = "(๑•̀_•́๑)";
              break;
            case 50:
              $elem.innerText = "( ̄へ ̄)";
              break;
            case 60:
              $elem.innerText = "(╯°口°)╯(┴—┴";
              break;
            case 70:
              $elem.innerText = "૮( ᵒ̌皿ᵒ̌ )ა";
              break;
            case 80:
              $elem.innerText = "╮(。>口<。)╭";
              break;
            case 90:
              $elem.innerText = "( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃";
              break;
            case 100:
            case 101:
            case 102:
            case 103:
            case 104:
            case 105:
              $elem.innerText = "(ꐦ°᷄д°᷅)";
              break;
            default:
              $elem.innerText = "❤";
              break;
          }
          $elem.style.fontSize = Math.random() * 10 + 8 + "px";
          var increase = 0;
          var anim;
          setTimeout(function() {
            anim = setInterval(function() {
              if (++increase == 150) {
                clearInterval(anim);
                $body.removeChild($elem);
              }
              $elem.style.top = y - 20 - increase + "px";
              $elem.style.opacity = (150 - increase) / 120;
            }, 8);
          }, 70);
          $body.appendChild($elem);
        };
      };

    </script>
    <style>
        * {
            padding: 0;
            margin: 0;
            list-style: none;
        }

        body {
            display: flex;
            height: 100vh;
            justify-content: center;
            align-items: center;
            background-color: rgb(54, 66, 70);
        }

        .tree {
            position: relative;
            width: 500px;
            height: 700px;
            display: flex;
            justify-content: center;
        }
        /*绘制星星*/
        .star {
            width: 50px;
            height: 50px;
            position: absolute;
            background-color: rgb(236, 234, 167);
            z-index: 999;
            clip-path: polygon(50% 0, 65% 40%, 100% 40%, 72% 60%,
                    85% 100%, 50% 75%, 15% 100%, 28% 60%, 0 40%, 35% 40%);
        }
        .tree li{
            position: absolute;
            top: 25px;
            width: 2px;
            /*颜色渐变*/
            background: linear-gradient(rgba(46,204,113,0),rgba(46,204,113,.25));
            transform-origin: 0 0;
            /*按照规定的动画 4秒内播放完毕 低速开始和结束 无限次播放*/
            animation: swing 10s ease-in-out infinite;
            height: calc(var(--i)*4px);
            /*动画开始前的等待时间*/
            animation-delay:calc(var(--i)*-0.23s);
        }

        @keyframes swing{
            0%,
            100%{
                transform: rotate(-30deg);
            }
            0%{
                opacity: 1;
            }
            5%,45%{
                opacity: 0.25;
            }
            50%,100%{
                opacity: 1;
            }
            50%{
                transform: rotate(30deg);
            }
        }
        .tree li::before{
            content: '';
            font-size: 1px;
            position: absolute;
            left: -1px;
            bottom: 1px;
            width: 3px;
            height: 3px;
        }
        .tree li:nth-child(4n)::before{
            background-color: #D8334A;
            color: #D8334A;
        }
        .tree li:nth-child(4n+1)::before{
            background-color: #FFCE54;
            color: #FFCE54
        }
        .tree li:nth-child(4n+2)::before{
            background-color: #2ECC71;
            color: #2ECC71
        }
        .tree li:nth-child(4n+3)::before{
            background-color: #5D9CEC;
            color: #5D9CEC
        }


    </style>
</head>

<body>
    <ul class="tree">
        <div class="star"></div>
    </ul>
</body>
<script>
    let tree = document.querySelector('.tree')
    for (let i = 0; i < 128; i++) {
        let li = document.createElement('li')
        li.style = "--i:" + i
        tree.appendChild(li)
    }
</script>
</html>

卡片圣诞树

这个代码文件比较多,就不贴了。有需要的可以评论私聊,以后会上传到资源

到此,本章内容就介绍完啦。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 圣诞节的起源
  • 圣诞祝福语
  • 用 coding 说圣诞快乐
    • Canvas 渲染 圣诞树特效
      • 唯美圣诞树
        • CSS实现圣诞树
          • 简易的圣诞树
            • 线性树
              • 卡片圣诞树
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档