Detailed explanation of dynamic Christmas tree through JavaScript

Detailed explanation of dynamic Christmas tree through JavaScript

1. Animated Christmas Tree Made Using Only CSS

Demo address: http://haiyong.site/christmastree1 (it is recommended to use a computer to open it, the mobile version will be a little distorted if it is not responsive, or you can take a look at the Christmas tree at the back)

HTML code:

The HTML code here is complete and uncut.

<div class="card-container">
  <div class="snow-flakes-1"></div>
  <div class="snow-flakes-2"></div>
  <h2>Next is snowflakes, Christmas trees, New Year and</h2>
  <h1>Better Us</h1>
  <div class="tree-container">
    <div class="ball-0"></div>
    <div class="tree-p1">
      <ul>
        <li>
          <div class="xmas-ball ball-1"></div>
          <div class="tree-left-branch"></div>
        </li>
        <li><div class="tree-right-branch"></div></li>
      </ul>
    </div>
    <div class="tree-p2">
      <ul>
        <li>
          <div class="xmas-ball ball-2"></div>
          <div class="tree-left-branch"></div>
        </li>
        <li>
          <div class="xmas-ball ball-3"></div>
          <div class="tree-right-branch"></div>
        </li>
      </ul>
    </div>
    <div class="tree-p3">
      <ul>
        <li>
          <div class="xmas-ball ball-6"></div>
          <div class="tree-left-branch"></div>
        </li>
        <li>
          <div class="xmas-ball ball-5"></div>
          <div class="xmas-ball ball-4"></div>
          <div class="tree-right-branch"></div>
        </li>
      </ul>
    </div>
    <div class="tree-p4">
      <ul>
        <li>
          <div class="xmas-ball ball-7"></div>
          <div class="xmas-ball ball-8"></div>
          <div class="tree-left-branch"></div>
        </li>
        <li>
          <div class="xmas-ball ball-9"></div>
          <div class="xmas-ball ball-10"></div>
          <div class="tree-right-branch stubborn"></div>
        </li>
      </ul>
    </div>
    <div class="wood"></div>
    <div class="presents">
      <div class="present-container-1">
        <div class="tie"></div>
        <div class="lid"></div>
        <div class="box"></div>
      </div>
      <div class="present-container-2">
        <div class="tie"></div>
        <div class="lid"></div>
        <div class="box"></div>
      </div>
    </div>
  </div>
  <h3>Merry Christmas!</h3>
  <p><span>from haiyong</span></p>
</div>

CSS main code

There is a lot of CSS, I have intercepted some of the main codes

body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #000;
}

ul {
  list-style-type: none;
}

ul li {
  display: inline-block;
}

