【Canvas】js用canvas绘制一个钟表时钟动画效果

news2024/11/24 0:28:49

学习JavaScript的看过来,有没有兴趣用Canvas画图呢,可以画很多有趣的事物,自由发挥想象,收获多多哦,旋转角度绘图这个重点掌握到了吗,这里有一个例子,如何用canvas画钟表时钟动图效果,接下来开始讲,边学边做。

1. 设计页面

首先,做好一个页面,开始写布局,页面源代码如下,看起来很简单吧

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport"  content="width=device-width, initial-scale=1.0"/>
		<title>Ballet Clock</title>
		<style>
			.clock{
				display: inherit;
				width: 70vw;
				height: 70vw;
				margin: auto;
				position: relative;
				margin-top: 10vw;
			}
			
			.clock img{
				position: absolute;
				left: 0;
				top: 0;
				width: 100%;
				height: 100%;
			}
		</style>
	</head>
	<body>
		<div>
			<div class="clock">
				<img id="clock"/>
				<img id="hour"/>
				<img id="minute"/>
				<img id="second"/>
			</div>
		</div>
		<script>
			//引入模块
			import BalletClock from './ballet_clock.js';
			
			window.onload=()=>{
				//加载脚本...
			}
		</script>
	</body>
</html>

2. 加载脚本

接下来,页面的加载脚本像这样写的,代码如下,应该看得明白吧

const { clock,hour,minute,second } = ((args)=>{
let e={};
	args.forEach(a=>e[a]=document.getElementById(a));
	return e;
})('clock,hour,minute,second'.split(','));
//创建一个模块对象
let bc = new BalletClock();
bc.start({
	bgImg:clock,
	hourImg:hour,
	minuteImg:minute,
	secondImg:second
	//...传入模块参数
},window)

3. 实现模块

发现了吗,有个引用的模块ballet_clock.js文件是没有的,需要自己去写一个,这时候要复杂一点,代码并不多

1. 初始化

先实现初始化的逻辑方法init(),代码如下,是绘制一个钟表图,很简单吧

export default class BalletClock{
	constructor(){
		
	}
	#init(config,window){
		const { document } = window;
		const { bgImg, hourImg, minuteImg, secondImg } = config;
		//这里创建一个画布 设置好宽高与图片元素益智
		let canvas = document.createElement('canvas');
		canvas.width=bgImg.width;
		canvas.height=canvas.width;
		//获取画布上下文对象(封装的可操作方法集合)
		let ctx = canvas.getContext('2d');
		const { width, height } = ctx.canvas;
		//表盘中心点
		let center = {
			x: width/2,
			y: height/2,
			r: width/2
		};
		//画表盘
		ctx.fillStyle=config.bgColor;
		ctx.arc(center.x,center.y,center.r,0,Math.PI*2);
		ctx.fill();
		//画刻度
		ctx.strokeStyle=config.foreColor;
		ctx.fillStyle=config.foreColor;
		ctx.textAlign='center';
		ctx.textBaseline='middle';
		ctx.font=`${config.fontSize}px sans-serif`;
		let r = center.r-config.fontSize;
		//旋转中心角度,将分布在不同角度位置的小时数画出来
		for(let a=0,hour=0; a<360; a+=30){
			let angle = (a-90)/180*Math.PI;
			let x = Math.cos(angle)*r;
			let y = Math.sin(angle)*r;
			ctx.fillText(hour==0?'12':hour.toString(),x+center.x,y+center.y);
			hour++;
		}
		bgImg.src=canvas.toDataURL();
		//画时针 最后设置到图片元素钟
		ctx.lineCap='round';
		ctx.lineWidth=config.fontSize/2;
		ctx.clearRect(0,0,width,height);
		ctx.beginPath();
		ctx.moveTo(center.x,center.y);
		ctx.lineTo(center.x,center.y*0.5);
		ctx.stroke();
		ctx.lineWidth=1;
		ctx.beginPath();
		ctx.arc(center.x,center.y,config.fontSize,0,Math.PI*2);
		ctx.fill();
		hourImg.src=canvas.toDataURL();
		//画分针 最后设置到图片元素钟
		ctx.lineWidth=config.fontSize/4;
		ctx.clearRect(0,0,width,height);
		ctx.beginPath();
		ctx.moveTo(center.x,center.y);
		ctx.lineTo(center.x,center.y*0.2);
		ctx.stroke();
		minuteImg.src=canvas.toDataURL();
		//画秒针 最后设置到图片元素钟
		ctx.strokeStyle='#f85';
		ctx.lineWidth=config.fontSize/6;
		ctx.clearRect(0,0,width,height);
		ctx.beginPath();
		ctx.moveTo(center.x,center.y);
		ctx.lineTo(center.x,center.y*0.1);
		ctx.stroke();
		secondImg.src=canvas.toDataURL();
	}
	start(config,window){
		//这里实现开始动画逻辑...
	}
}

💡关于绘图中的角度如何定,看上面代码中用到了相关函数是Math.cos()Math.cos(),其用法类似于在初中数学的“勾股定理”,如还不清楚,就要复习一下数学了,要理解透彻哦,再讲讲如下代码:

