Html -- 文字时钟

news2024/11/16 12:05:05

Html – 文字时钟

文字时钟,之前在Android上实现了相关效果,闲来无事,弄个网页版的玩玩。。。

在这里插入图片描述

直接上代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Text Clock</title>

    <style type="text/css">
        html, body {
            margin: 0;
            padding: 0;
            background: black;
        }

        .root {
            display: flex;
            justify-content: center;
        }

        .container {
            display: block;
            background: black;
        }
    </style>
</head>
<body>
<div class="root">
    <canvas id="container" class="container"></canvas>
</div>

<script type="text/javascript">
    const HOURS = [
        "一点", "二点", "三点", "四点", "五点", "六点", "七点", "八点", "九点", "十点", "十一点", "十二点"
    ];
    const MINUTES = [
        "一分", "二分", "三分", "四分", "五分", "六分", "七分", "八分", "九分", "十分",
        "十一分", "十二分", "十三分", "十四分", "十五分", "十六分", "十七分", "十八分", "十九分", "二十分",
        "二十一分", "二十二分", "二十三分", "二十四分", "二十五分", "二十六分", "二十七分", "二十八分", "二十九分", "三十分",
        "三十一分", "三十二分", "三十三分", "三十四分", "三十五分", "三十六分", "三十七分", "三十八分", "三十九分", "四十分",
        "四十一分", "四十二分", "四十三分", "四十四分", "四十五分", "四十六分", "四十七分", "四十八分", "四十九分", "五十分",
        "五十一分", "五十二分", "五十三分", "五十四分", "五十五分", "五十六分", "五十七分", "五十八分", "五十九分", ""
    ];
    const SECONDS = [
        "一秒", "二秒", "三秒", "四秒", "五秒", "六秒", "七秒", "八秒", "九秒", "十秒",
        "十一秒", "十二秒", "十三秒", "十四秒", "十五秒", "十六秒", "十七秒", "十八秒", "十九秒", "二十秒",
        "二十一秒", "二十二秒", "二十三秒", "二十四秒", "二十五秒", "二十六秒", "二十七秒", "二十八秒", "二十九秒", "三十秒",
        "三十一秒", "三十二秒", "三十三秒", "三十四秒", "三十五秒", "三十六秒", "三十七秒", "三十八秒", "三十九秒", "四十秒",
        "四十一秒", "四十二秒", "四十三秒", "四十四秒", "四十五秒", "四十六秒", "四十七秒", "四十八秒", "四十九秒", "五十秒",
        "五十一秒", "五十二秒", "五十三秒", "五十四秒", "五十五秒", "五十六秒", "五十七秒", "五十八秒", "五十九秒", ""
    ];

    const INTERVAL_UPDATE = 1000;//时间刷新间隔
    const mColorCenetr = "#ffffff";//中心字体颜色
    const mColorCur = "#ff0000";//选中字体颜色
    const mColorCom = "#bdbdbd";//基础色
    const mColorBg = "#000000";//背景颜色
    const mFont = "华文行楷";//字体

    var mWidth, mHeight;//宽高
    var mH, mM, mS;//当前的时分秒
    var mH24;//24制小时
    var mWeek, mDate, mTime;//星期,日期,时间
    var mRadiusH, mRadiusM, mRadiusS;//三个同心圆的半径
    var mDegreeH, mDegreeM, mDegreeS;//时分秒旋转角度
    var mTextSizeCom;//通用字体大小
    var mTextSizeCenter;//中间字体大小
    var mOffset;//中间文字行间隔
    var mCenterHeight;//文字纵向居中高度

    //
    var canvas;
    var cxt;
    var hd, md, sd, av;

    window.onload = function () {
        initial();
    }

    //适应屏幕大小变化
    window.onresize = function () {
        calcSize();
    }

    function initial() {
        canvas = document.getElementById("container");
        cxt = canvas.getContext("2d");
        calcSize();
        curTime();
        startTask();
    }

    function calcSize() {
        mWidth = window.innerWidth;
        mHeight = window.innerHeight;
        //确保为正方形
        mWidth = mHeight = Math.min(mWidth, mHeight);
        canvas.width = mWidth;
        canvas.height = mHeight;
        // console.log(mWidth + " - " + mHeight);

        //字体大小
        mTextSizeCom = mWidth / 50;//通用字体大小
        mTextSizeCenter = mWidth / 35;//中间字体大小
        mOffset = mTextSizeCenter / 2;//中间文字间隔
        mCenterHeight = (mHeight - mTextSizeCom) / 2;

        //各圆半径
        mRadiusH = mWidth / 6;
        mRadiusM = mRadiusH + 4 * mTextSizeCom;//3+1
        mRadiusS = mRadiusM + 5 * mTextSizeCom;//4+1
        // console.log(mRadiusH + " - " + mRadiusM + " - " + mRadiusS);
    }

    function startTask() {
        setInterval(function () {
            curTime();
            //内嵌一个有限循环
            var times = 0;
            var interval = setInterval(function () {
                if (times > 6) {
                    clearInterval(interval);
                } else {
                    doAnimation();
                    times++;
                }
            }, 10)
        }, INTERVAL_UPDATE);
    }

    //自定义线性循环动画
    function doAnimation() {
        //+ -> 顺时针; - -> 逆时针
        av = av - 0.9;//总偏移量/次数

        if (mM === 0 && mS === 0) {
            mDegreeH = hd + av * 5;//时圈旋转角度是分秒的5倍,线性的旋转30°
        }

        if (mS === 0) {
            mDegreeM = md + av;//线性的旋转6°
        }

        mDegreeS = sd + av;//线性的旋转6°
        drawCanvas();
    }

    //刷新背景
    function updateBg() {
        cxt.fillStyle = mColorBg;
        cxt.fillRect(0, 0, mWidth, mHeight);
    }

    //绘制中间时间/日期/星期
    function drawCenterInfo() {
        cxt.save();
        cxt.fillStyle = mColorCenetr;
        cxt.font = mTextSizeCenter + "px " + mFont;

        //draw time
        var len = (mTime.length -2) * mTextSizeCenter / 2;//数字大小只有文字的一半 //去掉两个符号
        cxt.fillText(mTime, (mWidth - len) / 2, mHeight / 2 - mTextSizeCenter * 3 / 2 - mOffset);

        //draw date
        var len2 = (mDate.length-2) * mTextSizeCenter / 2;//去掉两个符号
        cxt.fillText(mDate, (mWidth - len2) / 2, mHeight / 2 - mTextSizeCenter / 2);

        //draw week
        var len3 = mWeek.length * mTextSizeCenter;
        cxt.fillText(mWeek, (mWidth - len3) / 2, mHeight / 2 + mTextSizeCenter / 2 + mOffset);
        cxt.restore();
    }

    function drawHour() {
        cxt.save();
        //只能旋转角度,以原点(0,0)
        cxt.translate(mWidth / 2, mHeight / 2);
        cxt.rotate(mDegreeH * Math.PI / 180);//* Math.PI / 180
        cxt.translate(-mWidth / 2, -mHeight / 2);//旋转完之后需要移回去

        //时针圈: 360/12 = 30度
        for (var i = 0; i < HOURS.length; i++) {
            cxt.save();
            cxt.translate(mWidth / 2, mHeight / 2);
            cxt.rotate(30 * i * Math.PI / 180);
            cxt.translate(-mWidth / 2, -mHeight / 2);

            if (i + 1 === mH || (i === 11 && mH === 0)) {
                //当前时
                cxt.fillStyle = mColorCur;
            } else {
                cxt.fillStyle = mColorCom;
            }
            cxt.font = mTextSizeCom + "px " + mFont;
            cxt.fillText(HOURS[i], mWidth / 2 + mRadiusH, mCenterHeight);
            cxt.restore();
        }
        cxt.restore();
    }

    function drawMinute() {
        cxt.save();
        //只能旋转角度,以原点(0,0)
        cxt.translate(mWidth / 2, mHeight / 2);
        cxt.rotate(mDegreeM * Math.PI / 180);//* Math.PI / 180
        cxt.translate(-mWidth / 2, -mHeight / 2);//旋转完之后需要移回去

        //分针圈: 360/60 = 6度
        for (var i = 0; i < MINUTES.length; i++) {
            cxt.save();
            cxt.translate(mWidth / 2, mHeight / 2);
            cxt.rotate(6 * i * Math.PI / 180);
            cxt.translate(-mWidth / 2, -mHeight / 2);

            if (i + 1 === mM) {
                //当前时
                cxt.fillStyle = mColorCur;
            } else {
                cxt.fillStyle = mColorCom;
            }
            cxt.font = mTextSizeCom + "px " + mFont;
            cxt.fillText(MINUTES[i], mWidth / 2 + mRadiusM, mCenterHeight);
            cxt.restore();
        }
        cxt.restore();
    }

    function drawSecond() {
        cxt.save();
        //只能旋转角度,以原点(0,0)
        cxt.translate(mWidth / 2, mHeight / 2);
        cxt.rotate(mDegreeS * Math.PI / 180);//* Math.PI / 180
        cxt.translate(-mWidth / 2, -mHeight / 2);//旋转完之后需要移回去

        //秒针圈: 360/60 = 6度
        for (var i = 0; i < MINUTES.length; i++) {
            cxt.save();
            cxt.translate(mWidth / 2, mHeight / 2);
            cxt.rotate(6 * i * Math.PI / 180);
            cxt.translate(-mWidth / 2, -mHeight / 2);

            if (i + 1 === mS) {
                //当前时
                cxt.fillStyle = mColorCur;
            } else {
                cxt.fillStyle = mColorCom;
            }
            cxt.font = mTextSizeCom + "px " + mFont;
            cxt.fillText(SECONDS[i], mWidth / 2 + mRadiusS, mCenterHeight);
            cxt.restore();
        }
        cxt.restore();
    }

    //刷新画布
    function drawCanvas() {
        updateBg();
        drawCenterInfo();
        drawHour();
        drawMinute();
        drawSecond();
    }

    //
    function curTime() {
        let date = new Date();
        let year = date.getFullYear();
        let month = date.getMonth() + 1;
        let day = date.getDate();
        let week = date.getDay();
        mH24 = date.getHours();
        mM = date.getMinutes();
        mS = date.getSeconds();
        mH = mH24 >= 12 ? mH24 - 12 : mH24;

        mTime = formatTime(mH24) + ':' + formatTime(mM) + ':' + formatTime(mS);
        mDate = year + '/' + formatTime(month) + '/' + formatTime(day);
        mWeek = parseWeek(week);
        calculateDegree();
    }

    function calculateDegree() {
        //逆时针旋转
        mDegreeH = -360 / 12 * (mH - 1);
        mDegreeM = -360 / 60 * (mM - 1);
        mDegreeS = -360 / 60 * (mS - 1);

        hd = mDegreeH;
        md = mDegreeM;
        sd = mDegreeS;
        av = 6;//每次动画总偏移量
    }

    function formatTime(fn) {
        return fn < 10 ? "0" + fn : fn;
    }

    function parseWeek(week) {
        var mWeek;
        switch (week) {
            case 1:
                mWeek = "星期一";
                break;
            case 2:
                mWeek = "星期二";
                break;
            case 3:
                mWeek = "星期三";
                break;
            case 4:
                mWeek = "星期四";
                break;
            case 5:
                mWeek = "星期五";
                break;
            case 6:
                mWeek = "星期六";
                break;
            case 7:
                mWeek = "星期日";
                break;
        }

        return mWeek;
    }
