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

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

一、前言

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

二、效果展示

Python

在这里插入图片描述

 

HTML+CSS+JS

在这里插入图片描述

 

三、编码实现

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代码

<!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代码

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();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/45212.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenTDF数据加密引擎

OpenTDF是Virtru公司的开源项目。 Virtru基于OpenTDF开发了用于google Workspace和Microsoft 365的相关数据安全产品。 简介 virtru公司基于opentdf开发挺多产品的,都是数据安全类产品。 能把opentdf开源,已经非常不容易了。 opentdf的代码看起来还是比较整齐和成熟的。…

aPaaS开发 VS 传统软件开发?

aPaaS开发 VS 传统软件开发&#xff1f;aPaaS的优势和平台选型&#xff1a; &#xff08;1&#xff09;aPaaS模式具备成本优势、开发速度快、多场景适用等特点&#xff0c;在资本市场备受关注&#xff1b; &#xff08;2&#xff09;aPaaS能够覆盖企业销售、项目管理、业务财…

微服务远程调用openFeign简单回顾

目录 一. OpenFeign简介 二. OpenFeign原理 演示使用 provider模块 消费者模块 配置全局feign日志 示例源代码: 一. OpenFeign简介 OpenFeign是SpringCloud服务调用中间件&#xff0c;可以帮助代理服务API接口。并且可以解析SpringMVC的RequestMapping注解下的接口&#x…

学习day52

1.关于 error Component name "School" should always be multi-word vue/multi-word-component-names 这里是因为脚手架的规范原因&#xff0c; 解决办法&#xff1a; 我是在vue.comfig.js文件中加入了一条配置&#xff0c;即 lintOnSave:false 整个文件的完整…

Java 实现提取富文本中包含特定字符串的图片 src 属性值

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

Nginx配置server_name讲解

文章目录 1.Nginx配置中没有server_name会怎样&#xff1f;2.Nginx配置server_name的匹配规则3.正则表达式规则 1.Nginx配置中没有server_name会怎样&#xff1f; 此时Nginx会自动设置成 server_name ""; 它不会匹配任何域名&#xff0c;导致Nginx会优先将HTTP请求交…

Cesium态势标绘专题-弓形(标绘+编辑)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

3分钟,快速上手Postman接口测试

Postman是一个用于调试HTTP请求的工具&#xff0c;它提供了友好的界面帮助分析、构造HTTP请求&#xff0c;并分析响应数据。实际工作中&#xff0c;开发和测试基本上都有使用Postman来进行接口调试工作。有一些其他流程的工具&#xff0c;也是模仿的Postman的风格进行接口测试工…

Unity 性能优化一:性能标准、常用工具

性能标准 推荐耗时&#xff1a; 性能提现到玩家直观感受&#xff0c;就是帧率&#xff0c;为了达到要求的帧率&#xff0c;就要控制CPU的耗时&#xff0c;不同类型的游戏&#xff0c;对帧率要求不一样。下面是推荐耗时&#xff1a; 推荐内存&#xff1a; 避免游戏闪退的重点…

云服务器AccessKey执行命令

人之所以痛苦&#xff0c;在于追求错误的东西。如果你不给自己烦恼&#xff0c;别人也永远不可能给你烦恼。因为你自己的内心&#xff0c;你放不下。 好好的管教你自己&#xff0c;不要管别人。 漏洞实战 查看所有实例信息 A.exe -a xxx -s xxx ecs -list执行命令 A.exe -a…

SpringBoot整合Dubbo+Zookeeper

文章目录 实践前知识储备Dubbo概述安装zkDubbo在zk中的存储结构Dubbo的注册中心有哪些Dubbo支持的协议 Dubbo整合SpringBoot本案例工程结构具体实现开发两个接口进行测试实现步骤测试 实践前知识储备 Dubbo概述 学习Dubbo前你要了解这些 安装zk Zookeeper概述与安装 Dubbo…

视频的音频提取怎么做?这样提取很简单

提取视频中的音频通常在需要从视频中独立使用音频或需要对音频进行编辑时使用。例如&#xff0c;当我们需要将音频上传到音乐流媒体平台或将其用于播客或其他音频项目时&#xff0c;就可能需要从视频中提取音频。问题是该怎么提取呢&#xff1f;教给大家几种简单的提取方法&…

Nodejs 安装之后cmd 输入npm -v 提示error的问题解决

1.问题现象&#xff1a; 安装时候选择&#xff1a; 2. 解决问题 卸载nodejs 删除安装路径下的node_modules, 重新安装 按照下面的选择

科技与人元宇宙论坛跨界对话

近来&#xff0c;“元宇宙”成为热门话题&#xff0c;越来越频繁地出现在人们的视野里。大家都在谈论它&#xff0c;但似 乎还没有一个被所有人认同的定义。元宇宙究竟是什么&#xff1f;未来它会对我们的工作和生活带来什么样 的改变&#xff1f;当谈论虚拟现实&#xff08;VR…

磁场强度单位和磁感应强度单位转换

磁学量常用单位换算 、磁场强度单位和磁感应强度单位转换。 磁场单位 Oe&#xff08;奥斯特&#xff09;,A/m,T&#xff08;特斯拉&#xff09;三种. 1T1000mT 1mT10Gs 1Gs79.6A/m 1T(特斯拉)10000Gs(高斯)1Wb/M2 1Gs(高斯)1Oe(奥斯特)

DAY1,Qt [ 手动实现登录框(信息调试类,按钮类,行编辑器类,标签类的使用)]

1.手动实现登录框&#xff1b; ---mychat.h---头文件 #ifndef MYCHAT_H #define MYCHAT_H#include <QWidget> #include <QDebug> //打印信息 #include <QIcon> //图标 #include <QPushButton> //按钮 #include <QLineEdit> //行编辑器类 #in…

Fiddler学习笔记

Fiddler简介 学习Fiddler的基础前置知识 请求行又包括请求方法&#xff0c;统一资源定位符、请求协议及版本号 统一资源定位符就是资源的绝对路径 请求体里写服务器需要的参数 304是服务器没有变化&#xff0c;根据请求头发现请求的内容和本地一样&#xff0c;就不再发回来了 …

day02_springboot综合案例

day02_springboot综合案例 订单操作 查询所有订单 查询所有订单流程 查询订单&#xff0c;要把订单对应的产品也要查出来 Orders实体类 Data public class Orders {private String id;private String orderNum;DateTimeFormat(pattern"yyyy-MM-dd HH:mm")privat…

【前端知识】React 基础巩固(三十三)——Redux的使用详解

React 基础巩固(三十三)——Redux的使用详解 Redux的使用详解 针对React 基础巩固&#xff08;三十二&#xff09;中的案例&#xff0c;我们希望抽取页面中共有的代码&#xff08;例如下方的代码&#xff09;&#xff0c;使用高阶组件统一拦截。 constructor() {super();this.…

华为数通HCIP-ISIS高级

isis区域间的互访 1、L2区域 to L1区域 在L1区域发布的路由会以L1-LSP在L1区域内传递&#xff0c;到达L1-2路由器时&#xff0c;L1-2路由器会将该L1-LSP转换为L2-LSP在L2区域内传递&#xff1b; 因此L2区域的设备可以学习到L1区域的明细路由&#xff0c;进行访问&#xff1b;…