let angle = (a-90)/180*Math.PI;
let x = Math.cos(angle)*r;
let y = Math.sin(angle)*r;
其中a才是角度,angle是弧度,r是圆的半径,这样可以计算出xy在圆边上的哪个位置,圆中心点是**(0,0)**哈~这样好理解的

2. 开始动画

接着实现动画的逻辑方法start(),代码如下,能看懂最好

export default class YinAndYangTaiChiDiagram{
		
	constructor(){
		
	}
	
	#init = (config,window) => {
		//初始化,绘制钟表...
	}
	
	//这里实现开始动画逻辑
	start(config,window){
		const { bgImg, hourImg, minuteImg, secondImg } = config;
		this.#init(Object.assign({
			fontSize:18,
			bgColor:'#000',
			foreColor:'#fff',
		},config),window);
		//更新显示的逻辑 因调用多次 故写在一个函数中
		const updateAnimation = ()=>{
			let date = new Date();
			//定义一个时分秒的数据
			let  d = {
				hour: date.getHours()%12,
				minute: date.getMinutes(),
				second: date.getSeconds()
			};
			//求秒针的角度
			let angle = d.second/60*360;
			secondImg.style.transform=`rotate(${angle}deg)`;
			//求分针的角度
			angle = d.minute/60*360;
			minuteImg.style.transform=`rotate(${angle}deg)`;
			//求时针的角度
			angle = d.hour/12*360+d.minute/60*30;
			hourImg.style.transform=`rotate(${angle}deg)`;
			//考虑处理性能 调用此处 可避免没必要的更新
			window.requestAnimationFrame(()=>{
				//延迟更新  每一秒就更新
				setTimeout(()=>updateAnimation(),1000)
			});
		};
		//开始更新
		updateAnimation();
	}
}

4. 运行效果

最后,打开浏览器运行该网页,没出问题的话,就能看到期待的钟表图,带动画效果,效果图如下
请添加图片描述

💡 此钟表好看吗,自己动手,试试修改网页上的配置参数如下,按自己的爱好定制自己喜欢颜色的钟表吧

bc.start({
	//...传入配置参数
	fontSize:18,
	bgColor:'#000',
	foreColor:'#fff',
},window)

在这里插入图片描述

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

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

相关文章

Mybatis:快速搭建Mybatis(2)

快速搭建Mybatis搭建Mybatis目录框架步骤一&#xff1a;创建Maven工程步骤二&#xff1a;创建mybatis的核心配置文件步骤三&#xff1a;创建mapper接口步骤四&#xff1a;创建Mybatis的映射文件步骤四&#xff1a;通过junit测试增删改查功能步骤五&#xff1a;加入logback日志功…

【JavaSE】String类型

目录 1. Java中为何要有 String 类&#xff1f; 2. String 类中的常用方法 2.1 String 类中的构造方法 2.2 String 类对象的比较 2.2.1 比较是否引用同一个对象 2.2.2 使用 equals 方法 2.2.3 compareTo 方法 2.3 字符串的查找 2.4 字符串与别的数据类型的转换 2.4.1 数值和字…

RationalDMIS 2022位置度评价,轮廓度评价时, 元素理论值变了,如何一劳永逸解决!

1,几何尺寸和公差符号 2.通用尺寸公差符号 3.位置度(Position) 位置度的被测要素有点、直线和平面,基准要素主要有直线和平面。给定位置度的被测要素相对于基准要素必须保持图样给定的正确位置关系,被测要素相对于基准要素的正确位置关系应由基准要素和理论正确尺寸来…

python mitmproxy +雷电模拟器 安装

第一步 安装mitmproxy 首先在安装好python 的情况下 pip install mitmproxy 第二步 电脑端安装证书 进入这个目录下 如果没有就重新mitmproxy 点击mitmproxy-ca.p12&#xff0c;在电脑端安装证书 点击下一页 点击下一页 不用管密码直接下一页 按照途中选择&…

基于Spring更简单的读取和存储对象

在spring的创建和使用这篇博客中有讲到关于Spring存储和读取Bean对象的操作,但是细心的朋友有没有发现那些操作没有想象中的简单呢?所以呀,我今天要给朋友分享的是更简单的存储和读取Bean对象的方法,快来看看吧~ 在Spring中想要更简单的存储和读取对象的核心就是使用注解,这就…

蓝牙学习四(广播)

1.简介 什么叫做广播&#xff0c;顾名思义就像广场上的大喇叭一样&#xff0c;不停的向外传输着信号。不同的是&#xff0c;大喇叭传输的是音频信号&#xff0c;而蓝牙传输的是射频信号。 BLE使用的是无线电波传递信息&#xff0c;就是将数据编码&#xff0c;调制到射频信号中发…

cmake使用

