学习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是圆的半径,这样可以计算出x,y在圆边上的哪个位置,圆中心点是**(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)