</script>
</body>
</html>

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

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

相关文章

基于FPGA的图像自适应阈值二值化算法实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1Otsu方法 4.2 Adaptive Thresholding方法 4.3、FPGA实现过程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 Vivado2019.2 matlab2022a 3.部分核心程序 timescale …

Windows系统上安装MySQL 5.7详细步骤

一、下载 MySQL 5.7 首先&#xff0c;需要前往 MySQL 官网下载 MySQL 5.7 的安装文件&#xff0c;选择适合您系统的版本进行下载。 二、安装 MySQL 5.7 1.解压安装文件 将下载的压缩文件解压到指定的目录下&#xff0c;例如&#xff1a;D:\mysql-5.7。 2.配置 my.ini 文件…

skiaSharp linux 生成验码字体显示不出来

一、拷贝windows下的字体如&#xff1a;C:\Windows\Fonts 设置字体的地方&#xff1a; var fontPath Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts", "TAHOMA.TTF");最终效果&#xff1a;

极值点偏移2

已知 f ( x ) ln ⁡ x x f\left(x\right) \frac{\ln x}{x} f(x)xlnx​&#xff0c;若 f ( x ) a f\left(x\right) a f(x)a有两个不用的零点 x 1 , x 2 x_1, x_2 x1​,x2​&#xff0c;且 x 1 < x 2 x_1<x_2 x1​<x2​&#xff0c;求证&#xff1a; &#xff08;1…

