HTML - 简易版打字练习

news/2024/9/11 3:58:26/ 标签: html, 前端
htmledit_views">

1. 赛博朋克风格的视觉设计

  • 颜色与渐变:通过linear-gradient设置了背景的颜色渐变,使用高饱和度的霓虹色彩(如橙色、绿色和蓝色)来营造赛博朋克的视觉效果。这种配色方案是赛博朋克风格的典型元素。

  • 立体感和阴影:使用 box-shadow 为字符方框添加阴影,使其看起来具有一定的立体感和浮动感,模拟电子设备或键盘按键的效果。

  • 文本阴影:通过 text-shadow 给字符添加阴影,增强了赛博朋克风格的霓虹灯效果。这种效果在高对比度的背景下尤其突出,营造出虚拟世界的视觉效果。

2. 动态效果与动画

  • Glitch动画:利用 @keyframes 定义了 glitch 动画,通过clip-pathtransform模拟文本的抖动和错位,营造出电子干扰(glitch)的效果。这种故障效果是赛博朋克风格中常见的表现形式,模拟了数字世界中不稳定的电子信号。

  • 伪元素 ::after:使用 ::after 伪元素在每个字符方框后叠加一个内容相同的元素,通过visibility控制显示与隐藏,并在鼠标悬停时触发 glitch 动画,使其看起来像是字符发生了瞬间故障。

3. 交互与响应

  • 鼠标悬停效果:在 .character-box:hover::after 中定义了鼠标悬停时的动画效果,当用户将鼠标悬停在字符方框上时,伪元素 ::after 显示并触发 glitch 效果。这种交互为页面增添了动态元素,使用户的体验更加生动。

  • 按键状态变化:通过CSS类的切换(如 .correct, .incorrect, .highlighted)动态更新字符方框的状态和颜色,实时反馈用户输入的正确性。这种视觉反馈让用户能够迅速了解自己输入的正确与否。

4. 布局与排版

  • 容器布局:使用 display: inline-block;text-align: center; 将字符方框、输入框和结果展示区域合理布局。整个页面通过设置 widthmargin,保持在不同设备和屏幕尺寸上的一致性。

  • 字符方框的设计:每个字符被放置在独立的 .character-box 容器中,使得每个字符都有自己的背景、阴影和动画效果。这种设计不仅清晰美观,还增强了赛博朋克风格的整体感。

5. JavaScript 动态逻辑

  • 分页显示:通过JavaScript将长文本拆分为每页100个字符,并在用户打完一页后自动切换到下一页,实现了文本的分页显示,防止内容过于拥挤。

  • 实时输入检查:JavaScript动态检查用户输入的每个字符,利用 .correct, .incorrect, .highlighted 类名的切换实现实时的视觉反馈。

主要代码:

html"><!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>

 


http://www.ppmy.cn/news/1508651.html

相关文章

【C++类和对象(中)】—— 我与C++的不解之缘(四)

前言&#xff1a; 接下来进行类和对象中的学习&#xff0c;了解类和对象的默认成员函数 一、类和对象默认成员函数 默认成员函数就是用户没有显示实现&#xff0c;编译器会自动生成的成员函数。 一个类&#xff0c;我们不显示实现的情况下&#xff0c;编译器就会默认生成一下留…

【Kubernetes】k8s集群Pod控制器

目录 一.Pod控制器作用 二.Pod控制器类型 1.Deployment&#xff08;简称deploy&#xff09; ReplicaSet&#xff08;简称rs&#xff09; 2.StatefulSet&#xff08;简称sts&#xff09; 创建SatefulSet控制器 3.DaemonSet&#xff08;简称ds&#xff09; 4.Job 5.Cron…

【项目】火灾烟雾检测管理系统。PyQT5+QT Designe+YOLOv8_ssod半监督算法+OpenCV

【项目】火灾烟雾检测管理系统。PyQT5QT DesigneYOLOv8_ssod半监督算法OpenCV 0.摘要1.引言2.烟雾检测算法2.0图像标注2.1 YOLOv8全监督算法结构2.2 Efficient-Teacher半监督算法结构 3.性能对比图4.源码、论文获取 0.摘要 火灾是常见而危险的自然灾害&#xff0c;不仅对人类生…

【Python】Python中一些有趣的用法

Python是一种非常灵活和强大的编程语言&#xff0c;它有很多有趣的用法&#xff0c;以下是一些例子&#xff1a; 一行代码实现FizzBuzz&#xff1a; print(\n.join([FizzBuzz[i%3*4:i%5*8:-1] or str(i) for i in range(1, 101)]))使用列表推导式生成斐波那契数列&#xff1a; …

在 CentOS 7 上安装 Redmine 的详细步骤及 20 个经典用法

目录 1. 引言 2. 安装步骤 2.1 更新系统 2.2 安装依赖包 2.3 安装 MariaDB 数据库 2.4 配置 MariaDB 2.5 安装 Ruby 2.6 安装 Redmine 2.7 配置 Redmine 2.8 安装 Bundler 和必要的 Gems 2.9 生成密钥并迁移数据库 2.10 配置 Apache 2.11 启动 Apache 并设置开机自…

ZLMediaKit如何结合webrtc实现双向对讲

