2022年圣诞节 | 用代码实现简单圣诞树

2022年圣诞节到来啦,很高兴这次我们又能一起度过~

一、前言

本文我们用 Python 来画一棵带背景音乐效果的雪夜圣诞树以及使用 HTML+CSS+JS 在页面渲染出动态圣诞树,所涉及到的源码均来自GitHub开源站点。

二、效果展示

Python

HTML+CSS+JS

三、编码实现

Python代码

python 复制代码
import pygame
import random

# 初始化 pygame
pygame.init()
# 设置屏幕宽高,根据背景图调整
bg_img = "bg.png"
bg_size = (609, 601)
screen = pygame.display.set_mode(bg_size)
pygame.display.set_caption("雪夜圣诞树")
bg = pygame.image.load(bg_img)
# 雪花列表
snow_list = []
for i in range(150):
    x_site = random.randrange(0, bg_size[0])   # 雪花圆心位置
    y_site = random.randrange(0, bg_size[1])   # 雪花圆心位置
    X_shift = random.randint(-1, 1)         # x 轴偏移量
    radius = random.randint(4, 6)           # 半径和 y 周下降量
    snow_list.append([x_site, y_site, X_shift, radius])
# 创建时钟对象
clock = pygame.time.Clock()
# 添加音乐
track = pygame.mixer.music.load('my.mp3')  # 加载音乐文件
pygame.mixer.music.play()  # 播放音乐流
pygame.mixer.music.fadeout(600000)  # 设置音乐结束时间
done = False
while not done:
    # 消息事件循环,判断退出
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    screen.blit(bg, (0, 0))
    # 雪花列表循环
    for i in range(len(snow_list)):
        # 绘制雪花,颜色、位置、大小
        pygame.draw.circle(screen, (255, 255, 255), snow_list[i][:2], snow_list[i][3] - 3)
        # 移动雪花位置(下一次循环起效)
        snow_list[i][0] += snow_list[i][2]
        snow_list[i][1] += snow_list[i][3]
        # 如果雪花落出屏幕,重设位置
        if snow_list[i][1] > bg_size[1]:
            snow_list[i][1] = random.randrange(-50, -10)
            snow_list[i][0] = random.randrange(0, bg_size[0])
    # 刷新屏幕
    pygame.display.flip()
    clock.tick(30)
# 退出
pygame.quit()

HTML+CSS+JS

index.html代码

