HTML - 简易版打字练习

1. 赛博朋克风格的视觉设计
-
颜色与渐变:通过
linear-gradient设置了背景的颜色渐变,使用高饱和度的霓虹色彩(如橙色、绿色和蓝色)来营造赛博朋克的视觉效果。这种配色方案是赛博朋克风格的典型元素。 -
立体感和阴影:使用
box-shadow为字符方框添加阴影,使其看起来具有一定的立体感和浮动感,模拟电子设备或键盘按键的效果。 -
文本阴影:通过
text-shadow给字符添加阴影,增强了赛博朋克风格的霓虹灯效果。这种效果在高对比度的背景下尤其突出,营造出虚拟世界的视觉效果。
2. 动态效果与动画
-
Glitch动画:利用
@keyframes定义了glitch动画,通过clip-path和transform模拟文本的抖动和错位,营造出电子干扰(glitch)的效果。这种故障效果是赛博朋克风格中常见的表现形式,模拟了数字世界中不稳定的电子信号。 -
伪元素
::after:使用::after伪元素在每个字符方框后叠加一个内容相同的元素,通过visibility控制显示与隐藏,并在鼠标悬停时触发glitch动画,使其看起来像是字符发生了瞬间故障。
3. 交互与响应
-
鼠标悬停效果:在
.character-box:hover::after中定义了鼠标悬停时的动画效果,当用户将鼠标悬停在字符方框上时,伪元素::after显示并触发glitch效果。这种交互为页面增添了动态元素,使用户的体验更加生动。 -
按键状态变化:通过CSS类的切换(如
.correct,.incorrect,.highlighted)动态更新字符方框的状态和颜色,实时反馈用户输入的正确性。这种视觉反馈让用户能够迅速了解自己输入的正确与否。
4. 布局与排版
-
容器布局:使用
display: inline-block;和text-align: center;将字符方框、输入框和结果展示区域合理布局。整个页面通过设置width和margin,保持在不同设备和屏幕尺寸上的一致性。 -
字符方框的设计:每个字符被放置在独立的
.character-box容器中,使得每个字符都有自己的背景、阴影和动画效果。这种设计不仅清晰美观,还增强了赛博朋克风格的整体感。
5. JavaScript 动态逻辑
-
分页显示:通过JavaScript将长文本拆分为每页100个字符,并在用户打完一页后自动切换到下一页,实现了文本的分页显示,防止内容过于拥挤。
-
实时输入检查:JavaScript动态检查用户输入的每个字符,利用
.correct,.incorrect,.highlighted类名的切换实现实时的视觉反馈。
主要代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>中文打字练习</title><link href="https://fonts.font.im/css?family=Do+Hyeon" rel="stylesheet"><style>body {font-family: Arial, sans-serif;text-align: center;margin-top: 50px;background-image: url('https://bkimg.cdn.bcebos.com/pic/0ff41bd5ad6eddc451da707ff483a1fd5266d11695a4?x-bce-process=image/format,f_auto/quality,Q_70/resize,m_lfit,limit_1,w_536');background-size: cover;background-position: center;background-attachment: fixed;color: white;}#text-to-type-container {display: inline-block;font-size: 24px;margin: 20px 0;background-color: rgba(0, 0, 0, 0.5);padding: 10px;border-radius: 10px;text-align: left;width: 80%;}.character-box {display: inline-block;width: 40px;height: 55px;line-height: 55px;text-align: center;margin: 2px;font-weight: bold;font-family: 'Do Hyeon', sans-serif;border-radius: 5px;background: linear-gradient(30deg,transparent 10%,rgb(255, 136, 0) 10% 95%, rgb(0, 255, 149) 95%);box-shadow: 5px 0 0 rgb(0, 204, 255);color: rgb(255, 251, 251);position: relative;overflow: hidden;}.character-box::after {content: attr(data-char);position: absolute;top: 0;left: 0;text-shadow: -5px -2px 0 rgb(0, 183, 255),5px 2px 0 rgb(0, 255, 115);visibility: hidden;width: 100%;height: 100%;background: linear-gradient(30deg,transparent 10%,rgb(255, 136, 0) 10% 95%, rgb(0, 255, 149) 95%);}.character-box.correct {background: linear-gradient(30deg,transparent 10%,#34a853 10% 95%, #a8e6cf 95%);box-shadow: 5px 0 0 #34a853;}.character-box.incorrect {background: linear-gradient(30deg,transparent 10%,#d32f2f 10% 95%, #ff8a80 95%);box-shadow: 5px 0 0 #d32f2f;}.character-box.highlighted {background: linear-gradient(30deg,transparent 10%,#fbc02d 10% 95%, #fff176 95%);box-shadow: 5px 0 0 #fbc02d;}.character-box:hover::after {animation: glitch 1s;animation-timing-function: steps(1, end);visibility: visible;}@keyframes glitch {0% {clip-path: inset(20% -5px 60% 0);transform: translate(-6px, 5px);}10% {clip-path: inset(50% -5px 30% 0);transform: translate(6px, -5px);}20% {clip-path: inset(20% -5px 60% 0);transform: translate(5px, 0px);}30% {clip-path: inset(80% -5px 5% 0);transform: translate(-8px, 5px);}40% {clip-path: inset(0 -5px 80% 0);transform: translate(-4px, -3px);}50% {clip-path: inset(50% -5px 30% 0);transform: translate(-6px, -5px);}60% {clip-path: inset(80% -5px 5% 0);transform: translate(-7px, 5px);}70% {clip-path: inset(0 -5px 80% 0);transform: translate(3px, 6px);}80% {clip-path: inset(50% -5px 30% 0);transform: translate(5px, 5px);}90% {clip-path: inset(20% -5px 60% 0);transform: translate(6px, -5px);}100% {clip-path: inset(0 -5px 80% 0);transform: translate(1px, 5px);}}#user-input {width: 80%;height: 100px;font-size: 24px;margin-top: 20px;border: 2px solid #ccc;padding: 10px;outline: none;background-color: rgba(255, 255, 255, 0.8);border-radius: 10px;color: black;}#results {margin-top: 20px;background-color: rgba(0, 0, 0, 0.5);padding: 10px;border-radius: 10px;display: inline-block;}#pagination {margin-top: 20px;}button {font-size: 18px;padding: 10px 20px;border: none;border-radius: 5px;background-color: #007bff;color: white;cursor: pointer;box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);transition: background-color 0.3s ease;}button:hover {background-color: #0056b3;}button:disabled {background-color: #cccccc;cursor: not-allowed;}</style>
</head>
<body><h1>中文打字练习</h1><div id="text-to-type-container"></div><textarea id="user-input" placeholder="在此输入..." oninput="checkTyping()" onblur="checkCompletion()"></textarea><div id="results"><p>打字速度: <span id="speed">0</span> 字/分钟</p><p>准确率: <span id="accuracy">100</span>%</p><p>用时: <span id="time-taken">0</span> 秒</p></div><div id="pagination"><button onclick="previousPage()" disabled id="prev-button">上一页</button><button onclick="nextPage()" id="next-button">下一页</button></div><script>const textToType = "王楚钦,男,2000年5月11日出生于吉林省吉林市,国际级运动健将 ,中国男子乒乓球运动员。效力于山东魏桥乒乓球俱乐部和中国男子乒乓球队。 2015年12月,升入中国国家乒乓球队一队。2017年12月与薛飞获2017世界青少年锦标赛男双冠军 。2018年7月获2018年韩国乒乓球公开赛混双亚军;8月获2018年雅加达亚运会乒乓球男团冠军 ;10月获得2018布宜诺斯艾利斯青奥会乒乓球男单冠军 。2019年12月9日获“北京青年榜样·时代楷模”人物评选“青少年体育之星”。2021年7月入选2020年东京奥运会中国体育代表团乒乓球项目运动员名单;9月获第十四届全运会男双冠军;2021年11月休斯顿世乒赛混双搭档孙颖莎夺得混双金牌 。2022年1月获WTT澳门冠军赛男子单打冠军;10月获成都第56届世界乒乓球团体锦标赛冠军、WTT澳门冠军赛男子单打冠军 、新乡WTT世界杯男子单打冠军 。2023年4月获2023年WTT冠军赛澳门站男单冠军;9月获杭州第19届亚运会乒乓球男子团体、混双、男单、男双冠军。2024年2月获釜山世乒赛团体赛男子团体决赛冠军 ;5月获2024年WTT沙特阿拉伯大满贯男单、男双、混双冠军 。2024年巴黎奥运会,王楚钦入选中国国家乒乓球队大名单,出战男单、男团以及混双项目。2024年7月获得巴黎奥运会乒乓球混双冠军。";const textToTypeContainer = document.getElementById('text-to-type-container');const userInput = document.getElementById('user-input');const speedDisplay = document.getElementById('speed');const accuracyDisplay = document.getElementById('accuracy');const timeTakenDisplay = document.getElementById('time-taken');const prevButton = document.getElementById('prev-button');const nextButton = document.getElementById('next-button');const charsPerPage = 100;let currentPage = 0;let totalPages = Math.ceil(textToType.length / charsPerPage);let startTime = null;let endTime = null;let typedCharacters = 0;function displayText() {textToTypeContainer.innerHTML = '';const start = currentPage * charsPerPage;const end = Math.min(start + charsPerPage, textToType.length);const pageText = textToType.slice(start, end);pageText.split('').forEach(char => {const span = document.createElement('span');span.innerText = char;span.classList.add('character-box');span.setAttribute('data-char', char);textToTypeContainer.appendChild(span);});}displayText();function checkTyping() {const typedText = userInput.value;if (!startTime) {startTime = new Date();}typedCharacters = typedText.length;// 计算打字速度 (字/分钟)const elapsedTime = (new Date() - startTime) / 60000; // 转换为分钟const speed = Math.round(typedCharacters / elapsedTime);speedDisplay.innerText = speed;// 计算准确率let correctCharacters = 0;const characters = textToTypeContainer.children;for (let i = 0; i < characters.length; i++) {const currentChar = characters[i];if (i < typedText.length) {if (typedText[i] === currentChar.innerText) {currentChar.classList.add('correct');currentChar.classList.remove('incorrect', 'highlighted');correctCharacters++;} else {currentChar.classList.add('incorrect');currentChar.classList.remove('correct', 'highlighted');}} else if (i < typedCharacters) {currentChar.classList.add('highlighted');currentChar.classList.remove('correct', 'incorrect');} else {currentChar.classList.remove('correct', 'incorrect', 'highlighted');}}const accuracy = Math.round((correctCharacters / typedCharacters) * 100);accuracyDisplay.innerText = isNaN(accuracy) ? 100 : accuracy;// 检查是否完成当前页if (typedText.length >= characters.length && currentPage < totalPages - 1) {userInput.value = ''; // 清空输入框nextPage();} else if (typedText.length >= characters.length && currentPage === totalPages - 1) {endTime = new Date();const totalTimeTaken = ((endTime - startTime) / 1000).toFixed(2); // 以秒为单位timeTakenDisplay.innerText = totalTimeTaken;}}function nextPage() {if (currentPage < totalPages - 1) {currentPage++;displayText();prevButton.disabled = false;if (currentPage === totalPages - 1) {nextButton.disabled = true;}}}function previousPage() {if (currentPage > 0) {currentPage--;displayText();nextButton.disabled = false;if (currentPage === 0) {prevButton.disabled = true;}}}</script>
</body>
</html>
相关文章:
HTML - 简易版打字练习
1. 赛博朋克风格的视觉设计 颜色与渐变:通过linear-gradient设置了背景的颜色渐变,使用高饱和度的霓虹色彩(如橙色、绿色和蓝色)来营造赛博朋克的视觉效果。这种配色方案是赛博朋克风格的典型元素。 立体感和阴影:使用…...
【生成式人工智能-四-chatgpt的训练过程-pretrain预训练自督导式学习督导式学习】
大模型是怎么被训练出来的具有人类智慧的 阶段一训练-自我学习-具备知识训练资料self-supervised learning(自督导式学习) 阶段二-怎么让模型具备人的智慧supervised learning 督导式学习预训练pretrain为什么要用预训练的模型?Adapter逆向工…...
期权价格的奥秘:深入理解影响因素
在金融市场中,期权作为一种衍生工具,为投资者提供了风险管理和资产增值的多种可能性。期权价格的波动往往令人着迷,但其背后的定价机制却充满了复杂性。本文将带您探索期权价格变化的奥秘,并尝试以浅显易懂的方式,解析…...
STM32-USART时序与寄存器状态分析
一、时序分析 在UART(通用异步收发传输)通信中,信号线上的状态分为两种:逻辑1(高电平)和逻辑0(低电平)。在空闲状态下,数据线应保持逻辑高电平。UART协议中的各个信号位具…...
从零安装pytorch并在pycharm中使用
背景介绍 目前主流使用的工具有Facebook搞的pythorch和谷歌开发的tensorflow两种,二者在实现理念上有一定区别,pytorch和人的思维模式与变成习惯更像,而tensorflow则是先构建整体结构,然后整体运行,开发调试过程较为繁…...
开源AI工具FastGPT和RagFlow对比
FastGPT和RagFlow都是基于大型语言模型(LLM)的先进AI系统,它们在多个方面有着各自的特点和优势。 以下是对两者性能的详细对比: 一、系统架构与功能 FastGPT: 数据收集:通过从互联网上收集大量的文本数…...
第N2周:NLP中的数据集构建
对于初学者,NLP中最烦人的问题之一就数据集的构建问题,处理不好就会引起shape问题(各种由于shape错乱导致的问题)。这里给出一个模版,大家可根据这个模版来构建。 torch.utils.data是PyTorch中用于数据加载和预处理的…...
AI助力浮雕创作!万物皆可浮雕?Stable Diffusion AI绘画【浮雕艺术】之文生浮雕!
前言 对于浮雕艺术,其实并不了解。但有幸能和“细辛”前辈结识,对浮雕有了简单的了解,浮雕图案的传统方式是先由画师画出图,然后由雕刻师雕刻。画师画图归为浮雕的设计阶段,画师会绘制出浮雕的设计图,这为…...
你觉得大模型时代该出现什么?
大模型的概念都火了两年了,之前各种媒体吹嘘大模型的出现是类似“蒸汽机时代”、“iPhone时刻”等等。那为什么我们期待的结果都没出现呢?咱们先一起回顾下历史。 1、蒸汽机时代 1.1、蒸汽机历史 许多人都在讨论大模型时代好像只是概念在火࿰…...
JS【详解】事件委托
事件委托的简介 事件委托(Event Delegation)是 JS 处理事件的一种技术:不直接在目标元素上设置事件监听器,而是在其父元素或祖先元素上设置监听器,然后利用事件冒泡机制来捕获和处理事件。 事件委托的好处 减少内存占用…...
谈对象系列:C++类和对象
文章目录 一、类的定义1.1类定义的格式类的两种定义方法结构体: 1.2访问限定符1.3类域 二、实例化2.1变量的声明和定义2.2类的大小计算空类的大小(面试): 三、this指针小考题 一、类的定义 1.1类定义的格式 使用class关键字&…...
设计模式20-备忘录模式
设计模式20-备忘录 动机定义与结构定义结构 C代码推导优缺点应用场景总结备忘录模式和序列化备忘录模式1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 序列化1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 对比总结 动机 在软件构建过…...
绘制echarts-liquidfill水球图
文章目录 一、效果图二、步骤1.安装插件2.引入2.主要代码2.素材图片 总结 一、效果图 二、步骤 1.安装插件 npm install echarts npm install echarts-liquidfillecharts5的版本与echarts-liquidfill3兼容,echarts4的版本与echarts-liquidfill2兼容,安装的时候需要…...
应急响应:D盾的简单使用.
什么是应急响应. 一个组织为了 应对 各种网络安全 意外事件 的发生 所做的准备 以及在 事件发生后 所采取的措施 。说白了就是别人攻击你了,你怎么把这个攻击还原,看看别人是怎么攻击的,然后你如何去处理,这就是应急响应。 D盾功…...
c语言第14天笔记
通过指针引用数组 数组元素的指针 数组指针:数组中的第一个元素的地址,也就是数组的首地址。 指针数组:用来存放数组元素地址的数组,称之为指针数组。 注意:虽然我们定义了一个指针变量接收了数组地址,但…...
服装行业QMS中的来料检验:常见问题解析与解决策略
在服装行业的来料检验过程中,常会遇到一系列问题,这些问题可能影响到原材料的质量,进而影响最终产品的品质。以下将详细介绍来料检验的常见问题及相应的解决方法: 一、常见问题 外观瑕疵 问题描述:原材料表面存在污渍…...
健身动作AI识别,仰卧起坐计数(含UI界面)
用Python和Mediapipe打造,让你的运动效果一目了然! 【技术揭秘】 利用Mediapipe的人体姿态估计,实时捕捉关键点,精确识别动作。 每一帧的关键点坐标和角度都被详细记录,为动作分析提供数据支持。 支持自定义动作训练&a…...
GitHub开源金融系统:Actual
Actual:电子金融,本地优先,自由开源- 精选真开源,释放新价值。 概览 Actual的创新之处在于其对个人财务管理的全面考虑,它不仅仅是一个简单的记账工具,而是一个综合性的理财解决方案。它的本地优先设计意味…...
【学习笔记】Day 7
一、进度概述 1、DL-FWI基础入门培训笔记 2、inversionnet_train 试运行——未成功 二、详情 1、InversionNet: 深度学习实现的反演 InversionNet构建了一个具有编码器-解码器结构的卷积神经网络,以模拟地震数据与地下速度结构的对应关系。 (一…...
网络中特殊的 IP 地址
特殊网络 IP 127.0.0.1 127.0.0.1 是本机回送地址,发送到 127.0.0.1 的数据或者从 127.0.0.1 返回的数据只会在本机进行传输, 而不进行外部网络传输。 主要有以下两个作用: 测试本机网络 当我们可以 ping 通 127.0.0.1 的时候, 则说明本机的网卡以及 tc…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