【技术分享】RK356X Ubuntu 推流USB摄像头

本文适用与触觉智能所有RK356X ubuntu系统的主板。 IDO-SBC3566基于瑞芯微RK3566研发的一款高性能低功耗的智能主板&#xff0c;采用四核A55,主频高达1.8GHz&#xff0c;专为个人移动互联网设备和AIOT设备而设计&#xff0c;内置了多种功能强大的嵌入式硬件引擎&#xff0c;为…

前端导出数据到Excel(Excel.js导出数据)

库&#xff1a;Excel.js&#xff08;版本4.3.0&#xff09; 和 FileSaver&#xff08;版本2.0.5&#xff09; CDN地址&#xff1a; <script src"https://cdn.bootcdn.net/ajax/libs/exceljs/4.3.0/exceljs.min.js"></script> <script src"http…

RHCE---搭建博客网站

一.实验要求&#xff1a; Server-NFS-DNS主机配置NFS服务器&#xff0c;将博客网站资源文件共享给Server-web主机&#xff0c;Server-NFS-DNS主机配置DNS Server-web主机配置web服务&#xff0c;通过域名www.openlab.com可以访问到自建的博客网站 二.准备工作 创建两台虚拟机…

C++设计模式_09_Abstract Factory 抽象工厂

与上篇介绍的Factory Method工厂方法模式一样&#xff0c;Abstract Factory 抽象工厂模式也属于典型的“对象创建模式”模式&#xff0c;解决的问题也极其相似&#xff0c;在理解了Factory Method工厂方法模式的基础上再去理解Abstract Factory 抽象工厂模式就会变得更加容易。…

