Canvas绘制老友记时钟

2024-06-15 22:04
文章标签 老友记 canvas 时钟 绘制

本文主要是介绍Canvas绘制老友记时钟,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Canvas绘制老友记时钟

前言

一直做3D/2D可视化,Canvas API和三角函数,空间几何是基础。在官网上看了一遍Canvas API之后,决定绘制一个老友记时钟来巩固知识点,本文用实际代码讲解绘制过程。

在这里插入图片描述

代码

HTML

<canvas id="myCanvas" width="300" height="300"></canvas>

Javascript

const canvas = document.getElementById("myCanvas");
const bgImage = new Image();
const ctx = canvas.getContext("2d");bgImage.src = "https://thumbnail1.baidupcs.com/thumbnail/cc3e81310m71ea6cdb2c5755bda0dc0c?fid=1099650259173-250528-406088947420032&rt=pr&sign=FDTAER-DCb740ccc5511e5e8fedcff06b081203-VVyEw%2bgld39Yr5Tjp%2f1KbwKqa4M%3d&expires=8h&chkbd=0&chkv=0&dp-logid=409019635711974061&dp-callid=0&time=1718445600&size=c1512_u982&quality=90&vuk=1099650259173&ft=image&autopolicy=1";// 时钟半径
const r = 100bgImage.onload = function () {render();setInterval(function(){render();}, 1000);// 每一帧都先用canvas.clearRect(x,y,w,h)擦掉画布上的像素,否则会造成当前像素和之前的像素叠加的问题。将画布的原点移到画布的中心,有助于绘制刻度和以中心为基点旋转的指针,在之前得保存平移之前的环境状态。function render() {drawClockBackGround();drawHourTicks();drawTime();ctx.restore();}// 时针、分针、秒针的做法是一致的,使用canvas.rotate()绕原点旋转,旋转之前都要canvas.save()保存当前状态(指针的每一帧动作都是让画布旋转特定的角度,所以画完一次要摆正一次画布,否则秒针旋转一次,分针会在此基础上旋转)function drawTime(){var now = new Date();h = now.getHours();m = now.getMinutes();s = now.getSeconds();ctx.strokeStyle = 'black';drawHour(h,m);drawMinute(m,s);drawSecond(s);}function drawHour(h, m) {const hour = h + m/60;ctx.save();ctx.beginPath();ctx.rotate(hour * 2 * Math.PI / 12); // 时针旋转一周是12小时ctx.lineWidth = 4;ctx.moveTo(0, 0.2 * 0.4 * r);ctx.lineTo(0, -0.8 * 0.4 * r);ctx.stroke();ctx.closePath();ctx.restore();}function drawMinute(m, s) {const minute = m + s/60;ctx.save();ctx.beginPath();ctx.rotate(minute * 2 * Math.PI / 60); // 分针旋转一周是60分钟ctx.lineWidth = 2;ctx.moveTo(0, 0.2 * 0.6 * r);ctx.lineTo(0, -0.8 * 0.6 * r);ctx.stroke();ctx.closePath();ctx.restore();}function drawSecond(s) {ctx.save();ctx.beginPath();ctx.rotate(s * 2 * Math.PI / 60); // 秒针旋转一周是60秒ctx.lineWidth = 2;ctx.moveTo(0, 0.2 * 0.8 * r);ctx.lineTo(0, -0.8 * 0.8 * r);ctx.stroke();ctx.closePath();ctx.restore();}function drawHourTicks() {const hourTickLength = 5; // 刻度的长度const hourTickColor = "yellow";const gap = 10; // 刻度起始位置距离表盘边缘的间隔for (let i = 0; i * Math.PI / 6 < 2 * Math.PI; i ++) {const angle = i * Math.PI / 6;ctx.beginPath();ctx.moveTo((r - gap) * Math.cos(angle), (r - gap) * Math.sin(angle));ctx.lineTo((r - gap + hourTickLength) * Math.cos(angle), (r - gap + hourTickLength) * Math.sin(angle));ctx.strokeStyle = hourTickColor;ctx.stroke();ctx.closePath();}}function drawClockBackGround() {// 清除canvas  ctx.clearRect(0, 0, canvas.width, canvas.height);  ctx.save();// 将坐标系原点平移到画布中心位置ctx.translate(canvas.width / 2, canvas.height / 2);// 绘制圆形遮罩(实际上绘制一个圆形,并用白色填充)  ctx.beginPath();ctx.arc(0, 0, r, 0, Math.PI * 2);ctx.closePath();// 表盘背景图片drawBGImage();// 指针交汇处的圆形ctx.beginPath();ctx.fillStyle = 'black';ctx.arc(0, 0, 5, 0, Math.PI * 2, false);ctx.fill();ctx.closePath();// 描边表盘轮廓ctx.beginPath();ctx.lineWidth = 2;ctx.arc(0, 0, r, 0, Math.PI * 2);ctx.strokeStyle = 'black';  ctx.stroke();ctx.closePath();}function drawBGImage() {ctx.fillStyle = 'white'; // 遮罩颜色,通常与背景色相同  ctx.fill();  // 设置globalCompositeOperation为'source-in',这样接下来的绘制只会在遮罩区域内显示  ctx.globalCompositeOperation = 'source-in';  // 绘制背景图片,它现在只会在圆形区域内显示const scale = 1;  const scaledWidth = bgImage.width * scale;  const scaledHeight = bgImage.height * scale;  ctx.drawImage(bgImage, 0, 0, scaledWidth, scaledHeight, - canvas.width / 2, - canvas.height / 2, canvas.width, canvas.height);// 重置globalCompositeOperation以便后续绘制不受影响  ctx.globalCompositeOperation = 'source-over';}  
};

