文章目录
- 最近在学习HarmonyOS 相关的东西,看了很多网上的canvas 实现时钟,现在我也来写一个关于HarmonyOS 的时钟吧。
- 工具版本:DevEco Studio 3.0 Beta3 SDK版本;3.1.5.5 主要用到知识:canvas js
-
- <div class="container"> <canvas ref="clock" style="width: 600px; height:600px; background-color:#5a5a5a "></canvas></div
- export default { data: { c:'', ctx:'' } }
- onShow(){ this.el = this.$refs.clock; //获取canvas绘图上下文 this.ctx = this.el.getContext('2d'); this.initData()},
- initData:function(){ this.updateClock(this.ctx) },
-
- drawPanel:function(ctx){ ctx.beginPath() //开始 ctx.arc(300, 300, 200, 0, Math.PI * 2) //绘制弧线路径 ctx.fillStyle = 'white' //填充颜色 ctx.fill() //填充 ctx.closePath() //闭合 }, 此时的页面长这样:
- hourCalibration:function(ctx){ var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; //定义刻度的数字 ctx.beginPath(); //开始 ctx.translate(300, 300) //移动当前坐标系的原点 ctx.font = '30px bold' //文字的大小 ctx.textAlign = "center"; // 文字居中 ctx.textBaseline = "middle"; // 设置文本绘制中的水平对齐方式 为文本块的中间 ctx.fillStyle = "black"; // 填充颜色 for (var i = 0; i < arr.length; i++) {//绘制填充类文本 ctx.fillText( arr[i], 168 * Math.cos(((i * 30 - 60) * Math.PI) / 180), 168 * Math.sin(((i * 30 - 60) * Math.PI) / 180) ); } ctx.closePath(); // 结束 }, 此时页面:
- centerDot:function(ctx){ ctx.beginPath(); // 开始 ctx.arc(0, 0, 8, 0, 2 * Math.PI); //绘制弧线路径 ctx.fill(); //对封闭路径进行填充 ctx.beginPath(); //开始 ctx.fillStyle = "white"; ctx.arc(0, 0, 5, 0, 2 * Math.PI); //绘制弧线路径 ctx.fill();//对封闭路径进行填充 }, 此时的页面长这样:
- 此时需要获取当前系统的本地时间,在此处遇到了一个小麻烦,鸿蒙开发者工具new Date() 获取到的时间为格林威治时间,而我们现在采用的是北京时间,需要写函数来转化时间,转化函数为getTimeStamp()。 getTimeStamp:function(){ var zoneOffset = 8; //算出时差,并转换为毫秒: var offset2 = new Date().getTimezoneOffset()* 60 * 1000; //算出现在的时间: var nowDate2 = new Date().getTime(); //此时东八区的时间 var currentZoneDate = new Date(nowDate2 + offset2 + zoneOffset*60*60*1000); return currentZoneDate;} 获取当前北京时间: //修改时间 默认获取的是格林威治时间 需要将时间转化为北京时间才行var date = this.getTimeStamp(new Date())//获取当前的小时var hours = date.getHours()console.log(hours+'hours')//获取当前分钟var minutes = date.getMinutes()console.log(minutes+'minutes')//获取当前秒数var seconds = date.getSeconds()console.log(seconds+'seconds')
- hourHand:function(ctx,hours, minutes){ var radius = ((2 * Math.PI) / 12) * hours + (((1 / 6) * Math.PI) / 60) * minutes; ctx.save();// 保存当前状态,为了旋转后能回到当初状态。 ctx.beginPath(); //开始 ctx.lineWidth = 8; // 针的宽度 ctx.lineCap = "round"; // 针头为圆角 ctx.strokeStyle = "green"; //针的颜色 ctx.rotate(radius); // 旋转 ctx.moveTo(0, 0); ctx.lineTo(0, -90); ctx.stroke(); ctx.closePath() // 结束 // 回到保存的状态 ctx.restore(); }, 此时的页面长这样:
- minuteHand:function(ctx,minutes){ 2 * Math.PI; var radius = ((2 * Math.PI) / 60) * minutes; ctx.save(); // 保存当前状态,为了旋转后能回到当初状态。 ctx.beginPath(); //开始 ctx.lineWidth = 4; // 针的宽度 ctx.lineCap = "round"; //针头为圆角 ctx.strokeStyle = "black"; ctx.rotate(radius); //旋转 ctx.moveTo(0, 0); ctx.lineTo(0, -110); ctx.stroke(); //绘制轮廓圆 ctx.closePath() //结束 ctx.restore(); }, 此时页面长这样:
- secondHand:function(ctx,seconds) { var radius = ((2 * Math.PI) / 60) * seconds; ctx.save(); // 保存当前状态,为了旋转后能回到当初状态。 ctx.beginPath(); //开始 ctx.lineWidth = 2; // 针的宽度 ctx.lineCap = "round"; //针头为圆角 ctx.strokeStyle = "red"; ctx.rotate(radius); //旋转 ctx.moveTo(0, 0); ctx.lineTo(0, -140); ctx.stroke();//绘制轮廓圆 ctx.closePath() //结束 ctx.restore(); }, 此时页面长这样:
- updateClock:function(ctx){ var time = this.getTimeStamp(new Date()) var hours = time.getHours(); var minutes = time.getMinutes(); var seconds = time.getSeconds(); ctx.save(); this.drawPanel(this.ctx); this.hourCalibration(this.ctx); this.secondHand(this.ctx,seconds); this.minuteHand(this.ctx,minutes); this.hourHand(this.ctx,hours, minutes); this.centerDot(this.ctx) ctx.closePath(); ctx.restore();}
- 那么就需要在initData 函数中写一个定时器没一秒钟执行一次绘制函数即可: 最后的图片如上图第一张图所示的效果。 initData:function(){ // 定时器一分钟刷新一次时间 let timer = setInterval(()=>{ this.ctx.clearRect(0, 0, 600, 600); //删除指定区域内的绘制内容。 this.updateClock(this.ctx) },1000) },
- 以上就是canvas 绘制一个时钟的全部步骤了。 最重要的一点是要能正确的获取到时间(北京时间)但是我发现在编辑器上new Date() 到的时间跟咋们的北京时间相差了八小时,在一位同事的提醒下才知道这个获取的时间为格林威治时间,那么我们需要将这个格林威治时间转化成北京时间,在网上找了一段转化方法终于转化成功。 想了解更多关于开源的内容,请访问: 51CTO 开源基础软件社区 https://ost.51cto.com。

最近在学习HarmonyOS 相关的东西,看了很多网上的canvas 实现时钟,现在我也来写一个关于HarmonyOS 的时钟吧。
- 工具版本:DevEco Studio 3.0 Beta3
- SDK版本;3.1.5.5
- 主要用到知识:canvas js

<div class="container">
<canvas ref="clock" style="width: 600px; height:600px; background-color:#5a5a5a "></canvas>
</div
<canvas ref="clock" style="width: 600px; height:600px; background-color:#5a5a5a "></canvas>
</div
export default {
data: {
c:'',
ctx:''
}
}
data: {
c:'',
ctx:''
}
}
onShow(){
this.el = this.$refs.clock;
//获取canvas绘图上下文
this.ctx = this.el.getContext('2d');
this.initData()
},
this.el = this.$refs.clock;
//获取canvas绘图上下文
this.ctx = this.el.getContext('2d');
this.initData()
},
initData:function(){
this.updateClock(this.ctx)
},
this.updateClock(this.ctx)
},
drawPanel:function(ctx){
ctx.beginPath() //开始
ctx.arc(300, 300, 200, 0, Math.PI * 2) //绘制弧线路径
ctx.fillStyle = 'white' //填充颜色
ctx.fill() //填充
ctx.closePath() //闭合
},
ctx.beginPath() //开始
ctx.arc(300, 300, 200, 0, Math.PI * 2) //绘制弧线路径
ctx.fillStyle = 'white' //填充颜色
ctx.fill() //填充
ctx.closePath() //闭合
},
此时的页面长这样:

hourCalibration:function(ctx){
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; //定义刻度的数字
ctx.beginPath(); //开始
ctx.translate(300, 300) //移动当前坐标系的原点
ctx.font = '30px bold' //文字的大小
ctx.textAlign = "center"; // 文字居中
ctx.textBaseline = "middle"; // 设置文本绘制中的水平对齐方式 为文本块的中间
ctx.fillStyle = "black"; // 填充颜色
for (var i = 0; i < arr.length; i++) {
//绘制填充类文本
ctx.fillText(
arr[i],
168 * Math.cos(((i * 30 - 60) * Math.PI) / 180),
168 * Math.sin(((i * 30 - 60) * Math.PI) / 180)
);
}
ctx.closePath(); // 结束
},
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; //定义刻度的数字
ctx.beginPath(); //开始
ctx.translate(300, 300) //移动当前坐标系的原点
ctx.font = '30px bold' //文字的大小
ctx.textAlign = "center"; // 文字居中
ctx.textBaseline = "middle"; // 设置文本绘制中的水平对齐方式 为文本块的中间
ctx.fillStyle = "black"; // 填充颜色
for (var i = 0; i < arr.length; i++) {
//绘制填充类文本
ctx.fillText(
arr[i],
168 * Math.cos(((i * 30 - 60) * Math.PI) / 180),
168 * Math.sin(((i * 30 - 60) * Math.PI) / 180)
);
}
ctx.closePath(); // 结束
},
此时页面:

centerDot:function(ctx){
ctx.beginPath(); // 开始
ctx.arc(0, 0, 8, 0, 2 * Math.PI); //绘制弧线路径
ctx.fill(); //对封闭路径进行填充
ctx.beginPath(); //开始
ctx.fillStyle = "white";
ctx.arc(0, 0, 5, 0, 2 * Math.PI); //绘制弧线路径
ctx.fill();//对封闭路径进行填充
},
ctx.beginPath(); // 开始
ctx.arc(0, 0, 8, 0, 2 * Math.PI); //绘制弧线路径
ctx.fill(); //对封闭路径进行填充
ctx.beginPath(); //开始
ctx.fillStyle = "white";
ctx.arc(0, 0, 5, 0, 2 * Math.PI); //绘制弧线路径
ctx.fill();//对封闭路径进行填充
},
此时的页面长这样:

此时需要获取当前系统的本地时间,在此处遇到了一个小麻烦,鸿蒙开发者工具new Date() 获取到的时间为格林威治时间,而我们现在采用的是北京时间,需要写函数来转化时间,转化函数为getTimeStamp()。
getTimeStamp:function(){
var zoneOffset = 8;
//算出时差,并转换为毫秒:
var offset2 = new Date().getTimezoneOffset()* 60 * 1000;
//算出现在的时间:
var nowDate2 = new Date().getTime();
//此时东八区的时间
var currentZoneDate = new Date(nowDate2 + offset2 + zoneOffset*60*60*1000);
return currentZoneDate;
}
获取当前北京时间:
//修改时间 默认获取的是格林威治时间 需要将时间转化为北京时间才行
var date = this.getTimeStamp(new Date())
//获取当前的小时
var hours = date.getHours()
console.log(hours+'hours')
//获取当前分钟
var minutes = date.getMinutes()
console.log(minutes+'minutes')
//获取当前秒数
var seconds = date.getSeconds()
console.log(seconds+'seconds')
hourHand:function(ctx,hours, minutes){
var radius =
((2 * Math.PI) / 12) * hours + (((1 / 6) * Math.PI) / 60) * minutes;
ctx.save();// 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 8; // 针的宽度
ctx.lineCap = "round"; // 针头为圆角
ctx.strokeStyle = "green"; //针的颜色
ctx.rotate(radius); // 旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -90);
ctx.stroke();
ctx.closePath() // 结束
// 回到保存的状态
ctx.restore();
},
var radius =
((2 * Math.PI) / 12) * hours + (((1 / 6) * Math.PI) / 60) * minutes;
ctx.save();// 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 8; // 针的宽度
ctx.lineCap = "round"; // 针头为圆角
ctx.strokeStyle = "green"; //针的颜色
ctx.rotate(radius); // 旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -90);
ctx.stroke();
ctx.closePath() // 结束
// 回到保存的状态
ctx.restore();
},
此时的页面长这样:

minuteHand:function(ctx,minutes){
2 * Math.PI;
var radius = ((2 * Math.PI) / 60) * minutes;
ctx.save(); // 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 4; // 针的宽度
ctx.lineCap = "round"; //针头为圆角
ctx.strokeStyle = "black";
ctx.rotate(radius); //旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -110);
ctx.stroke(); //绘制轮廓圆
ctx.closePath() //结束
ctx.restore();
},
2 * Math.PI;
var radius = ((2 * Math.PI) / 60) * minutes;
ctx.save(); // 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 4; // 针的宽度
ctx.lineCap = "round"; //针头为圆角
ctx.strokeStyle = "black";
ctx.rotate(radius); //旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -110);
ctx.stroke(); //绘制轮廓圆
ctx.closePath() //结束
ctx.restore();
},
此时页面长这样:

secondHand:function(ctx,seconds) {
var radius = ((2 * Math.PI) / 60) * seconds;
ctx.save(); // 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 2; // 针的宽度
ctx.lineCap = "round"; //针头为圆角
ctx.strokeStyle = "red";
ctx.rotate(radius); //旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -140);
ctx.stroke();//绘制轮廓圆
ctx.closePath() //结束
ctx.restore();
},
var radius = ((2 * Math.PI) / 60) * seconds;
ctx.save(); // 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 2; // 针的宽度
ctx.lineCap = "round"; //针头为圆角
ctx.strokeStyle = "red";
ctx.rotate(radius); //旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -140);
ctx.stroke();//绘制轮廓圆
ctx.closePath() //结束
ctx.restore();
},
此时页面长这样:

updateClock:function(ctx){
var time = this.getTimeStamp(new Date())
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();
ctx.save();
this.drawPanel(this.ctx);
this.hourCalibration(this.ctx);
this.secondHand(this.ctx,seconds);
this.minuteHand(this.ctx,minutes);
this.hourHand(this.ctx,hours, minutes);
this.centerDot(this.ctx)
ctx.closePath();
ctx.restore();
}
var time = this.getTimeStamp(new Date())
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();
ctx.save();
this.drawPanel(this.ctx);
this.hourCalibration(this.ctx);
this.secondHand(this.ctx,seconds);
this.minuteHand(this.ctx,minutes);
this.hourHand(this.ctx,hours, minutes);
this.centerDot(this.ctx)
ctx.closePath();
ctx.restore();
}
那么就需要在initData 函数中写一个定时器没一秒钟执行一次绘制函数即可: 最后的图片如上图第一张图所示的效果。
initData:function(){
// 定时器一分钟刷新一次时间
let timer = setInterval(()=>{
this.ctx.clearRect(0, 0, 600, 600); //删除指定区域内的绘制内容。
this.updateClock(this.ctx)
},1000)
},
以上就是canvas 绘制一个时钟的全部步骤了。 最重要的一点是要能正确的获取到时间(北京时间)但是我发现在编辑器上new Date() 到的时间跟咋们的北京时间相差了八小时,在一位同事的提醒下才知道这个获取的时间为格林威治时间,那么我们需要将这个格林威治时间转化成北京时间,在网上找了一段转化方法终于转化成功。
© 版权声明
文章版权归作者所有,未经允许请勿转载。