h1 {
  font-family: "Mountains of Christmas", cursive;
  font-size: 42px;
  line-height: 60px;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

h1::before, h1::after {
  content: "❆";
  margin: 0 10px;
}

h2 {
  font-family: "Source Sans Pro", sans-serif;
  font-size: 14px;
  text-transform:uppercase;
  letter-spacing: 2px;
}

h3 {
  font-family: "Open Sans Condensed", sans-serif;
  font-weight: 300;
  font-size: 18px;
  letter-spacing: 2px;
  margin-bottom: 5px;
}

p {
  font-family: "Dancing Script", cursive;
  font-size: 20px;
  font-weight: 700;
}

span {
  font-family: "Roboto", sans-serif;
  font-size: 14px;
  font-weight: 400;
}

.card-container {
  height: 675px;
  width: 675px;
  padding: 30px;
  background-color: rgba(255, 255, 255, 0.6);
  border: 8px double #fff;
  border-radius: 20px;
  text-align: center;
  border-radius: 50%;
  -webkit-border-radius: 50%;
  overflow: hidden;
  position: relative;
  -webkit-mask-image: -webkit-radial-gradient(white, black);
}

2. Spiral Christmas Tree Made Using Only CSS

Demo address: http://haiyong.site/christmastree2 (perfectly responsive on both mobile and PC)

HTML Code

<div class="tree">
		  <div class="tree__light" style="--appear: 0; --y: 0; --rotate: 1440; --radius: 12.5; --speed: 9.235939340131775; --delay: -2.416794939166802;"></div>
		  <div class="tree__light" style="--appear: 1; --y: 2; --rotate: 1411.2; --radius: 12.25; --speed: 7.165430171444827; --delay: -2.992603509592233;"></div>
		  <div class="tree__light" style="--appear: 2; --y: 4; --rotate: 1382.4; --radius: 12; --speed: 3.5061879558149545; --delay: -0.7704234444726743;"></div>
		  <div class="tree__light" style="--appear: 3; --y: 6; --rotate: 1353.6000000000001; --radius: 11.75; --speed: 4.727223159267884; --delay: -9.55238654379912;"></div>
		  <div class="tree__light" style="--appear: 4; --y: 8; --rotate: 1324.8; --radius: 11.5; --speed: 0.702989829906826; --delay: -4.2545348853934435;"></div>
		  <div class="tree__light" style="--appear: 5; --y: 10; --rotate: 1296; --radius: 11.25; --speed: 6.842573668088441; --delay: -4.560144802030952;"></div>
		  <div class="tree__light" style="--appear: 6; --y: 12; --rotate: 1267.2; --radius: 11; --speed: 5.8193198565131965; --delay: -8.605875056439737;"></div>
		  <!-- The same rule is written until style="--appear: 49; omitted here for the sake of blog brevity-->
		  <div class="tree__light" style="--appear: 49; --y: 98; --rotate: 28.8; --radius: 0.25; --speed: 1.7070837859932286; --delay: -3.8515175108122546;"></div>
		  <svg class="tree__star" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 113.32 108.44" style="--delay: 50">
		    <path d="M90.19 104.33L57.12 87.38 24.4 105l5.91-36.69L3.44 42.65l36.72-5.72 16.1-33.5L73.06 36.6l36.83 4.97-26.35 26.21z" fill="none" stroke-width="6.88" stroke-linecap="round" stroke-linejoin="round"></path>
		  </svg>
		</div>

Complete CSS code

Just copy and paste

* {
  box-sizing: border-box;
}
body {
  background: #233343;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 1200px;
  transform-style: preserve-3d;
}
.tree {
  position: relative;
  height: 50vmin;
  width: 25vmin;
  transform-style: preserve-3d;
  -webkit-animation: spin 2s infinite linear;
          animation: spin 2s infinite linear;
}
.tree__light {
  transform-style: preserve-3d;
  position: absolute;
  height: 1vmin;
  width: 1vmin;
  border-radius: 50%;
  -webkit-animation: flash calc(var(--speed) * 1s) calc(var(--delay) * 1s) infinite steps(4), appear 0.5s calc(var(--appear) * 0.05s) both;
          animation: flash calc(var(--speed) * 1s) calc(var(--delay) * 1s) infinite steps(4), appear 0.5s calc(var(--appear) * 0.05s) both;
  left: 50%;
  transform: translate(-50%, 50%) rotateY(calc(var(--rotate, 0) * 1deg)) translate3d(0, 0, calc(var(--radius, 0) * 1vmin));
  bottom: calc(var(--y, 0) * 1%);
}
.tree__star {
  stroke-width: 5vmin;
  stroke: #f5e0a3;
  filter: drop-shadow(0 0 2vmin #fcf1cf);
  height: 5vmin;
  width: 5vmin;
  overflow: visible !important;
  bottom: 100%;
  left: 50%;
  transform: translate(-50%, 0);
  position: absolute;
  stroke-dasharray: 1000 1000;
  fill: none;
  -webkit-animation: stroke 1s calc((var(--delay) * 0.95) * 0.05s) both;
          animation: stroke 1s calc((var(--delay) * 0.95) * 0.05s) both;
}
@-webkit-keyframes stroke {
  from {
    stroke-dashoffset: -1000;
  }
}
@keyframes stroke {
  from {
    stroke-dashoffset: -1000;
  }
}
@-webkit-keyframes spin {
  to {
    transform: rotateY(360deg);
  }
}
@keyframes spin {
  to {
    transform: rotateY(360deg);
  }
}
@-webkit-keyframes appear {
  from {
    opacity: 0;
  }
}
@keyframes appear {
  from {
    opacity: 0;
  }
}
@-webkit-keyframes flash {
  0%, 100% {
    background: #f00;
  }
  20% {
    background: #fff;
  }
  40% {
    background: #f00;
  }
  60% {
    background: #fff;
  }
  80% {
    background: #f00;
  }
}
@keyframes flash {
  0%, 100% {
    background: #f00;
  }
  20% {
    background: #fff;
  }
  40% {
    background: #f00;
  }
  60% {
    background: #fff;
  }
  80% {
    background: #f00;
  }
}

3. Christmas tree made with HTML+CSS+JS

Demo address: http://haiyong.site/christmastree3 (preview on PC is best)

Full CSS

body {
  background-color:#151522;
  overflow: hidden;
    display: flex;
  align-items: center;
  justify-content: center; 
}

body,
html {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
}


svg{
  width:90%;
  height:90%;
  visibility:hidden;
 
}

Partial JS

MorphSVGPlugin.convertToPath('polygon');
	var xmlns = "http://www.w3.org/2000/svg",
	  xlinkns = "http://www.w3.org/1999/xlink",
	select = function(s) {
	    return document.querySelector(s);
	  },
	  selectAll = function(s) {
	    return document.querySelectorAll(s);
	  },
	  pContainer = select('.pContainer'),
	  mainSVG = select('.mainSVG'),
	  star = select('#star'),
	  sparkle = select('.sparkle'),
	  tree = select('#tree'),
	  showParticle = true,
	  particleColorArray = ['#E8F6F8', '#ACE8F8', '#F6FBFE','#A2CBDC','#B74551', '#5DBA72', '#910B28', '#910B28', '#446D39'],
	  particleTypeArray = ['#star','#circ','#cross','#heart'],
	  particlePool = [],
	  particleCount = 0,
	  numParticles = 201
	
	
	gsap.set('svg', {
	  visibility: 'visible'
	})
	
	gsap.set(sparkle, {
		transformOrigin:'50% 50%',
		y:-100
	})
	
	let getSVGPoints = (path) => {
		
		let arr = []
		var rawPath = MotionPathPlugin.getRawPath(path)[0];
		rawPath.forEach((el, value) => {
			let obj = {}
			obj.x = rawPath[value * 2]
			obj.y = rawPath[(value * 2) + 1]
			if(value % 2) {
				arr.push(obj)
			}
		})
		return arr;
	}
	let treePath = getSVGPoints('.treePath')	
	var treeBottomPath = getSVGPoints('.treeBottomPath')
	var mainTl = gsap.timeline({delay:0, repeat:0}), starTl;
	function flicker(p){
	  gsap.killTweensOf(p, {opacity:true});
	  gsap.fromTo(p, {
	    opacity:1
	  }, {
			duration: 0.07,
	    opacity:Math.random(),
	    repeat:-1
	  })
	}
	
	function createParticles() {
	  var i = numParticles, p, particleTl, step = numParticles/treePath.length, pos;
	  while (--i > -1) {
	    
	    p = select(particleTypeArray[i%particleTypeArray.length]).cloneNode(true);
	    mainSVG.appendChild(p);
	    p.setAttribute('fill', particleColorArray[i % particleColorArray.length]);
	    p.setAttribute('class', "particle");   
	    particlePool.push(p);
	    gsap.set(p, {
	                 x:-100, 
	                 y:-100,
	   transformOrigin:'50% 50%'
	                 })
	  }
	
	}
	
	var getScale = gsap.utils.random(0.5, 3, 0.001, true);
	
	function playParticle(p){
	  if(!showParticle){return};
	  var p = particlePool[particleCount]
	 gsap.set(p, {
		 x: gsap.getProperty('.pContainer', 'x'),
		 y: gsap.getProperty('.pContainer', 'y'),
		 scale:getScale()
	    }
	    );
	var tl = gsap.timeline();
	  tl.to(p, {
			duration: gsap.utils.random(0.61,6),
	      physics2D:
	        velocity: gsap.utils.random(-23, 23),
	        angle:gsap.utils.random(-180, 180),
	        gravity:gsap.utils.random(-6, 50)
	      },
	      scale:0,
	      rotation:gsap.utils.random(-123,360),
	      ease: 'power1',
	      onStart: flicker,
	      onStartParams:[p],
	      //repeat:-1,
	      onRepeat: (p) => {
	        gsap.set(p, {         
	            scale:getScale()
	        })
	      },
	      onRepeatParams: [p]
	
	    });

	  particleCount++;
	  particleCount = (particleCount >=numParticles) ? 0 : particleCount
	  
	}
	
	function drawStar(){
	  
	  starTl = gsap.timeline({onUpdate:playParticle})
	  starTl.to('.pContainer, .sparkle', {
			duration: 6,
			motionPath :
				path: '.treePath',
	      autoRotate: false
			},
	    ease: 'linear'
	  })  
	  .to('.pContainer, .sparkle', {
			duration: 1,
	    onStart:function(){showParticle = false},
	    x:treeBottomPath[0].x,
	    y:treeBottomPath[0].y
	  })
	  .to('.pContainer, .sparkle', {
			duration: 2,
	    onStart:function(){showParticle = true},
			motionPath :
				path: '.treeBottomPath',
	      autoRotate: false
			},
	    ease: 'linear'    
	  },'-=0')
	.from('.treeBottomMask', {
			duration: 2,
	  drawSVG:'0% 0%',
	  stroke:'#FFF',
	  ease:'linear'
	},'-=2')  
	  
	}
	
	
	createParticles();
	drawStar();
	//ScrubGSAPTimeline(mainTl)
	
	mainTl.from(['.treePathMask','.treePotMask'],{
		duration: 6,
	  drawSVG:'0% 0%',
	  stroke:'#FFF',
		stagger:
			each: 6
		},
	    duration: gsap.utils.wrap([6, 1,2]),
	  ease:'linear'
	})
	.from('.treeStar', {
		duration: 3,
	  //skewY:270,
	  scaleY:0,
	  scaleX:0.15,
	  transformOrigin:'50% 50%',
	  ease: 'elastic(1,0.5)'
	},'-=4')
	
	 .to('.sparkle', {
		duration: 3,
	    opacity:0,
	    ease:"rough({strength: 2, points: 100, template: linear, taper: both, randomize: true, clamp: false})"
	  },'-=0')
	  .to('.treeStarOutline', {
		duration: 1,
	    opacity:1,
	    ease:"rough({strength: 2, points: 16, template: linear, taper: none, randomize: true, clamp: false})"
	  },'+=1')		
	mainTl.add(starTl, 0)
	gsap.globalTimeline.timeScale(1.5);

