[Canvas与艺术]Golden StopWatch 金色停表
【关键点】
之前做过两个时钟,本例和勾画时钟的差别主要在表盘渐变色的使用。
【效果图】
【代码】
<!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <head> <title>StopWatch秒表</title> <style type="text/css"> .centerlize{ margin:0 auto; width:1200px; } </style> </head> <body onload="init();"> <div class="centerlize"> <canvas id="myCanvas" width="512px" height="512px" style="border:1px dotted black;"> 如果看到这段文字说您的浏览器尚不支持HTML5 Canvas,请更换浏览器再试. </canvas> </div> <div> <button id="btn1" onclick="start();">启动/暂停</button> <button id="btn2" onclick="reset();">重置</button> </div> </body> </html> <script type="text/javascript"> <!-- /***************************************************************** * 将全体代码(从<!DOCTYPE到script>)拷贝下来,粘贴到文本编辑器中, * 另存为.html文件,再用chrome浏览器打开,就能看到实现效果。 ******************************************************************/ // canvas的绘图环境 var ctx; // 边长 const LENGTH=512; var paused=true; var stage; function start(){ paused=!paused; } function reset(){ paused=true; stage.init(); } //------------------------------- // 初始化 //------------------------------- function init(){ // 获得canvas对象 var canvas=document.getElementById('myCanvas'); // 初始化canvas的绘图环境 ctx=canvas.getContext('2d'); ctx.translate(LENGTH/2,LENGTH/2);// 原点平移到屏幕中央 // 准备 stage=new Stage(); stage.init(); } // 每一秒调用paintClock函数 setInterval(paintClock,1000); //------------------------------- // 绘制时钟 //------------------------------- function paintClock(){ if(!paused){ stage.update(); } stage.paintBg(ctx); stage.paintFg(ctx); } // 舞台类 function Stage(){ // 秒针数 this.second=0; // 秒针转了多少圈 this.secondCnt=0; // 初始化 this.init=function(){ this.second=0; this.secondCnt=0; } // 更新 this.update=function(){ this.second++; if(this.second>60){ this.second=1; this.secondCnt++; } if(this.secondCnt>60){ this.secondCnt=0; } } // 画背景,主要是画静态的刻度和文字 this.paintBg=function(ctx){ //ctx.clearRect(-LENGTH/2,-LENGTH/2,LENGTH,LENGTH);// 清屏 // 外圈 ctx.strokeStyle="#D9B300"; ctx.lineWidth=3; ctx.beginPath(); ctx.arc(0,0,250,0,2*Math.PI,true); ctx.closePath(); ctx.stroke(); // 中渐变圈 ctx.beginPath(); ctx.arc(0,0,247,0,2*Math.PI,true); ctx.closePath(); ctx.stroke(); ctx.clip(); var gnt=ctx.createLinearGradient(-LENGTH/2,-LENGTH/2,LENGTH,LENGTH); gnt.addColorStop(0,"#AE8F00"); gnt.addColorStop(0.4,"#FFDC35"); gnt.addColorStop(1,"#5B4B00"); ctx.fillStyle=gnt; ctx.fillRect(-LENGTH/2,-LENGTH/2,LENGTH,LENGTH); // 内圈 ctx.strokeStyle="#FFD306"; ctx.lineWidth=2; ctx.beginPath(); ctx.arc(0,0,230,0,2*Math.PI,true); ctx.closePath(); ctx.stroke(); // 底盘 //ctx.fillStyle="#FFF8D7"; var gnt2=ctx.createLinearGradient(-LENGTH/2,-LENGTH/2,LENGTH,LENGTH); gnt2.addColorStop(0,"#C6A300"); gnt2.addColorStop(0.35,"#FFF8D7"); gnt2.addColorStop(1,"#796400"); ctx.fillStyle=gnt2; ctx.beginPath(); ctx.arc(0,0,228,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); // 画外表盘-->> // 内圈 ctx.strokeStyle="black"; ctx.lineWidth=1; ctx.beginPath(); ctx.arc(0,0,224,0,2*Math.PI,true); ctx.closePath(); ctx.stroke(); var nums=["15","20","25","30","35","40","45","50","55","60","5","10"]; ctx.strokeStyle="#272727"; ctx.lineWidth=1; for(var i=0;i<12;i++){ var theta=i*Math.PI/6; var x1=224*Math.cos(theta); var y1=224*Math.sin(theta); var x2=212*Math.cos(theta); var y2=212*Math.sin(theta); // 画小时刻度 ctx.beginPath(); ctx.moveTo(x1,y1); ctx.lineTo(x2,y2); ctx.closePath(); ctx.stroke(); // 写数字 var x3=190*Math.cos(theta); var y3=190*Math.sin(theta); ctx.font="24px bold"; ctx.textAlign="center"; ctx.textBaseLine="Middle"; ctx.fillStyle="#272727"; ctx.fillText(nums[i],x3,y3+12);// 12是经验值 } // 画分针刻度 ctx.strokeStyle="black"; ctx.lineWidth=1; for(var i=0;i<60;i++){ var theta=i*Math.PI/30; var x1=224*Math.cos(theta); var y1=224*Math.sin(theta); var x2=218*Math.cos(theta); var y2=218*Math.sin(theta); ctx.beginPath(); ctx.moveTo(x1,y1); ctx.lineTo(x2,y2); ctx.closePath(); ctx.stroke(); } // <<--画外表盘结束 // 画内表盘-->> ctx.save(); ctx.translate(0,-80); // 内表盘外圈 ctx.strokeStyle="black"; ctx.lineWidth=1; ctx.beginPath(); ctx.arc(0,0,60,0,2*Math.PI,true); ctx.closePath(); ctx.stroke(); ctx.strokeStyle="#272727"; ctx.lineWidth=1; for(var i=0;i<12;i++){ var theta=i*Math.PI/6; var x1=60*Math.cos(theta); var y1=60*Math.sin(theta); var x2=56*Math.cos(theta); var y2=56*Math.sin(theta); // 画小时刻度 ctx.beginPath(); ctx.moveTo(x1,y1); ctx.lineTo(x2,y2); ctx.closePath(); ctx.stroke(); // 写罗马数字 var x3=50*Math.cos(theta); var y3=50*Math.sin(theta); ctx.font="8px bold"; ctx.textAlign="center"; ctx.textBaseLine="Middle"; ctx.fillStyle="#272727"; ctx.fillText(nums[i],x3,y3+4);// 4是经验值 } // 画分针刻度 ctx.strokeStyle="black"; ctx.lineWidth=1; for(var i=0;i<60;i++){ var theta=i*Math.PI/30; var x1=60*Math.cos(theta); var y1=60*Math.sin(theta); var x2=58*Math.cos(theta); var y2=58*Math.sin(theta); ctx.beginPath(); ctx.moveTo(x1,y1); ctx.lineTo(x2,y2); ctx.closePath(); ctx.stroke(); } ctx.restore(); // <<--画内表盘结束 } // 画前景,主要是画动态的两根针 this.paintFg=function(ctx){ // ----------以下为大针--------------------- var i=this.second; var angleS=-Math.PI/2+i*Math.PI/30; // ctx.save(); ctx.lineWidth=0.5; ctx.fillStyle = "black"; ctx.beginPath(); ctx.rotate(angleS); ctx.moveTo(200,0); ctx.lineTo(-30,-10); ctx.lineTo(-30,10); ctx.closePath(); ctx.fill(); ctx.restore(); ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(0,0,14,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); ctx.fillStyle = "#FFF8D7"; ctx.beginPath(); ctx.arc(0,0,12,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); ctx.fillStyle="black"; ctx.lineWidth=2; ctx.beginPath(); ctx.arc(0,0,9,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); ctx.save(); ctx.lineWidth=4; ctx.strokeStyle = "black"; ctx.beginPath(); ctx.rotate(angleS); ctx.moveTo(14,0); ctx.lineTo(-14,0); ctx.closePath(); ctx.stroke(); ctx.restore(); // //-------------以下为小针------------------ var j=this.secondCnt; var angleCnt=-Math.PI/2+j*Math.PI/30; ctx.save(); ctx.translate(0,-80); ctx.save(); ctx.lineWidth=0.5; ctx.fillStyle = "black"; ctx.beginPath(); ctx.rotate(angleCnt); ctx.moveTo(50,0); ctx.lineTo(-7.5,-2.5); ctx.lineTo(-7.5,2.5); ctx.closePath(); ctx.fill(); ctx.restore(); ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(0,0,3.5,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); ctx.fillStyle = "#FFF8D7"; ctx.beginPath(); ctx.arc(0,0,3,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); ctx.fillStyle="black"; ctx.lineWidth=2; ctx.beginPath(); ctx.arc(0,0,2.25,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); ctx.save(); ctx.lineWidth=1; ctx.strokeStyle = "black"; ctx.beginPath(); ctx.rotate(angleS); ctx.moveTo(3.5,0); ctx.lineTo(-3.5,0); ctx.closePath(); ctx.stroke(); ctx.restore(); ctx.restore(); } } //--> </script>
【特别声明】
以上是我臆想中的机械式秒表,因我未实际操作过,难免与实际不同,大家见谅。网上机械秒表要二百多,实在有点贵,等我股票大赚了再买一个玩玩,之后再修正吧......
END
分类:
Canvas与钟表
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)