首页 > 其他分享 >记录--canvas 复刻锤子时钟

记录--canvas 复刻锤子时钟

时间:2023-08-02 17:34:12浏览次数:43  
标签:canvas const -- ctx width 绘制 复刻 deg

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

介绍

canvas:使用脚本 (通常为 JavaScript) 来绘制图形的 HTML 元素。

本人遍历了以下两份文档,学习完就相当于有了笔和纸,至于最后能画出什么,则需要在 canvas 应用方面进一步学习。

  • MDNCanvas 教程1
  • 张鑫旭的 Canvas API 中文文档2

Demo 时钟

下面介绍如何使用 canvas 制作一个时钟,首先分析一个简单的时钟包含哪些部分:

  • 表盘
  • 时针 / 分针 / 秒针
  • 按秒走时

初始化 canvas 画布

<!-- html -->
<canvas id="clock"></canvas>


/* css */
canvas {
  width: 300px;
  height: 300px;
}


// js
const radio = window.devicePixelRatio;
const width = 300 * radio;
const height = 300 * radio;
const canvas = document.getElementById('clock');
const ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;

ctx 对应 “Canvas 2D 渲染上下文”,暴露了大量 API 属性和方法,用于绘制形状,文本,图像和其他对象。

devicePixelRatio 是当前显示设备物理像素分辨率与 CSS 像素分辨率之比。假设该值为 2,表示浏览器使用 2 个物理像素来绘制 1 个 CSS 像素。在上面代码中,会将 canvas 画布尺寸按照该值放大,使图像更清晰。

绘制表盘

/**
 * 绘制表盘
 */
const drawCircle = () => {
  ctx.save();
  ctx.translate(width / 2, height / 2);
  ctx.fillStyle = '#f8f9fa';
  ctx.beginPath();
  ctx.arc(0, 0, 0.4 * width, 0, 2 * Math.PI);
  ctx.fill();
  ctx.restore();
}

save()restore() 可以看作是一对方法,前者保存当前 canvas 画布状态并放在栈最上面,后者将状态依次取出。以 fillStyle 属性为例,代码中 restore 方法执行后,fillStyle 将恢复为之前设置的值。

translate() 对 canvas 坐标系进行整体位移,这里用于变换中心点。

beginPath() 开始一个新路径,之后由 arc() 绘制一个整圆,路径本身没有颜色,可以通过描边或填充为路径着色,代码中使用 fill() 方法为整圆填充颜色,作为表盘。

绘制指针

/**
 * 绘制单根指针
 * @param {Number} deg 指针沿 12 点钟方向顺时针旋转角度
 * @param {Number} l 指针长度(比例值)
 * @param {String} rgb 指针颜色
 */
const pointer = (deg, l, rgb) => {
  ctx.save();
  ctx.rotate(deg);
  ctx.lineWidth = radio;
  ctx.strokeStyle = rgb;
  ctx.beginPath();
  ctx.moveTo(0, 0);
  ctx.lineTo(0, 0 - l * width);
  ctx.stroke();
  ctx.restore();
}

/**
 * 计算时针、分针、秒针的角度并调用 pointer 函数绘制
 */
const drawPointer = () => {
  const date = new Date();
  const h = date.getHours() % 12;
  const m = date.getMinutes();
  const s = date.getSeconds();
  const h_deg = ((m / 60 + h) / 12) * 2 * Math.PI;
  const m_deg = ((s / 60 + m) / 60) * 2 * Math.PI;
  const s_deg = (s / 60) * 2 * Math.PI;

  ctx.save();
  ctx.translate(width / 2, height / 2);
  pointer(h_deg, 0.2, '#4e4e4e');   // 时针
  pointer(m_deg, 0.25, '#4e4e4e');  // 分针
  pointer(s_deg, 0.35, '#c32927');  // 秒针
  ctx.restore();
}

单根指针是由一条指向 12 点钟方向的直线,沿着表盘中心点顺时针旋转指定角度后构成。drawPointer 函数计算出三根指针各自与 12 点钟方向的夹角,再调用 pointer 函数一一绘制。

pointer 函数中,rotate() 方法将画布沿着变换后的中心点顺时针旋转指定角度,moveTo()lineTo() 方法再绘制一条从中心点指向原 12 点钟方向的路径,使用 stroke() 为路径添加描边,如此便完成了一根对应当前时间的指针。

按秒走时

setInterval(() => {
  ctx.clearRect(0, 0, width, height);
  drawCircle();
  drawPointer();
}, 1000);

每隔 1 秒钟擦除一次画布,然后重新绘制表盘与指针即可。

效果