4. Shooting Star Christmas Tree Using Only CSS

Demo address: http://haiyong.site/christmastree4 (responsive, available for preview on both mobile and PC)

HTML Code

<ul>
 <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
<ul>
<!-- 256 lines are omitted here<li></li> -->
</ul>

CSS Code

:root {
  --background:#3C3B3D;
}

body {
  background: var(--background);
}
body ul {
  padding: 0;
}
body ul li {
  list-style: none;
}
body ul:nth-child(1) {
  position: absolute;
  top: 20vh;
  left: 50%;
  width: 1rem;
  height: 1rem;
  border-radius: 100%;
  transform: translate(-50%, -50%);
}
body ul:nth-child(1) li {
  position: absolute;
  width: 0;
  height: 0;
  border-width: 0 0.5rem 1rem 0.5rem;
  border-style: solid;
  border-color: transparent;
  border-bottom-color: #FFCE54;
  transform-origin: 0.5rem 1rem;
}
body ul:nth-child(1) li:nth-child(0) {
  transform: rotate(0deg);
}
body ul:nth-child(1) li:nth-child(1) {
  transform: rotate(72deg);
}
body ul:nth-child(1) li:nth-child(2) {
  transform: rotate(144deg);
}
body ul:nth-child(1) li:nth-child(3) {
  transform: rotate(216deg);
}
body ul:nth-child(1) li:nth-child(4) {
  transform: rotate(288deg);
}
body ul:nth-child(2) li {
  position: absolute;
  top: 20vh;
  left: 50%;
  width: 0.0625rem;
  height: 60vh;
  transform-origin: 50% 0%;
}
body ul:nth-child(2) li:nth-child(1) {
  transform: rotate(4.9322004015deg);
}
body ul:nth-child(2) li:nth-child(1):before, body ul:nth-child(2) li:nth-child(1):after {
  -webkit-animation-delay: -0.015625s;
          animation-delay: -0.015625s;
}
body ul:nth-child(2) li:nth-child(2) {
  transform: rotate(7.7960629984deg);
}
body ul:nth-child(2) li:nth-child(2):before, body ul:nth-child(2) li:nth-child(2):after {
  -webkit-animation-delay: -0.03125s;
          animation-delay: -0.03125s;
}
body ul:nth-child(2) li:nth-child(3) {
  transform: rotate(10.5294548885deg);
}
body ul:nth-child(2) li:nth-child(3):before, body ul:nth-child(2) li:nth-child(3):after {
  -webkit-animation-delay: -0.046875s;
          animation-delay: -0.046875s;
}
/* ...... */
/* Same pattern, until the 256th */
body ul:nth-child(2) li:nth-child(256) {
  transform: rotate(2deg);
}
body ul:nth-child(2) li:nth-child(256):before, body ul:nth-child(2) li:nth-child(256):after {
  -webkit-animation-delay: -4s;
          animation-delay: -4s;
}
body ul:nth-child(2) li:before, body ul:nth-child(2) li:after {
  content: "";
  position: absolute;
  top: 0%;
  -webkit-animation: fall 4s linear infinite;
          animation: fall 4s linear infinite;
}
body ul:nth-child(2) li:before {
  width: 0.0625rem;
  height: 3rem;
  background: linear-gradient(rgba(46, 204, 113, 0), rgba(46, 204, 113, 0.5));
}
body ul:nth-child(2) li:after {
  bottom: 0;
  transform: translate(-50%, 3rem);
  width: 0.1875rem;
  height: 0.1875rem;
  border-radius: 100%;
  background: #ffce54;
}
body ul:nth-child(2) li:nth-child(4n):after {
  background: #D8334A;
}
body ul:nth-child(2) li:nth-child(4n+1):after {
  background: #FFCE54;
}
body ul:nth-child(2) li:nth-child(4n+2):after {
  background: #2ECC71;
}
body ul:nth-child(2) li:nth-child(4n+3):after {
  background: #5D9CEC;
}