飞书-多维文档-计算时间差

1. 选择字段类型 如图所示&#xff0c;字段类型选择 公式 2. 编辑公式 单击 公式编辑器 在弹出的公式编辑框中输入公式 TEXT([终结时间]-[开始时间],"HH:MM") [终结时间] 和 [开始时间] 请替换成你的表格中对应的字段名称HH:MM 表示输出的时间格式为 时:分其中 “…

如何理解TCP/IP协议?

一、是什么 TCP/IP&#xff0c;传输控制协议/网际协议&#xff0c;是指能够在多个不同网络间实现信息传输的协议簇 TCP&#xff08;传输控制协议&#xff09; 一种面向连接的、可靠的、基于字节流的传输层通信协议 IP&#xff08;网际协议&#xff09; 用于封包交换数据网…

npm常用命令与操作篇

npm简介 npm是什么 npm 的英文是&#xff0c;node package manager&#xff0c;是 node 的包管理工具 为什么需要npm 类比建造汽车一样&#xff0c;如果发动机、车身、轮胎、玻璃等等都自己做的话&#xff0c;几十年也做不完。但是如果有不同的厂商&#xff0c;已经帮我们把…

《windows核心编程》第1章 错误处理

一、错误信息的获取 1.1 C库错误信息 1、获取错误信息 #include <stdio.h> #include <stdlib.h> #include <string.h>int main() {fopen("D:\\ASC", "r");printf("%s\n", strerror(errno));getchar();return 0; } 2、设置错…