上面代码合起来运行,就能得到一个如下图所示的简单时钟:

Smartisan 时钟

曾经有一部心爱的 锤子(Smartisan)坚果 R1 手机,后来……总之手机自带的 锤子时钟 我很喜欢,而时间来到 2023 年时,Android 版只剩魅族应用市场在架,版本停留在了 1.4.1,IOS 在 2016-03-25 更新了最后一个版本 1.4.2 后,在 2021-04-14 便一直下架了。

好在我的 iPhone 手机之前下载过,在已购项目中重新下载,打开应用截个图:

 在上面代码中,只是实现了一个最简单的 demo 版时钟,现在加一点点细节,复刻一下锤子时钟,效果如下:


代码放在了 codepen,有兴趣的话请移步。

本文转载于:

https://juejin.cn/post/7262280335979085861

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

标签:canvas,const,--,ctx,width,绘制,复刻,deg
From: https://www.cnblogs.com/smileZAZ/p/17601319.html

相关文章

  • SOLIDWORKS 钣金零件怎么画?
    一、SOLIDWORKS钣金功能介绍SOLIDWORKS 是一款广泛应用于机械设计领域的CAD软件,其钣金功能可以帮助用户快速创建钣金件的3D模型。钣金折弯是一种常见的加工方式,可以将平面材料通过弯曲变形成为所需形状。二、如何使用SOLIDWORKS钣金功能步骤1:创建基体法兰并设置钣金参数在......
  • 基础xshell学习笔记
    一,shell概述shell是一个命令行解释器,用来接受应用程序命令/用户命令,然后调用操作系统内核(linux内核),控制硬件shell的特点:功能强大的的编程语言,易编写,易调试,灵活性强,可读性强二,变量1>,系统级变量 $HOME $PWD $SHELLecho$SHELL解释器 $USERecho$USER当前用户......
  • 【python_1】第一个python程序!
    打开CMD(命令提示符)程序,输入python并回车;输入:print("HelloWorld!")然后回车;print代表的是打印输出的意思;这段代码的含义就是:在屏幕上输出引号内的内容。代码中使用的符号()""必须是英文符号。持续更新【python】系列!有需要的请移步秃头程序媛!......
  • 2023年湖南省对口高考真题
    一、选择题1、下列关于算法的描述中,错误的是__________。A.算法可以用伪代码、流程图等多种形式描述B.一个正确的算法必须有输入C.一个正确的算法必须有输出D.能用流程图描述的算法,也可用计算机高级语言描述2、如用"scanf("%c%c",&c1,&c2)",为字符变量c1和c2分别赋值字符'A'和'B',正......
  • 对称二叉树
    1boolcompare(Node*left,Node*right){2if(left==NULL&&right!=NULL)returnfalse;3elseif(left!=NULL&&right==NULL)returnfalse;4elseif(left==NULL&&right==NULL)returntrue;5//排除了空节点......
  • RS232转Profinet网关rs232和rs485的区别
    在工业自动化领域,如何将扫码枪与PLC连接一直是一个重要的问题。而今天,我们将通过一个案例来展示如何通过RS232转Profinet网关,将X-9300扫码枪接入到PLC1200工业以太网总线上。在这个过程中,我们将会用到捷米的RS232自由协议转Profinet网关。1, 首先,我们需要了解RS232和Profinet两......
  • Nginx详解
    Nginx:强大的Web服务器和反向代理服务器一、简介Nginx是一款开源的Web服务器和反向代理服务器,广泛应用于互联网应用和网络托管领域。其具有高可靠性、高性能和高扩展性,能够轻松处理大量并发请求,保证服务器资源的有效利用和网络流量的均衡分配。Nginx的主要特点包括高效的事件处理机......
  • 【vue】vue3+ts+element-plus制作的vueCms后台管理系统(开源)
    我的开源项目地址:vueCms_xg......
  • 使用expect实现shell自动交互
    安装expectsudoaptinstallexpect要执行的脚本#!/bin/bash#cpao.shssh-keygen-f"/home/lyq/.ssh/known_hosts"-R"192.168.1.10"scpsd.shao_app.elfbrdc*[email protected]:/[email protected]交互输入脚本#!/usr/bin/expect#ca.tcls......
  • 什么是软件检测证明材料,如何才能获得软件检测证明材料?
    一、什么是软件检测证明材料软件检测证明材料是指在软件开发和发布过程中,为了证明软件的质量和合法性,进行的一系列检测和测试的结果的集合。它是软件开发者和用户之间信任的桥梁,可以帮助用户了解软件的性能和安全性,让用户放心使用。二、软件检测证明材料包括以下几个方......