@-webkit-keyframes fall {
  0% {
    opacity: 0;
    top: 0%;
  }
  5% {
    opacity: 0;
  }
  15%, 90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    top: 100%;
  }
}

@keyframes fall {
  0% {
    opacity: 0;
    top: 0%;
  }
  5% {
    opacity: 0;
  }
  15%, 90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    top: 100%;
  }
}

5. Christmas tree in the crystal ball

Demo address: http://haiyong.site/christmastree5 (responsive, available for preview on both mobile and PC)

CSS complete code

html, body {
    margin:0;
    width: 100%;
    height: 100%;
    position: absolute;
    overflow: hidden;
    background: linear-gradient(135deg, rgba(180,186,214,1) 0%, rgba(232,203,192,1) 100%);
}

.content {
    text-align: center;
    width: 100%;
}

svg {
    max-width: 575px;
}

#canvas {
    border-radius: 50%;
    position: relative;
    width: 310px;
    height: 290px;
    top: 10px;
    left: 0px;
}

.canvas_container {
    position: absolute;
    width: 100%;
}

.draw_container {
    position: absolute;
    top: 50px;
    width: 100%;
}

JS complete code

$(function() {
		    var canvas = $("#canvas")[0];
		    var ctx = canvas.getContext("2d");
		    var WIDTH = 320;
		    var HEIGHT = 320;
		    canvas.width = WIDTH;
		    canvas.height = HEIGHT;
		    clearCanvas();
		
		    var particles = [];
		    for (var i = 0; i < WIDTH; i++) {
		        particles.push({
		            x: Math.random() * WIDTH,
		            y: Math.random() * HEIGHT,
		            r: Math.random() * 2 + 1
		        })
		    }
		    
		    function draw() {
		        clearCanvas();
		        ctx.fillStyle = "rgba(255, 255, 255, 0.6)";
		        ctx.beginPath();
		
		        for (let i = 0; i < WIDTH; i++) {
		            let p = particles[i];
		            ctx.moveTo(px, py);
		            ctx.arc(px, py, pr, 0, Math.PI * 2, true);
		        }
		        ctx.fill();
		        update();
		    }
		    
		    function update() {
		        for (let i = 0; i < WIDTH; i++) {
		            let p = particles[i];
		            py += pr;
		            if (py > canvas.height) {
		                particles[i] = {
		                    x: Math.random() * canvas.width,
		                    y: -10,
		                    r:pr
		                };
		            }
		        }
		    }
		    var timer = setInterval(draw, 50);
		
		    function clearCanvas() {
		        ctx.clearRect(0, 0, canvas.width, canvas.height);
		    }
		
		})