python 复制代码
<!DOCTYPE html>
<html lang="en">
    <head>
		<meta charset="utf-8">

		<meta name="description" content="A Christmas tree built out of form elements." />
		<meta name="author" content="Hakim El Hattab" />

		<meta http-equiv="X-UA-Compatible" content="chrome=1">

        <title>DOM Tree</title>

		<link href="css/domtree.css" rel="stylesheet" media="screen" />

		<link href='https://fonts.googleapis.com/css?family=Armata' rel='stylesheet' type='text/css'>

    </head>
    <body>
    	<div class="tree"></div>

		<script src="js/domtree.js"></script>

		<!-- Third party scripts and sharing UI -->
		<p class="project-title">DOM Tree</p>

		<div class="credits">
			<a href="https://github.com/hakimel/dom-tree">Source on GitHub</a>
			<a href="https://twitter.com/share?text=A%20Christmas%20tree%20made%20out%20of%20form%20elements&url=http://lab.hakim.se/domtree&via=hakimel&related=hakimel" target="_blank">Tweet this</a>
			<a href="https://twitter.com/hakimel">Follow @hakimel</a>
		</div>

		<style type="text/css" media="screen">
			.project-title {
				position: absolute;
				left: 25px;
				bottom: 20px;

				font-size: 16px;
				color: #fff;
			}

			.credits {
				position: absolute;
				right: 20px;
				bottom: 25px;
				font-size: 15px;
				z-index: 20;
				color: #fff;
				vertical-align: middle;
			}

			.credits * + * {
				margin-left: 15px;
			}

			.credits a {
				padding: 8px 10px;
				color: rgba(255,255,255,0.7);
				border: 2px solid rgba(255,255,255,0.7);
				text-decoration: none;
			}

			.credits a:hover {
				border-color: #fff;
				color: #fff;
			}

			@media screen and (max-width: 1040px) {
				.project-title {
					display: none;
				}

				.credits {
					width: 100%;
					left: 0;
					right: auto;
					bottom: 0;
					padding: 30px 0;
					background: #b72424;
					text-align: center;
				}

				.credits a {
					display: inline-block;
					margin-top: 7px;
					margin-bottom: 7px;
				}
			}
		</style>

		<script>
			var _gaq = [['_setAccount', 'UA-15240703-1'], ['_trackPageview']];
			(function(d, t) {
			var g = d.createElement(t),
			    s = d.getElementsByTagName(t)[0];
			g.async = true;
			g.src = ('https:' == location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
			s.parentNode.insertBefore(g, s);
			})(document, 'script');
		</script>

    </body>
</html>

domtree.js代码

python 复制代码
const width = 500;
const height = 600;
const quantity = 150;
const types = [ 'text', 'select', 'progress', 'meter', 'button', 'radio', 'checkbox' ];
const greetings = [ 'Joyeuses Fêtes','Felices Fiestas','God Jul','Boas Festas','Mutlu Bayramlar','Sarbatori Fericite','Jie Ri Yu Kuai','Bones Festes','Tanoshii kurisumasu wo','Buone Feste','Happy Holidays', 'Ii holide eximnandi','Frohe Feiertage','Prettige feestdagen','Beannachtaí na Féile','Vesele Praznike','Selamat Hari Raya','Sretni praznici' ];

let tree = document.querySelector( '.tree' ),
	treeRotation = 0;

tree.style.width = width + 'px';
tree.style.height = height + 'px';

window.addEventListener( 'resize', resize, false );

// The tree
for( var i = 0; i < quantity; i++ ) {
	let element = null,
		type = types[ Math.floor( Math.random() * types.length ) ],
		greeting = greetings[ Math.floor( Math.random() * greetings.length ) ];

	let x = width/2,
		y = Math.round( Math.random() * height );

	let rx = 0,
		ry = Math.random() * 360,
		rz = -Math.random() * 15;

	let elemenWidth = 5 + ( ( y / height ) * width / 2 ),
		elemenHeight = 26;

	switch( type ) {
		case 'button':
			element = document.createElement( 'button' );
			element.textContent = greeting;
			element.style.width = elemenWidth + 'px';
			element.style.height = elemenHeight + 'px';
			break;
		case 'progress':
			element = document.createElement( 'progress' );
			element.style.width = elemenWidth + 'px';
			element.style.height = elemenHeight + 'px';
			if( Math.random() > 0.5 ) {
				element.setAttribute( 'max', '100' );
				element.setAttribute( 'value', Math.round( Math.random() * 100 ) );
			}
			break;
		case 'select':
			element = document.createElement( 'select' );
			element.setAttribute( 'selected', greeting );
			element.innerHTML = '<option>' + greetings.join( '</option><option>' ) + '</option>';
			element.style.width = elemenWidth + 'px';
			element.style.height = elemenHeight + 'px';
			break;
		case 'meter':
			element = document.createElement( 'meter' );
			element.setAttribute( 'min', '0' );
			element.setAttribute( 'max', '100' );
			element.setAttribute( 'value', Math.round( Math.random() * 100 ) );
			element.style.width = elemenWidth + 'px';
			element.style.height = elemenHeight + 'px';
			break;
		case 'text':
		default:
			element = document.createElement( 'input' );
			element.setAttribute( 'type', 'text' );
			element.setAttribute( 'value', greeting );
			element.style.width = elemenWidth + 'px';
			element.style.height = elemenHeight + 'px';
	}

	element.style.transform = `translate3d(${x}px, ${y}px, 0px) rotateX(${rx}deg) rotateY(${ry}deg) rotateZ(${rz}deg)`;

	tree.appendChild( element );
}

// Let it snow
for( var i = 0; i < 200; i++ ) {
	let element = document.createElement( 'input' );
	element.setAttribute( 'type', 'radio' );

	let spread = window.innerWidth/2;

	let x = Math.round( Math.random() * spread ) - ( spread / 4 ),
		y = Math.round( Math.random() * height ),
		z = Math.round( Math.random() * spread ) - ( spread / 2 );

	let rx = 0,
		ry = Math.random() * 360,
		rz = 0;

	if( Math.random() > 0.5 ) element.setAttribute( 'checked', '' );

	element.style.transform = `translate3d(${x}px, ${y}px, ${z}px) rotateX(${rx}deg) rotateY(${ry}deg) rotateZ(${rz}deg)`;

	tree.appendChild( element );
}

function resize() {
	tree.style.top = ( ( window.innerHeight - height - 100 ) / 2 ) + 'px';
}

resize();
相关推荐
codists14 分钟前
《Django 5 By Example》阅读笔记:p339-p358
python·django
檀越剑指大厂17 分钟前
【Python系列】异步 Web 服务器
服务器·前端·python
m0_6760995836 分钟前
数据结构--创建链表--Python
数据结构·python·链表
搬砖的果果1 小时前
HTTP代理是什么,主要用来干嘛?
网络·python·网络协议·tcp/ip·http
白初&1 小时前
文件上传代码分析
java·c++·python·php·代码审计
菜鸟小贤贤1 小时前
pyhton+yaml+pytest+allure框架封装-全局变量渲染
python·macos·pytest·接口自动化·jinja2
赛丽曼2 小时前
Python中的简单爬虫
爬虫·python
CODE_RabbitV2 小时前
Python + 深度学习从 0 到 1(00 / 99)
开发语言·python·深度学习
微凉的衣柜3 小时前
在 PyTorch 中进行推理时,为什么 `model.eval()` 和 `torch.no_grad()` 需要同时使用?
人工智能·pytorch·python
int WINGsssss3 小时前
使用系统内NCCL环境重新编译Pytorch
人工智能·pytorch·python