分享一个有意思的文字飞入动画(模仿水滴融合)

news2024/9/21 4:33:21

先上效果图:
在这里插入图片描述
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        :root {
            --text-color: #f6f1e6;
            --drops-color: #231d1c;
        }

        body {
            background: var(--text-color);
            font-family: Georgia, serif;
        }

        .canvas {
            position: relative;
            height: 100vh;
            overflow: hidden;
        }
        .canvas--animated .puddle__letter {
            -webkit-animation-play-state: running;
            animation-play-state: running;
        }

        .puddle {
            position: absolute;
            display: flex;
            transform: rotate(var(--r, 0deg)) translate(calc(-50% - var(--x, 0)), calc(-50% - var(--y, 0)));
            top: 50%;
            left: 50%;
            color: var(--text-color);
            font-size: 6vmin;
            white-space: pre;
        }
        .puddle__letter {
            transform: translateY(800px);
            padding: 0.1em 0.2em;
            margin: -0.1em -0.2em;
            will-change: transform;
            -webkit-animation: drop 800ms var(--delay) ease-out forwards paused;
            animation: drop 800ms var(--delay) ease-out forwards paused;
        }

        .combined-puddles {
            position: relative;
            height: 100%;
            z-index: -1;
            filter: url(#drops-filter);
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }
        .combined-puddles .puddle__letter {
            border-radius: 50%;
            color: var(--drops-color);
            background-color: currentColor;
        }
        .combined-puddles .puddle__letter--t-1 {
            box-shadow: 0.0259077911em 0.0158195613em 0 0.156531918em currentColor;
        }
        .combined-puddles .puddle__letter--t-2 {
            box-shadow: 0.0027610231em 0.0292517118em 0 0.0017377822em currentColor;
        }
        .combined-puddles .puddle__letter--t-3 {
            box-shadow: 0.0014897121em 0.0208965418em 0 0.2029532073em currentColor;
        }
        .combined-puddles .puddle__letter--t-4 {
            box-shadow: 0.0181212165em 0.0001267036em 0 0.2696130855em currentColor;
        }
        .combined-puddles .puddle__letter--t-5 {
            box-shadow: 0.0299544544em 0.0155872295em 0 0.3927980665em currentColor;
        }
        .combined-puddles .puddle__letter--t-6 {
            box-shadow: 0.0223628085em 0.013623193em 0 0.3951977831em currentColor;
        }
        .combined-puddles .puddle__letter--t-7 {
            box-shadow: 0.017073126em 0.0166402911em 0 0.1251815461em currentColor;
        }
        .combined-puddles .puddle__letter--t-8 {
            box-shadow: 0.0160218528em 0.0103797109em 0 0.2355980051em currentColor;
        }
        .combined-puddles .puddle__letter--t-9 {
            box-shadow: 0.0061457537em 0.0272304962em 0 0.0502537243em currentColor;
        }
        .combined-puddles .puddle__letter--t-10 {
            box-shadow: 0.0010890892em 0.0108737853em 0 0.2990892848em currentColor;
        }

        @-webkit-keyframes drop {
            0% {
                transform: translate(0, 100vh);
            }
            80% {
                transform: translate(0, -5px);
            }
            100% {
                transform: translate(0, 0);
            }
        }

        @keyframes drop {
            0% {
                transform: translate(0, 100vh);
            }
            80% {
                transform: translate(0, -5px);
            }
            100% {
                transform: translate(0, 0);
            }
        }
    </style>
</head>
<body>
<div class="canvas">
    <div class="puddle" style="--x: 1.55em; --y: 3.73em">Roses are red</div>
    <div class="puddle" style="--x: 1.5em; --y: 1.8em">Violets are blue</div>
    <div class="puddle" style="--x: -1.5em; --y: -1.8em">Unexpected ";"</div>
    <div class="puddle" style="--x: -1.3em; --y: -3.7em">On line 32</div>
</div>
</body>
<script>
    class Droppy {
        DEFAULT_OPTIONS = {
            canvasSelector: ".canvas",
            textSelector: ".puddle",
            letterClassName: "puddle__letter",
            dropsClassName: "combined-puddles",
            delayBetweenDrops: 95,
            dropTypes: 10,
            wordAngleRange: [-3, 3]
        };

        constructor(opts) {
            this.opts = { ...this.DEFAULT_OPTIONS, ...opts };
            this.$textSelector = document.querySelectorAll(this.opts.textSelector);
            this.$canvas = document.querySelector(this.opts.canvasSelector);
            this.init();
        }

        init() {
            this.injectSVGFilter();
            this.wrapLetters();
            this.addDelayToEachLetter();
            this.createDrops();
            this.startAnimation();
        }

        getRandomInt = (min, max) => {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        };

        startAnimation() {
            this.$canvas.classList.add("canvas--animated");
        }

        wrapLetters() {
            this.$textSelector.forEach(($word) => {
                const letters = Array.from($word.innerText).map((letter) => {
                    const dropType = this.getRandomInt(1, this.opts.dropTypes);
                    const className = `${this.opts.letterClassName} ${this.opts.letterClassName}--t-${dropType}`;
                    return `<div class="${className}">${letter}</div>`;
                });
                const angle = this.getRandomInt(
                    this.opts.wordAngleRange[0],
                    this.opts.wordAngleRange[1]
                );
                $word.style.cssText += `--r:${angle}deg`;
                $word.innerHTML = letters.join("");
            });
        }
        addDelayToEachLetter() {
            const letters = document.querySelectorAll(`.${this.opts.letterClassName}`);
            Array.from(letters, ($letter, index) => {
                const delay = index * this.opts.delayBetweenDrops;
                $letter.style.cssText += `--delay:${delay}ms`;
            });
        }

        createDrops() {
            const $drops = document.createElement("div");
            $drops.className = this.opts.dropsClassName;
            Array.from(this.$textSelector, ($word) =>
                $drops.appendChild($word.cloneNode(true))
            );
            this.$canvas.appendChild($drops);
        }

        injectSVGFilter() {
            const filter =
                '<svg style="display:none;"><filter id="drops-filter" x="-50%" width="200%" y="-50%" height="200%" color-interpolation-filters="sRGB"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" /><feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 21 -7" result="cm" /></filter></svg>';
            this.$canvas.insertAdjacentHTML("beforeend", filter);
        }
    }
    new Droppy();

</script>
</html>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前后端分离demo 旅馆管理系统(Angular+Springboot)

模型设计 旅馆管理系统&#xff0c;主要涉及到登记入住&#xff0c;退房以及客房和客人信息管理&#xff1b;经过分析抽像出涉及到的实体以及各实体之间的关系&#xff1a;   可以看出整个业务以客房为中心&#xff0c;入住&#xff0c;退房&#xff0c;定价&#xff0c;收费…

Build an SAP Fiori App(一)后面更新中

1.登录 SAP BTP Trial 地址&#xff1a; https://account.hanatrial.ondemand.com 流程可以参考 点击 serviced marketplace 搜索studio 点击创建 点击创建&#xff0c;点击view subscription 点击go to application 创建完成后 添加新链接 Field Value Name ES5 - if you’…

Shell基础入门实战

写在前面 好久没在项目内做自动化了&#xff0c;主要是现阶段在项目内做自动化收益不大&#xff0c;最近开发做batch run的正好缺人&#xff0c;我看了一下代码&#xff0c;就是通过代码读取jar包和远程服务器连接&#xff0c;然后通过shell脚本&#xff0c;向数据库插入数据&a…

如何成为一名优秀的接口自动化测试工程师?了解这些技能是关键

摘要&#xff1a; 随着互联网行业的不断发展&#xff0c;越来越多的应用程序通过API接口提供服务。因此&#xff0c;接口自动化测试成为了保障软件质量的重要环节。本文将介绍接口自动化测试所需掌握的技能&#xff0c;以及相关的历史进程。 B站首推&#xff01;2023最详细自…

什么是 Java 垃圾回收器~

什么是 Java 垃圾回收器 Java 垃圾回收器是 Java 虚拟机 (JVM) 的三个重要模块 (另外两个是解释器和多线程机制) 之一&#xff0c;为应用程序提供内存的自动分配 (Memory Allocation)、自动回收 (Garbage Collect) 功能&#xff0c;这两个操作都发生在 Java 堆上 (一段内存快)…

sqoop安装

文章目录 1. 上传安装包至虚拟机2. 解压安装包到指定路径3. 修改目录名4. 配置环境变量5. 修改配置文件6. 拷贝mysql驱动包7. 验证安装是否成功8. 测试sqoop连接mysql 注&#xff1a;sqoop安装的前提条件是环境已安装java和hadoop 1. 上传安装包至虚拟机 上传安装包sqoop-1.4.…

信通初试第一:无科研无竞赛一战上岸上海交大819学硕感悟

笔者来自通信考研小马哥23上交819全程班学员 信通初试第一&#xff1a;无科研无竞赛一战上岸上海交大819学硕感悟 原创2023-04-27 11:04通信考研小马哥 笔者来自通信考研小马哥23上交819全程班学员 本人情况&#xff1a; 本人是19届交本&#xff0c;本科成绩很差&#xff0c;…

赎金信(Hash的应用)

给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 来源&#xff1a;力扣&#xff0…

Java 实现 YoloV7 目标检测

1 OpenCV 环境的准备 这个项目中需要用到 opencv 进行图片的读取与处理操作&#xff0c;因此我们需要先配置一下 opencv 在 java 中运行的配置。 首先前往 opencv 官网下载 opencv-4.6 &#xff1a;点此下载&#xff1b;下载好后仅选择路径后即可完成安装。 此时将 opencv\b…

WMS是什么?

WMS&#xff08;Warehouse Management System&#xff09;中文译作仓库管理系统&#xff0c;是一种专用于物流仓储管理的IT系统。它主要应用于企业物流中心、配送中心、供应商物料储备中心、电子商务配送中心等仓库管理过程中。 WMS系统可以帮助企业管理和控制其物流仓储流程。…

线程池的设计

一.什么是线程池? 线程池就是创建若干个可执行的线程放到容器中&#xff0c;有任务处理时&#xff0c;会提交到线程池中的任务队列中&#xff0c;线程处理完不是销毁&#xff0c;而是阻塞等待下一个任务。 二.为何要使用线程池? 降低资源消耗。重复利用创建好的线程减少线…

NLP原理和应用入门:paddle(梯度裁剪、ONNX协议、动态图转静态图、推理部署)

目录 一、梯度裁剪 1.1设定范围值裁剪 1. 全部参数裁剪&#xff08;默认&#xff09; 2. 部分参数裁剪 1.2 通过L2范数裁剪 1.3通过全局L2范数裁剪 二. 模型导出ONNX协议 三、动态图转静态图 3.1两种图定义 3.2 什么场景下需要动态图转静态图 3.3为什么动态图模式越来…

k8s 部署 seata1.6.0 集群 基于 nacos 注册中心 + mysql 数据库

k8s 部署 seata1.6.0 集群 基于 nacos 注册中心 mysql 数据库 大纲 1 镜像制作2 准备configmap3 准备deploy 部署文件4 部署seata到k8s 镜像制作 下载seata 选择1.6.0。下载后得到 seata-server-1.6.0.zip 已经上传到百度云盘 下载地址&#xff1a;http://seata.io/zh-cn…

Maven 依赖下载失败解决方案——配置国内源 + 具体解决办法

目录 前言 一、配置 Maven 国内源 二、重新下载jar包 三、其他问题 前言 最近发现 spring-boot 框架更新到 2.7.11 了&#xff0c;由于以前一直使用的是 2.7.9 &#xff0c;所以一直出现依赖下载失败的问题&#xff0c;实际上这是由于 IDEA 会先加载之前下载好的依赖&#xf…

openharmony内核中不一样的双向链表

不一样的双向链表 链表初识别遍历双向链表参考链接 链表初识别 最近看openharmony的内核源码时看到一个有意思的双向链表&#xff0c;结构如下 typedef struct LOS_DL_LIST{struct LOS_DL_LIST *pstPrev; //前驱节点struct LOS_DL_LIST *pstNext; //后继节点 }LOS_DL_LIST;不…

FPGA入门系列12--RAM的使用

文章简介 本系列文章主要针对FPGA初学者编写&#xff0c;包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解&#xff0c;旨在更快速的提升初学者在FPGA开发方面的能力&#xff0c;每一个章节中都有针对性的代码…

Spring IOC DI - 整合MyBatis

Spring IOC目录 主要内容Spring 框架介绍Spring 框架的优势(对比以前项目的缺点)Spring 框架引入历史发展框架学习三要素Spring 模块介绍 Spring IoC/DI - 引入IoC/DI 概念辨析使用IoC/DI的好处IoC/DI具体应用场景 Spring IoC/DI - 代码实现环境准备Spring 框架环境搭建创建Mav…

图的遍历和应用

文章目录 图的遍历深度优先遍历对于无向图的邻接矩阵的深度优先遍历无向非连通图的深度优先遍历 对于无向图的邻接表的深度优先遍历非递归实现深度优先遍历无向图的邻接矩阵代码实现无向图的邻接表代码实现递归和非递归的同异 广度优先遍历邻接表BFS邻接矩阵BFS 图的应用生成树…

Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

前言 在项目研发中&#xff0c;相信大家都遇到过给用户增加头像照片的需求。 随着手机版本的不断更新&#xff0c;android 8、android 9、android 10、android 12、android 13、鸿蒙系统等等&#xff1b;遇到这个功能需求&#xff0c;大家肯定会想&#xff0c;“这还不好写&…

“双碳”目标下二氧化碳地质封存技术应用前景及模型构建实践方法

二氧化碳地质封存技术起步较晚&#xff0c;目前仍没有一套相对完整的行业规范&#xff1b;且就该技术而言&#xff0c;涉及环节众多&#xff0c;理论相对复杂&#xff0c;对于行业的新入局者不太友好。因此&#xff0c;结合时代背景&#xff0c;我们首次尝试对二氧化碳地质封存…