6. Christmas Cards

Demo address: http://haiyong.site/shengdanheka

The above is the detailed content of the dynamic Christmas tree implemented through JavaScript. For more information about JavaScript Christmas tree, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Implementing Christmas tree code based on JS2Image
  • JavaScript flashing Christmas tree implementation code
  • Using JS to implement a rotating Christmas tree in HTML

<<:  An article to understand MySQL master-slave replication and read-write separation

>>:  Example of creating circular scrolling progress bar animation using CSS3

Recommend

Table td picture horizontally and vertically centered code

Html code: Copy code The code is as follows: <t...

Common causes and solutions for slow MySQL SQL statements

1. Slow query due to lack of index or invalid ind...

Linux process management tool supervisor installation and configuration tutorial

Environment: CentOS 7 Official documentation: htt...

How to analyze MySQL query performance

Table of contents Slow query basics: optimizing d...

Setting up VMware vSphere in VMware Workstation (Graphic Tutorial)

VMware vSphere is the industry's leading and ...

Example of how nginx implements dynamic and static separation

Table of contents Deploy nginx on server1 Deploy ...

Echart Bar double column chart style most complete detailed explanation

Table of contents Preface Installation and Config...

Three Vue slots to solve parent-child component communication

Table of contents Preface Environment Preparation...

How to modify Flash SWF files in web pages

I think this is a problem that many people have en...

A brief introduction to MySQL database optimization techniques

A mature database architecture is not designed wi...

How to quickly build your own server detailed tutorial (Java environment)

1. Purchase of Server 1. I chose Alibaba Cloud...

Implementation of tomcat deployment project and integration with IDEA

Table of contents 3 ways to deploy projects with ...

An article tells you how to write a Vue plugin

Table of contents What is a plugin Writing plugin...

Build a WebRTC video chat in 5 minutes

In the previous article, I introduced the detaile...

Summary of problems that may occur when using JDBC to connect to Mysql database

First, clarify a few concepts: JDBC: Java databas...