nodejs+vue 校园通勤车-计算机毕业设计

在此情况下开发一款校园通勤车可视化系统小程序&#xff0c;于是乎变得非常合乎时宜。 经过网上调查和搜集数据,我们可以发现校园通勤车可视化管理方面的小程序在并不是相当普及,同时在校园通勤车可视化管理方面的可以有许多改进。目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪…

Android切换主题生命周期流程与onSaveInstanceState和onRestoreInstanceState,Kotlin

Android切换主题生命周期流程与onSaveInstanceState和onRestoreInstanceState&#xff0c;Kotlin import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity() {private val TAG "fly&…

基于nodejs+vue 校园通勤车系统

但是管理好校园通勤车可视化又面临很多麻烦需要解决, 信息化已经成为主流,开发一个校园通勤车可视化系统小程序一方面的可能会更合乎时宜,困扰管理层的许多问题当中,校园通勤车 管理也是不敢忽视的一块。另一方面来说也可以提高在校园通勤车可视化管理方面的效率给相关管理人员…

【力扣周赛】第 367 场周赛(⭐二维数组当成一维数组,前后缀分解)

文章目录 竞赛链接Q1&#xff1a;100096. 找出满足差值条件的下标 I竞赛时代码——暴力双循环 Q2&#xff1a;100084. 最短且字典序最小的美丽子字符串竞赛时代码——双指针 Q3&#xff1a;100101. 找出满足差值条件的下标 II竞赛时代码——记录可用最大最小值下标 Q4&#xff…

MATLAB模拟的电磁学时域有限差分法(电子书PDF)

摘要: MATLAB语言具有编程简单&#xff0c;并可以给出精美图像的特点&#xff0c;它已成为理工科大学生必备的系统工具平台。其完备的工具箱功能&#xff0c;使得MATLAB日益受到大学生和工程师们的喜爱。《MATLAB模拟的电磁学时域有限差分法》 目录 第1章 FDTD简介 1.1 时域有限…

Bootstrap的列表组相关知识

目录 01-列表组的相关基础知识02-一个简单的列表组示例03-激活或禁用列表组的一行或多行04-设置列表项的颜色05-给列表项添加徽章 01-列表组的相关基础知识 Bootstrap的list-group是一个用于创建列表组件的CSS类&#xff0c;通常用于显示一个项目列表&#xff0c;如导航菜单或…

Spark内核

环境准备及提交流程 底层通信协议 Akka通信协议&#xff0c;收发邮箱是一体的Netty通信协议&#xff0c;收发邮箱是分开的 任务调度 任务的最小单位是线程。失败重试&#xff0c;会记录失败的次数&#xff0c;如果超过最大重试次数&#xff0c;宣告Application失败。失败的…

knife4j-openapi3 无法使用swagger注解@ApiModelProperty

问题描述 当使用knife4j springboot3&#xff0c; 发现无法使用 swagger注解ApiModelProperty需要单独导入一个包但是即使导入这个包也不生效&#xff0c;即使配置了description也为空 原因 简单来说&#xff1a;swagger2 > swagger3的时候出现了破坏性的更新 将ApiMode…