1. cmake概述及例子 CMake快速入门 cmake、qmake、cl之间关系 1.1 各种cmake cmake根据CMakeLists.txt生成makefile&#xff0c;make根据makefile行编译。 1.1.1 最简cmake&#xff1a;生成可执行程序&#xff08;一个文件&#xff09; #CMakeLists.txt cmake_minimum_req…

【正点原子FPGA连载】 第二十章 LCD触摸屏实验摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

1&#xff09;实验平台&#xff1a;正点原子MPSoC开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id692450874670 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第二十章 LCD触摸…

第十一章 建立语义化版本并提交组件库到NPM仓库

语义化版本是这样规定的。 版本格式&#xff1a;主版本号.次版本号.修订号&#xff08;MAJOR.MINOR.PATCH&#xff09;&#xff0c;版本号递增规则如下&#xff1a; 主版本号&#xff1a;当你做了不兼容的 API 修改&#xff1b;次版本号&#xff1a;当你做了向下兼容的功能性…

springboot+vue毕业生离校系统

目 录 摘 要 I 目 录 III 第1章 概述 1 1.1 研究背景 1 1.2 研究现状 1 1.3 研究内容 2 第二章 开发技术介绍 2 2.1 系统开发平台 2 2.2 平台开发相关技术 3 2.2.1 B/S架构 3 2.2.2 Java技术介绍 4 2.2.3 mysql数据库介绍 4 2.2.4 …

盘点程序员的花式赚外快的骚操作

2022世界杯比赛难得如期开幕了&#xff0c;卡塔尔王子的表情包想必大家已经看到眼晕。 我拿2200亿和你玩&#xff0c;你踢一个0&#xff1a;2过不过分啊~ 现实中的投资可不比卡塔尔王子的表情包失落更多&#xff0c;毕竟投资有风险入行需谨慎。 然而悲惨的事实是&#xff0c;…

[附源码]SSM计算机毕业设计新生入学计算机配号系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

企业若要实现预期广告推广效果,必须做好这六个步骤

在网络营销中&#xff0c;软文营销是一种最常用的营销手段。 我们知道&#xff0c;很多公司都是用软文进行广告推广。 然而&#xff0c;许多公司都觉得&#xff0c;软文营销并不是一件容易的事情&#xff0c;因为它不仅要有高品质的内容&#xff0c;还要有一定的操作能力&#…

CAD最常用的快捷键大全来啦

CAD快捷键的使用能够让我们加快画图的速度&#xff0c;但是想想CAD中有那么多的功能命令&#xff0c;所以CAD快捷键是很多的&#xff0c;想要完全记住是不可能的&#xff0c;这里就总结了常用的CAD快捷键命令&#xff0c;可能不全但是很实用。 一、常用绘图快捷键 最基本的一…

低代码与mes生产管理系统:功能篇

随着信息技术的发展和应用,信息系统在企业中的使用也越来越广泛。不仅可以使企业内部和企业间的信息流通更为便捷和频繁&#xff0c;同时可以提高管理的水平&#xff0c;有助于提高企业的生产效益。其中mes生产管理系统就是美豳的调查资询公司AMR(Advanced Manufacturing Resea…

牛顿法,高斯牛顿法,列文伯格-马夸尔特(LM)法

文章目录一&#xff1a;牛顿法 &#xff08;Newtons method&#xff09;1&#xff1a;概述2&#xff1a;牛顿方向与牛顿法3&#xff1a;牛顿法的基本步骤4&#xff1a;举例二&#xff1a;高斯牛顿法 &#xff08;Gauss–Newton algorithm&#xff09;1&#xff1a;概述2&#x…

若依、多选框前后端处理,MyBatis处理多对多关系

背景 很经典的CRUD&#xff0c;整理下笔记。 后端 实体类 /*** 专业方向主键&#xff0c;用于下拉框搜索*/private Long disasterTypeId;/*** 专业方向*/private List<DisasterType> disasterType;业务层 /*** 新增专家信息库** param expertInfo 专家信息库* return 结…

mac pro M1(ARM)安装:php开发环境

0. 引言 最近在处理各个语言的加密算法&#xff0c;正好需要安装php环境&#xff0c;特此记录&#xff0c;以供后续参考 1. 安装php 1、安装php包管理工具composer brew install composer2、安装php brew install php # 同时可以指定版本安装 brew install php8.0 # 查…

基于Java+SpringBoot+Mybatis+Vue+ElementUi的航空公司电子售票系统

项目介绍 本系统是利用Spring Boot框架而设计的一款结合用户的实际情况而设计的平台&#xff0c;前端利用VUE技术开发&#xff0c;将可供教师和管理员来使用的所有界面来显示出来&#xff0c;利用Java语言技术来编程实现用户和管理员所执行的各类操作业务逻辑&#xff0c;以My…

在MacOS上实现两个网络调试助手的UDP通信测试

文章目录一、背景二、网络调试助手软件三、UDP通信过程一、背景 因为有一个项目要中会使用本机中两个应用程序之间的UDP通信。 因此本文记录一下怎么在MacOS上实现两个网络调试助手的UDP通信测试。 二、网络调试助手软件 我使用的网络调试助手软件是&#xff1a;网络调试助…