目录 1. 安装和配置ZLMediaKit 2. 启用WebRTC模块 3. 创建WebRTC会话 4. 处理媒体流 5. 实现双向通信 6. 调试和测试 7. 安全性考虑 ZLMediaKit结合WebRTC实现双向对讲的过程涉及多个步骤&#xff0c;包括安装配置ZLMediaKit、启用WebRTC模块、创建WebRTC会话、处理媒体…

【LeetCode】将有序数组转换为二叉搜索树

目录 一、题目二、解法完整代码 一、题目 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1…

知识改变命运 数据结构【杨辉三角(顺序表)】

杨辉三角 首先我们可以发现题目中返回类型是一个 这其实返回的类似与一个二维数组 我们大概分析下题目根据画图可知&#xff0c;我们可以把每一行的元素进行存储&#xff0c;然后再把每一行存储起来&#xff0c;然后就实现了题目 代码&#xff1a; public List<List<…

Unity初识

1&#xff1a;下载Unity Hub 下载地址&#xff1a;Unity官方下载_Unity最新版_从Unity Hub下载安装 | Unity中国官网 建议直接使用unity hub因为支持比较全面&#xff0c;适合新手 有中文 管理 编辑器等等功能支持 下载安装不过多介绍 2&#xff1a;Unity Hub汉化 因为我…

mysql主从服务配置

主从MySQL服务器 [rootlocalhost ~]# yum -y install ntpdate [rootlocalhost ~]# ntpdate cn.ntp.org.cn [rootlocalhost ~]# yum -y install rsync [rootlocalhost ~]# vim mysql.sh #!/bin/bash yum list installed |grep libaio if [ $? ne 0 ]; then yum -y install…

Forcepoint 网络安全解决方案

Forcepoint 作为全球领先的网络安全解决方案提供商&#xff0c;自 1994 年成立以来&#xff0c;便一直致力于为企业和政府机构提供最前沿、最有效的安全技术&#xff0c;以全力守护其最为珍贵的资产和数据。公司总部坐落于美国得克萨斯州奥斯汀市&#xff0c;凭借其卓越的技术实…

Java 多线程练习 (2024.8.12)

MultiProcessingExercise1 package MultiProcessingExercise20240812;public class MultiProcessingExercise1 {public static void main(String[] args) {// 设置、获取线程名称// 如果使用继承Thread类的方式实现多线程&#xff0c;那么可以直接通过set和get方法进行设置和获…

Oracle ACE是什么缩写?

大家都知道&#xff0c;Oracle有个ACE 计划&#xff0c;旨在奖励和表彰个人对 Oracle 社区做出的贡献。 这些贡献主要包括两方面&#xff1a; 知识与经验分享&#xff0c;如撰写博客、书籍和文章&#xff1b;制作视频教程&#xff1b;为开源项目做贡献&#xff1b;编写代码&a…

10分钟学会Docker的安装和使用

Docker 是一个用于开发、发布和运行应用程序的开源平台。它通过提供轻量级的容器技术&#xff0c;使得应用程序可以在任何环境中一致地运行。以下是快速学会Docker的安装和使用的步骤。 1. 安装Docker 在Windows上安装 下载Docker Desktop&#xff1a; 访问Docker官网下载适用…

Java->双击Window批处理程序动态切换Java版本

JDK8 echo off chcp 65001 >nul :: 设置控制台编码为UTF-8&#xff0c;避免中文乱码:: 检查是否以管理员身份运行 openfiles >nul 2>&1 if %errorlevel% neq 0 (echo 请求管理员权限...powershell -Command "Start-Process cmd -ArgumentList /c %~fnx0 -Ve…

13.1 Python 正则表达式基础

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

苹果发布 AirPods Pro 2 测试版固件 搭配iOS 18新特性

苹果今天发布了AirPods Pro 2 的第三个测试版固件&#xff0c;包括 Lightning 和 USB-C 两个版本。更新后的固件版本号为 7A5266c&#xff0c;高于 7A5244b&#xff0c;目前可供开发者使用。这是苹果公司自 6 月份宣布 AirPods Pro 2 新功能以来发布的第三个固件更新。 作为iOS…

git拉取后,代码不见了,没有冲突覆盖,且,没有删除,看我是怎么找回的

git拉取后&#xff0c;代码不见了&#xff0c;没有冲突覆盖&#xff0c;且&#xff0c;没有删除 重点提醒 当你的代码丢失时&#xff0c;不要惊慌&#xff0c;首先尝试使用本地的历史记录和远程仓库来找回代码。如果这些方法不起作用&#xff0c;你可以考虑其他的救援工具或寻…

搭建高可用OpenStack(Queen版)集群(十)之部署分布式存储Ceph

一、Ceph知识点学习 Ceph知识点学习&#xff1a;https://www.cnblogs.com/happy-king/p/9207509.html 二、部署分布式存储Ceph 一&#xff09;设置yum源 在全部控制与计算节点设置epel与ceph yum源 epel源&#xff1a;repo安装包下载_开源镜像站-阿里云 ceph源&#xff1a;cep…

在亚马逊云科技上利用生成式AI开发用户广告营销平台

项目简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 本次介绍的是如何利用亚马逊云科技大模型托…