当前位置: 首页 > news >正文

用HTML、CSS和JS打造绚丽的雪花飘落效果

目录

一、程序代码

二、代码原理

三、运行效果


一、程序代码

<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=GBK"><style>* {margin: 0;padding: 0;}#box {width: 100vw;height: 100vh;padding: 3px;position: absolute;background: black;}</style>
</head><body><div id="box"></div>
</body><script>(function () {var screenWidth = screen.availWidth; // 获取屏幕宽度var screenHeight = screen.availHeight; // 获取屏幕高度var speed = 1; // 雪花下落的速度function Snow(size, downSize) {this.box = document.getElementById("box"); // 获取容器元素this.size = size; // 雪花数量this.downSize = downSize || 10; // 每次落下的雪花数量,默认为10个this.item = []; // 雪花元素数组this.init(); // 初始化this.start(); // 开始下雪}// 获取相关随机数据的方法Snow.prototype.getRandomThings = function (type) {var res;if (type == 'left') { // 初始的leftres = Math.round(Math.random() * (screenWidth - 30 - 10)) + 10; // 随机生成left值Math.random() > 0.8 ? (res = -res) : null; // 80%的概率使左边的雪花出现在左侧(left为负值)} else if (type == 'top') { // 初始的topres = -(Math.round(Math.random() * (50 - 40)) + 40); // 随机生成top值,负值使雪花在屏幕上方} else if (type == 'incre') { // 向下的速度res = Math.random() * (4 - 1) + 1; // 随机生成向下的速度} else if (type == 'increLeft') { // 向右的速度res = Math.random() * (0.8 - 0.5) + 0.5; // 随机生成向右的速度} else { // 雪花的大小res = Math.round(Math.random() * (30 - 10)) + 10; // 随机生成雪花的大小}return res;}Snow.prototype.init = function () {this.box.style.width = screenWidth + 'px'; // 设置容器宽度为屏幕宽度this.box.style.height = screenHeight + 'px'; // 设置容器高度为屏幕高度var fragment = document.createDocumentFragment(); // 创建文档片段,用于性能优化for (var i = 0; i < this.size; i++) { // 创建雪花元素var left = this.getRandomThings('left'); // 获取随机的left值var top = this.getRandomThings('top'); // 获取随机的top值var snowSize = this.getRandomThings('size'); // 获取随机的雪花大小var snow = document.createElement("div"); // 创建雪花元素snow.style.cssText = 'position:absolute;color:#FFFFFF;'; // 设置元素样式snow.style['font-size'] = snowSize + 'px'; // 设置字体大小snow.style.left = left + 'px'; // 设置left值snow.style.top = top + 'px'; // 设置top值snow.innerHTML = '&#10052'; // 设置雪花图标(Unicode编码)this.item.push(snow); // 添加到雪花元素数组中fragment.appendChild(snow); // 添加到文档片段中}box.appendChild(fragment); // 将文档片段添加到容器中}Snow.prototype.start = function () {var that = this;var num = 0;for (var i = 0; i < this.size; i++) { // 遍历雪花元素数组var snow = this.item[i];if ((i + 1) % this.downSize == 0) { // 每downSize个雪花一组,控制下落速度num++;}(function (s, n) { // 使用闭包保存snow和num的值setTimeout(function () { // 定时器,实现雪花分批下落that.doStart(s); // 调用doStart方法使雪花开始下落}, 1000 * n) // 每隔n秒下落一组雪花})(snow, num)}}// 针对每个雪花的定时处理Snow.prototype.doStart = function (snow) {var that = this;(function (s) {var increTop = that.getRandomThings('incre'); // 获取向下的速度var increLeft = that.getRandomThings('increLeft'); // 获取向右的速度var x = parseInt(getStyle(s, 'left')), y = parseInt(getStyle(s, 'top')); // 获取当前的left和top值if (s.timmer) return; // 如果定时器已存在,则不执行后续代码s.timmer = setInterval(function () { // 设置定时器,使雪花动起来// 超过右边或者底部重新开始if (y > (screenHeight - 5) || x > (screenWidth - 30)) {// 重新回到天上开始往下increTop = that.getRandomThings('incre');increLeft = that.getRandomThings('increLeft');// 重新随机属性var left = that.getRandomThings('left');var top = that.getRandomThings('top');var snowSize = that.getRandomThings('size');s.style.left = left + 'px';s.style.top = top + 'px';s.style['font-size'] = snowSize + 'px';y = top;x = left;n = 0;return;}// 加上系数,当随机数大于0.5时速度加快,小于0.5时速度减慢,形成飘动效果x += Math.random() > 0.5 ? increLeft * 1.1 : increLeft * 0.9;y += Math.random() > 0.5 ? increTop * 1.1 : increTop * 0.9;// 设置left和top值使雪花动起来s.style.left = x + 'px';s.style.top = y + 'px';}, speed); // 每隔speed毫秒执行一次定时器中的代码})(snow)}// 获取元素的样式值function getStyle(obj, prop) {var prevComputedStyle = document.defaultView ? document.defaultView.getComputedStyle(obj, null) : obj.currentStyle;return prevComputedStyle[prop];}new Snow(300, 30); // 创建一个Snow对象,传入雪花数量和每批下落的雪花数量})()</script></html>

二、代码原理

这段代码主要通过JavaScript来操作DOM元素,实现了一个下雪的效果。首先,通过CSS样式设置整个页面的背景为黑色,并且创建一个id为"box"的容器元素用于容纳雪花。

接着,使用JavaScript代码自执行函数来封装雪花的相关逻辑。在这个函数中,获取屏幕的宽度和高度,并定义了雪花下落的速度。

然后,定义了一个Snow对象构造函数,用于创建雪花。构造函数接受两个参数,分别是雪花的数量和每批下落的雪花数量。在构造函数中,首先通过getElementById方法获取到容器元素,并设置容器的宽度和高度与屏幕一致。然后,使用for循环创建指定数量的雪花元素,通过随机数设置雪花的初始位置、大小和样式,并将雪花元素添加到数组item和文档片段中。最后,将文档片段添加到容器中。

接着,在Snow对象的原型上定义了一系列方法。其中,getRandomThings方法用于根据type参数获取随机的left值、top值、向下的速度、向右的速度或雪花的大小。init方法用于初始化雪花,设置容器的宽度和高度,并创建指定数量的雪花元素,并将其添加到容器中。start方法用于控制雪花的下落,通过定时器和闭包实现分批下落的效果。doStart方法用于针对每个雪花设置定时处理,根据当前位置和速度计算新的位置,并更新雪花元素的样式值,使其动起来。getStyle方法用于获取元素的样式值。

最后,在全局作用域中创建了一个Snow对象,传入了300个雪花和每批下落的雪花数量为30,从而开始执行下雪效果。

三、运行效果

相关文章:

用HTML、CSS和JS打造绚丽的雪花飘落效果

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetGBK"><style>* {margin: 0;padding: 0;}#box {width: 100vw;heig…...

订餐|网上订餐系统|基于springboot的网上订餐系统设计与实现(源码+数据库+文档)

网上订餐系统目录 目录 基于springboot的网上订餐系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户功能模块的实现 &#xff08;1&#xff09;用户注册界面 &#xff08;2&#xff09;用户登录界面 &#xff08;3&#xff09;菜品详情界面 &#xff08…...

从零开始学howtoheap:解题西湖论剑Storm_note

how2heap是由shellphish团队制作的堆利用教程&#xff0c;介绍了多种堆利用技术&#xff0c;后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境&#xff1a;从零开始配置pwn环境&#xff1a;从零开始配置pwn环境&#xff1a;优化pwn虚拟机配置支持libc等指…...

Rust 基本环境安装

rust 基本介绍请看上一篇文章&#xff1a;rust 介绍 rustup 介绍 rustup 是 Rust 语言的安装器和版本管理工具。通过 rustup&#xff0c;可以轻松地安装 Rust 编译器&#xff08;rustc&#xff09;、标准库和文档。它也允许你切换不同的 Rust 版本或目标平台&#xff0c;以及…...

【电源】POE系统供电原理(二)

转载本博客文章&#xff0c;请注明出处 ​ 上一篇文章中&#xff0c;有提到POE系统工作原理及动态检测机制&#xff0c;下面我们继续介绍受电端PD技术及原理。POE供电系统包含PSE、PD及互联接口部分组成&#xff0c;如下图所示。 图1 POE供电系统 PSE控制器的主要作用&#xff…...

GPU独显下ubuntu屏幕亮度不能调节解决方法

GPU独显下屏幕亮度不能调节&#xff08;假设你已经安装了合适的nvidia显卡驱动&#xff09;&#xff0c;我试过修改 /etc/default/grub 的 GRUB_CMDLINE_LINUX_DEFAULT"quiet splash acpi_backlightvendor" &#xff0c;没用。修改和xorg.conf相关的文件&#xff0c;…...

Linux篇:网络基础1

一、网络基础&#xff1a;网络本质就是在获取和传输数据&#xff0c;而系统的本质是在加工和处理数据。 1、应用问题&#xff1a; ①如何处理发来的数据&#xff1f;—https/http/ftp/smtp ②长距离传输的数据丢失的问题&#xff1f;——TCP协议 ③如何定位的主机的问题&#…...

RK3568笔记十七:LVGL v8.2移植

若该文为原创文章&#xff0c;转载请注明原文出处。 本文介绍嵌入式轻量化图形库LVGL 8.2移植到Linux开发板ATK-RK3568上的步骤。 主要是参考大佬博客&#xff1a; LVGL v8.2移植到IMX6ULL开发板_lvgl移植到linux-CSDN博客 一、环境 1、平台&#xff1a;rk3568 2、开发板:…...

C#系列-C#访问MongoDB+redis+kafka(7)

目录 一、 C#中访问MongoDB. 二、 C#访问redis. 三、 C#访问kafka. C#中访问MongoDB 在C#中访问MongoDB&#xff0c;你通常会使用MongoDB官方提供的MongoDB C#/.NET Driver。这个驱动提供了丰富的API来执行CRUD&#xff08;创建、读取、更新、删除&#x…...

(12)Hive调优——count distinct去重优化

离线数仓开发过程中经常会对数据去重后聚合统计&#xff0c;count distinct使得map端无法预聚合&#xff0c;容易引发reduce端长尾&#xff0c;以下是count distinct去重调优的几种方式。 解决方案一&#xff1a;group by 替代 原sql 如下&#xff1a; #7日、14日的app点击的…...

记录 | 验证pytorch-cuda是否安装成功

检测程序如下&#xff1a; import torchprint(torch.__version__) print(torch.cuda.is_available()) 或者用终端 Shell&#xff0c;运行情况如下...

LeetCode 239.滑动窗口的最大值 Hot100 单调栈

给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xff1a;nums [1,3,-1,-3,5,3,6,7], k 3 输…...

463. Island Perimeter(岛屿的周长)

问题描述 给定一个 row x col 的二维网格地图 grid &#xff0c;其中&#xff1a;grid[i][j] 1 表示陆地&#xff0c; grid[i][j] 0 表示水域。 网格中的格子 水平和垂直 方向相连&#xff08;对角线方向不相连&#xff09;。整个网格被水完全包围&#xff0c;但其中恰好有…...

如何解决缓存和数据库的数据不一致问题

数据不一致问题是操作数据库和操作缓存值的过程中&#xff0c;其中一个操作失败的情况。实际上&#xff0c;即使这两个操作第一次执行时都没有失败&#xff0c;当有大量并发请求时&#xff0c;应用还是有可能读到不一致的数据。 如何更新缓存 更新缓存的步骤就两步&#xff0…...

linux系统下vscode portable版本的python环境搭建003:venv

这里写自定义目录标题 python安装方案一. 使用源码安装&#xff08;有[构建工具](https://blog.csdn.net/ResumeProject/article/details/136095629)的情况下&#xff09;方案二.使用系统包管理器 虚拟环境安装TESTCG 本文目的&#xff1a;希望在获得一个新的系统之后&#xff…...

使用TinyXML-2解析XML文件

一、XML介绍 当我们想要在不同的程序、系统或平台之间共享信息时&#xff0c;就需要一种统一的方式来组织和表示数据。XML&#xff08;EXtensible Markup Language&#xff0c;即可扩展标记语言&#xff09;是一种用于描述数据的标记语言&#xff0c;它让数据以一种结构化的方…...

Linux:docker在线仓库(docker hub 阿里云)基础操作

把镜像放到公网仓库&#xff0c;这样可以方便大家一起使用&#xff0c;当需要时直接在网上拉取镜像&#xff0c;并且你可以随时管理自己的镜像——删除添加或者修改。 1.docker hub仓库 2.阿里云加速 3.阿里云仓库 由于docker hub是国外的网站&#xff0c;国内的对数据的把控…...

C语言程序设计(第四版)—习题7程序设计题

目录 1.选择法排序。 2.求一批整数中出现最多的数字。 3.判断上三角矩阵。 4.求矩阵各行元素之和。 5.求鞍点。 6.统计大写辅音字母。 7.字符串替换。 8.字符串转换成十进制整数。 1.选择法排序。 输入一个正整数n&#xff08;1&#xff1c;n≤10&#xff09;&#xf…...

ZCC6982-同步升压充双节锂电池充电芯片

特性 ■高达 2A 的可调充电电流&#xff08;受实际散热和输入功率限制&#xff09; ■支持 8.4V、8.6V、8.7V、8.8V 的充满电压&#xff08;限QFN&#xff09; ■高达 28V 的输入耐压保护 ■高达 28V 的电池端耐压保护 ■宽输入工作电压范围&#xff1a;3.0V~6.5V ■峰值…...

定时器(基本定时器、通用定时器、高级定时器)

目录 一、基本定时器 二、通用定时器 三、高级定时器 一、基本定时器 1、作用&#xff1a;计时和计数。 二、通用定时器 1、除了有基本定时器的计时和计数功能外&#xff0c;主要有输入捕获和输出比较的功能&#xff0c;硬件主要由六大部分组成&#xff1a; ① 时钟源 ② 控…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...