【Canvas与表盘】绘制黄蓝两色简约表盘
【成图】



【代码】
<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head><title>黄蓝卡通手表</title><style type="text/css">.centerlize{margin:0 auto;width:1200px;}</style></head><body οnlοad="init();"><div class="centerlize"><canvas id="myCanvas" width="12px" height="12px" style="border:1px dotted black;">如果看到这段文字说您的浏览器尚不支持HTML5 Canvas,请更换浏览器再试.</canvas><img id="myImg" src="406.jpg" style="display:none;"/></div></body>
</html>
<script type="text/javascript">
<!--
/*****************************************************************
* 将全体代码(从<!DOCTYPE到script>)拷贝下来,粘贴到文本编辑器中,
* 另存为.html文件,再用chrome浏览器打开,就能看到实现效果。
******************************************************************/// canvas的绘图环境
var ctx;// 高宽
const WIDTH=512;
const HEIGHT=512;// 舞台对象
var stage;//-------------------------------
// 初始化
//-------------------------------
function init(){// 获得canvas对象var canvas=document.getElementById('myCanvas'); canvas.width=WIDTH;canvas.height=HEIGHT;// 初始化canvas的绘图环境ctx=canvas.getContext('2d'); ctx.translate(WIDTH/2,HEIGHT/2);// 原点平移// 准备stage=new Stage(); stage.init();// 开幕animate();
}// 播放动画
function animate(){ stage.update(); stage.paintBg(ctx);stage.paintFg(ctx); // 循环if(true){//sleep(100);window.requestAnimationFrame(animate); }
}// 舞台类
function Stage(){// 初始化this.init=function(){}// 更新this.update=function(){ }// 画背景this.paintBg=function(ctx){ctx.clearRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);// 清屏 }// 画前景this.paintFg=function(ctx){// 底色ctx.fillStyle = "white";ctx.fillRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);const R=100;// 基准尺寸// 黑色横向渐变外框var r=R*1.05;var gnt=ctx.createLinearGradient(-r,0,r,0);gnt.addColorStop(0,"black");gnt.addColorStop(0.35,"grey");gnt.addColorStop(0.5,"lightgrey");gnt.addColorStop(0.65,"grey");gnt.addColorStop(1,"black"); ctx.fillStyle=gnt;ctx.beginPath();ctx.arc(0,0,r,0,Math.PI*2,false);ctx.closePath();ctx.fill();// 黑色竖向渐变外框r=R;var gnt1=ctx.createLinearGradient(0,-r,0,r);gnt1.addColorStop(0,"black");gnt1.addColorStop(0.45,"grey");gnt1.addColorStop(0.5,"lightgrey");gnt1.addColorStop(0.55,"grey");gnt1.addColorStop(1,"black");ctx.fillStyle=gnt1;ctx.beginPath();ctx.arc(0,0,r,0,Math.PI*2,false);ctx.closePath();ctx.fill();// 表盘r=R-5;ctx.fillStyle="white";ctx.beginPath();ctx.arc(0,0,r,0,Math.PI*2,false);ctx.closePath();ctx.fill();// 刻度r=R-5;for(var i=0;i<60;i++){var theta=i*Math.PI/30;var rad1=r/20*19;var pt=createPt(rad1*Math.cos(theta),rad1*Math.sin(theta));var rad2=r/20*18;var pt2=createPt(rad2*Math.cos(theta),rad2*Math.sin(theta)); ctx.strokeStyle="grey";ctx.beginPath();ctx.moveTo(pt.x,pt.y);ctx.lineTo(pt2.x,pt2.y);ctx.stroke(); }// 小时背景var N=12;const PART=Math.PI/45;r=R;for(var i=0;i<N;i++){var theta=Math.PI*2/N*i;var r1=r*0.96;var a=createPt(r1*Math.cos(theta),r1*Math.sin(theta));var angle=theta+PART;var b=createPt(r1*Math.cos(angle),r1*Math.sin(angle));angle=theta-PART;var c=createPt(r1*Math.cos(angle),r1*Math.sin(angle));var r2=r*0.75;var o=createPt(r2*Math.cos(theta),r2*Math.sin(theta));angle=theta+PART;var e=createPt(r2*Math.cos(angle),r2*Math.sin(angle));angle=theta-PART;var d=createPt(r2*Math.cos(angle),r2*Math.sin(angle));ctx.lineWidth=1;ctx.strokeStyle="black";ctx.fillStyle=((i%2==0)?"rgb(255,185,24)":"rgb(71,132,195)");ctx.beginPath();ctx.moveTo(b.x,b.y);ctx.lineTo(e.x,e.y);var radius=r2*Math.sin(PART);ctx.arc(o.x,o.y,radius,theta+Math.PI/2,theta+Math.PI/2*3,false);ctx.lineTo(d.x,d.y);ctx.lineTo(c.x,c.y);ctx.arc(0,0,r1,theta-PART,theta+PART,false);ctx.lineTo(b.x,b.y);ctx.closePath();ctx.fill();}// 小时数字// 数字r=R*0.75;var hours=["Ⅲ","Ⅳ","Ⅴ","Ⅵ","Ⅶ","Ⅷ","Ⅸ","Ⅹ","Ⅺ","Ⅻ","Ⅰ","Ⅱ"]; for(var i=0;i<12;i++){var theta=i*Math.PI/6;var pt=createPt(r*Math.cos(theta),r*Math.sin(theta));ctx.save();ctx.translate(pt.x,pt.y);ctx.rotate(theta+Math.PI/2);ctx.font=R/12.5+"px Microsoft YaHei UI";ctx.textAlign="center";ctx.textBaseLine="Middle";ctx.fillStyle="white";ctx.fillText(hours[i],0,0);ctx.restore();}// 得到当前时间var now=new Date();var s=now.getSeconds();var m=now.getMinutes();var h=now.getHours()+m/60;// 画三根针 drawMinutePointer(ctx,m,R*0.40);drawSecondPointer(ctx,s,R*0.60);drawHourPointer(ctx,h,R*0.05);writeText(ctx,WIDTH/2-30,HEIGHT/2-5,"逆火制图","8px consolas","lightgrey");// 版权}
}// 画秒针
function drawSecondPointer(ctx,s,radius){const R=radius;const W=R/40;ctx.save();ctx.rotate(s*Math.PI/30-Math.PI/2);// 长杆ctx.fillStyle="rgb(71,132,195)";ctx.beginPath();ctx.lineTo(0,W);ctx.lineTo(R,W);ctx.arc(R,0,W,Math.PI/2,-Math.PI/2,true);ctx.lineTo(R,-W);ctx.lineTo(-R/3,-W);ctx.lineTo(-R/3,W);ctx.closePath(); ctx.fill();// 圆球配重ctx.beginPath();ctx.arc(-R/3,0,3*W,0,Math.PI*2,false);ctx.closePath();ctx.fill();ctx.restore();
}// 画分针
function drawMinutePointer(ctx,m,radius){const R=radius;const W=R/10;ctx.save();ctx.rotate(m*Math.PI/30-Math.PI/2);// 短杆ctx.fillStyle="rgb(255,185,24)";ctx.beginPath();ctx.lineTo(0,W);ctx.lineTo(R,W);ctx.arc(R,0,W,Math.PI/2,-Math.PI/2,true);ctx.lineTo(R,-W);ctx.lineTo(0,-W);ctx.closePath(); ctx.fill();ctx.restore();
}// 画时针
function drawHourPointer(ctx,h,radius){const R=radius;ctx.save();ctx.rotate(h*Math.PI/6-Math.PI/2);ctx.fillStyle="black";ctx.beginPath();ctx.arc(0,0,1.2*R,0,Math.PI*2,false);ctx.closePath(); ctx.fill();ctx.fillStyle="rgb(71,132,195)";ctx.beginPath();ctx.arc(R-2,0,0.2*R,0,Math.PI*2,false);ctx.closePath(); ctx.fill();ctx.restore();
}/*----------------------------------------------------------
函数:用于绘制实心圆,用途是标记点以辅助作图
ctx:绘图上下文
x:矩形中心横坐标
y:矩形中心纵坐标
r:圆半径
color:填充圆的颜色
----------------------------------------------------------*/
function drawSolidCircle(ctx,x,y,r,color){ctx.fillStyle=color;ctx.beginPath();ctx.arc(x,y,r,0,Math.PI*2,false);ctx.closePath();ctx.fill();
}/*----------------------------------------------------------
函数:创建一个二维坐标点
x:横坐标
y:纵坐标
Pt即Point
----------------------------------------------------------*/
function createPt(x,y){var retval={};retval.x=x;retval.y=y;return retval;
}/*----------------------------------------------------------
函数:延时若干毫秒
milliseconds:毫秒数
----------------------------------------------------------*/
function sleep(milliSeconds) {const date = Date.now();let currDate = null;while (currDate - date < milliSeconds) {currDate = Date.now();}
}/*----------------------------------------------------------
函数:书写文字
ctx:绘图上下文
x:横坐标
y:纵坐标
text:文字
font:字体
color:颜色
----------------------------------------------------------*/
function writeText(ctx,x,y,text,font,color){ctx.save();ctx.textBaseline="bottom";ctx.textAlign="center";ctx.font = font;ctx.fillStyle=color;ctx.fillText(text,x,y);ctx.restore();
}/*-------------------------------------------------------------
You must be the change you wish to see in the end!
--------------------------------------------------------------*/
//-->
</script>
END
相关文章:
【Canvas与表盘】绘制黄蓝两色简约表盘
【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>黄蓝卡通手表</title><style type"text/css">…...
大数据-128 - Flink 并行度设置 细节详解 全局、作业、算子、Slot
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…...
图新地球-将地图上大量的地标点批量输出坐标到csv文件【kml转excel】
0.序 有很多用户需要在卫星影像、或者无人机航测影像、倾斜模型上去标记一些地物的位置(如电线杆塔、重点单位、下水盖等) 标记的位置最终又需要提交坐标文本文件给上级单位或者其他部门使用,甚至需要转为平面直角坐标。 本文的重点是通过of…...
Git提交有乱码
服务器提交记录如图 可知application.properties中文注释拉黄线 ,提示Unsupported characters for the charset ISO-8859-1 打开settings - Editor - File Encodings 因为我们项目的其他文件都是UTF-8,所以,我们将默认值都改成UTF-8 然后…...
leetcode hot100_part4_子串
2024/4/20—4/21 560.和为K的子数组 前缀和哈希表,做二叉树的时候也有这个套路。注意细节,遍历到当前前缀和的时候是先找结果个数还是先加入哈希?应该先找结果个数,不然的话,当前位置也算上了(因为是前缀和…...
Spring Cloud之三 网关 Gateway
1:Intellij 新建项目 spring-cloud-gateway 2:pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLoca…...
Linux 进程1
进程 在linux系统中,触发任何一个事件时系统会将其定义为一个进程(一个程序开始执行),系统会给这个进程分配一个进程ID统称为PID。 程序:通常是二进制文件,放置于存储媒介如硬盘中。 进程:当存…...
LeetCode: 2552. 统计上升四元组 动态规划 时间复杂度O(n*n)
2552. 统计上升四元组 today 2552. 统计上升四元组 题目描述 给你一个长度为n下标从 0 开始的整数数组 nums ,它包含1到n的所有数字,请你返回上升四元组的数目。 如果一个四元组 (i, j, k, l) 满足以下条件,我们称它是上升的:…...
Unity 编辑器设置中文
在 Unity 编辑器中,你可以按照以下步骤将语言设置为中文: 步骤: 1. 打开 Unity 编辑器。 2. 在顶部菜单栏,依次点击 Edit > Preferences(在 macOS 上是 Unity > Preferences)。 3. 在弹出的 Preferen…...
springboot-创建连接池
操作数据库 代码开发步骤: pom.xml文件配置依赖properties文件配置连接数据库信息(连接池用的是HikariDataSource)数据库连接池开发 configurationproperties和value注解从properties文件中取值bean方法开发 service层代码操作数据库 步骤&am…...
matlab绘制不同区域不同色彩的图,并显示数据(代码)
绘图结果如下: 代码如下: A为绘图的数据,每个数据对应着上图中的一个区域,数据大小决定区域的颜色 % 假设有一系列的数据点 Arand(5,6); %A为绘图的数据,数据大小决定颜色 wei_shu%.3f; %代表数据保留三位小…...
Docker Desktop 的安装与汉化指南
前言 Docker Desktop 是一款非常流行的开发工具,它使得开发者能够在自己的计算机上轻松地构建、运行和调试 Docker 容器。然而,默认情况下,Docker Desktop 的界面是英文的,对于中文用户来说,有时候会觉得不够友好。幸…...
前端form表单+ifarme方式实现大文件下载
// main.jsimport Vue from vue; import App from ./App.vue; import { downloadTokenFile } from /path/to/your/function; // 替换为您的函数路径// 将 downloadTokenFile 添加到 Vue 原型上 Vue.prototype.$downloadTokenFile downloadTokenFile;new Vue({el: #app,render:…...
Leetcode面试经典150题-141.环形链表
题目比较简单,重点是理解思想 解法都在代码里,不懂就留言或者私信 /*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ public…...
sh文件执行提示语法错误: 未预期的文件结尾
在执行sh文件时总是提示:语法错误: 未预期的文件结尾,尝试删除最后的空格也不对 最后发现在notepad中转换的问题 需要把windows换成unix就行了...
基于SpringBoot的甜品店管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的蛋糕甜品店管理系…...
动态规划-不同的子序列
题目描述 给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 7 取模。 示例: 输入:s "babgbag", t "bag" 输出:5 解释: 如下所示, 有 5 种可以从…...
如何通过OceanBase的多级弹性扩缩容能力应对业务洪峰
每周四晚上的10点,都有近百万的年轻用户进入泡泡玛特的抽盒机小程序,共同参与到抢抽盲盒新品的活动中。瞬间的并发流量激增对抽盒机小程序的系统构成了巨大的挑战,同时也对其数据库的扩容能力也提出了更高的要求。 但泡泡玛特的工程师们一点…...
D - 1D Country(AtCoder Beginner Contest 371)
题目链接: D - 1D Country (atcoder.jp) 题目描述: 数据范围: 输入输出: 题目分析: 典型的l, r 区间问题,即是前缀和问题,但是注意到数据范围, 数据范围1e-9 到 1e9 数据范围,要是从最小到最大直接for循环去模拟的话,时间复杂度…...
怎么很多张图片拼接成一张?试试这几种图片拼接方法!
怎么很多张图片拼接成一张?在繁忙的现代生活中,我们不断地捕捉和累积着各式各样的图像,它们如同记忆的珍珠,串联起生活的每一个瞬间,然而,随图片数量的激增,管理它们成为了一项挑战,…...
从SolidWorks到Geant4仿真:我的第一个粒子探测器CAD模型导入全记录(含CADMesh避坑点)
从SolidWorks到Geant4仿真:我的第一个粒子探测器CAD模型导入全记录(含CADMesh避坑点) 作为一名刚接触粒子探测器仿真的研究生,我花了整整两周时间才成功将SolidWorks设计的模型导入Geant4进行模拟。这个过程远比想象中复杂&#x…...
IDEA 2018.2.3 下 Maven 依赖包消失?别慌,可能是版本兼容性在作祟
IDEA 2018.2.3 下 Maven 依赖包消失的深度排查指南 当你打开一个尘封已久的老项目,准备继续维护或迁移时,突然发现IDEA的External Libraries里空空如也,只剩下孤零零的JDK包,整个项目文件一片飘红——这种场景对许多维护历史代码库…...
ARMv8-AArch64 异常处理实战:从寄存器解析到调试技巧
1. ARMv8-AArch64异常处理入门指南 第一次接触ARMv8架构的异常处理时,我被那一堆寄存器搞得头晕眼花。ELR、ESR、FAR...这些缩写看起来就像天书一样。但经过几个实际项目的磨练后,我发现只要掌握几个关键点,异常处理其实并没有想象中那么难。…...
3个按键冲突场景,Hitboxer如何帮你重获游戏控制权?
3个按键冲突场景,Hitboxer如何帮你重获游戏控制权? 【免费下载链接】socd Key remapper for epic gamers 项目地址: https://gitcode.com/gh_mirrors/so/socd 你是否曾在激烈的游戏对战中,因为同时按下W和S键而突然卡住?或…...
3个维度深度解析:UABEA如何重塑Unity资源处理生态
3个维度深度解析:UABEA如何重塑Unity资源处理生态 【免费下载链接】UABEA c# uabe for newer versions of unity 项目地址: https://gitcode.com/gh_mirrors/ua/UABEA 在Unity游戏开发和资源处理的复杂生态中,开发者常常面临一个核心挑战…...
Arm Iris调试接口:架构设计与工程实践详解
1. Iris调试与追踪接口深度解析调试与追踪技术是嵌入式系统开发的核心支柱,而Arm的Iris接口代表了这一领域的最新进展。作为一名长期从事嵌入式调试工具开发的工程师,我将带您深入剖析这套接口的设计哲学与实战应用。1.1 接口架构设计理念Iris的架构设计…...
Arduino与手机蓝牙通信:nRF8001 BLE模块硬件连接与软件配置全解析
1. 项目概述与核心价值如果你手头有一个Arduino项目,想让它和你的手机“说说话”,比如把传感器数据无线传到手机App上显示,或者用手机App远程控制几个LED灯,那么nRF8001这个蓝牙低功耗(BLE)模块绝对是你绕不…...
从二维到三维:DIY LED视频立方体构建全攻略
1. 项目概述:从平面到立体的视觉革命几年前,当我第一次成功点亮一整面由32x32 RGB LED面板组成的视频墙时,那种由1024个像素点共同编织出的动态画面所带来的震撼,至今记忆犹新。但作为一个热衷于将技术推向边界的创作者࿰…...
Linux权限继承与umask配置实践
Linux权限继承与umask配置实践很多协作目录问题并不是因为当前权限错了,而是因为新建文件的默认权限总是不符合预期。背后的核心变量之一就是 umask。中级阶段如果不理解默认权限是怎么生成的,就会陷入“每次都手工 chmod”的低效循环。一、默认权限不是…...
μSR技术中的双量子Rabi振荡优化与应用
1. 实验背景与核心原理 在量子物理和凝聚态物理研究中,μ子自旋共振(μSR)技术是一种独特的探测手段。这项技术利用正μ子(μ)作为微观探针,通过观测其自旋极化行为来研究材料的局部磁环境。当μ子注入样品…...