效果

在这里插入图片描述

链接

在线演练请参考: CodePen

这篇关于Canvas绘制老友记时钟的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1064698

相关文章

以canvas方式绘制粒子背景效果,感觉还可以

这个是看到项目中别人写好的,感觉这种写法效果还可以,就存留记录下 就是这种的背景效果。如果想改背景颜色可以通过canvas.js文件中的fillStyle值改。 附上demo下载地址。 https://download.csdn.net/download/u012138137/11249872

[FPGA][基础模块]跨时钟域传播脉冲信号

clk_a 周期为10ns clk_b 周期为34ns 代码: module pulse(input clk_a,input clk_b,input signal_a,output reg signal_b);reg [4:0] signal_a_widen_maker = 0;reg signal_a_widen;always @(posedge clk_a)if(signal_a)

XMG 绘制形状

1. 除非是绘制曲线直接使用原生的。如果绘制形状直接使用UIBezerPath  2. 命名原则,类方法以类名开头 UIBezierPath bezierPathWithRect 3.圆角半径 画圆的大小 以每个顶点为圆心。给定的半径为半径画一个1/4圆。把周边的给切掉 4.只有封闭的形状调用这个方法才有用 [path fill] 5. stroke 描边一下

Android 10.0 系统开机重启桌面时钟小部件widget加载慢解决方案

1.前言 在10.0的系统rom产品定制化开发中,在Launcher3桌面系统默认会有时钟widget小部件显示在首屏的,但是发现在开机过程 中会显示的好慢,等进入桌面了 还没显示,所以接下来分析下相关的源码流程,来实现相应的功能 2.系统开机重启桌面时钟小部件widget加载慢解决方案的核心类 frameworks\base\services\appwidget\java\com\andr

CesiumJS【Basic】- #008 通过canvas绘制billboard

文章目录 通过canvas绘制billboard1 目标2 实现 通过canvas绘制billboard 1 目标 通过canvas绘制billboard 2 实现 /** @Author: alan.lau* @Date: 2024-06-16 11:15:48* @LastEditTime: 2024-06-16 11:43:02* @LastEditors: al

Android自定义系列——4.Canvas操作

1.画布操作 为什么要有画布操作? 画布操作可以帮助我们用更加容易理解的方式制作图形。 ⑴位移(translate) translate是坐标系的移动,可以为图形绘制选择一个合适的坐标系。 请注意,位移是基于当前位置移动,而不是每次基于屏幕左上角的(0,0)点移动,如下: // 省略了创建画笔的代码// 在坐标原点绘制一个黑色圆形mPaint.setColor(Color.BLACK);ca

使用AGG里面的clip_box函数裁剪画布, 绘制裁剪后的图形

// 矩形裁剪图片, 透明void agg_testImageClipbox_rgba32(unsigned char* buffer, unsigned int width, unsigned int height){// ========= 创建渲染缓冲区 =========agg::rendering_buffer rbuf;// BMP是上下倒置的,为了和GDI习惯相同,最后一个参数是

多线程简单运用---时钟的实现

效果图:   代码: package game;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Container;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListe

Canvas绘制图片和区域

如何使用Canvas在图片上绘制区域? 一. 首先,我们需要初始化三个canvas画布(初始化Canvas)   initCanvas() {// 初始化canvas画布let canvasWrap = document.getElementsByClassName("canvas-wrap");this.wrapWidth = canvasWrap[0].clientWidth;thi

「JCVI教程」如何绘制CNS级别的共线性图(中)

在「JCVI教程」编码序列或蛋白序列运行共线性分析流程(上)还是有一个尴尬的事情,就是只用到两个物种,不能展示出JCVI画图的方便之处,因此这里参考https://github.com/tanghaibao/jcvi/wiki/MCscan-(Python-version)的分析,只不过画图部分拓展下思路。 首先要运行如下代码获取目的数据 python -m jcvi.apps.fetch p