下面一段代码给大家分享js实现时钟滴答声功能,具体代码如下所示:
<!doctype html>
<html>
<head>
<meta charset="utf8">
<meta http-equiv="x-ua-compatible" content="ie=edge, chrome=1">
<meta name="keywords" content="clock">
<meta name="description" content="this is a clock">
<title>clock</title>
</head>
<body>
<audio id="ticktock">
<source = src="ticktock.mp3" type="audio/mp3">
</audio>
<script type="text/javascript">
/*
年(y)可以用 1-4 个占位符
月(m)、日(d)、时(h,24时)、时(h,12时)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符
毫秒(s)只能用 1 个占位符(是 1-3 位数字)
am或pm只能用 1 个占位符(是 2 位英文)
上午或下午(t)只能用 1 个占位符(是 2 位中文)
星期(e)可以用 1-3 个占位符
季度(q)只能用 1 个占位符(是 1 位数字)
*/
date.prototype.format = function(fmt) {
var map = {
"m+" : this.getmonth() + 1, //月
"d+" : this.getdate(), //日
"h+" : this.gethours(), //24时
/*
上午12时只代表当天上午的12时,下午的12时代表当天下午的12时,
0时代表第二天的开始,即前面一天12时已过0时开始计算新一天的时间,
虽然说时间上跟前面那一天下午12时重合,但日期已经发生更改,所以不能说0时就是12时
*/
"h+" : this.gethours()%12 == 0 ? 12 : this.gethours()%12,//12时
"m+" : this.getminutes(), //分
"s+" : this.getseconds(), //秒
"s" : this.getmilliseconds(), //毫秒
"t" : this.gethours() < 12 ? "am" : "pm",
"t" : this.gethours() < 12 ? "上午" : "下午",
};
var week = {
"0" : "日",
"1" : "一",
"2" : "二",
"3" : "三",
"4" : "四",
"5" : "五",
"6" : "六",
}
var quarter = {
"0" : "一",
"1" : "二",
"2" : "三",
"3" : "四",
}
if(/(y+)/.test(fmt)) {
fmt = fmt.replace(regexp.$1, (this.getfullyear()+"").substr(4 - regexp.$1.length));
}
if(/(e+)/.test(fmt)) {
var weekprestr;
switch(regexp.$1.length) {
case 1:
weekprestr = "";
break;
case 2:
weekprestr = "周";
break;
default:
weekprestr = "星期";
break;
}
fmt = fmt.replace(regexp.$1, weekprestr + week[this.getday()]);
}
if(/(q)/.test(fmt)) {
fmt = fmt.replace(regexp.$1, quarter[math.floor(this.getmonth() / 3)]);
}
for(var key in map) {
if(new regexp("(" + key + ")").test(fmt)) {
fmt = fmt.replace(regexp.$1, regexp.$1.length == 1 ? map[key] : ("00" + map[key]).substr((map[key]+"").length));
}
}
return fmt;
}
</script>
<script>
var canvas = document.createelement("canvas");
document.body.appendchild(canvas);
var ctx = canvas.getcontext("2d");
var halfpi = math.pi / 2;
var doublepi = math.pi * 2;
//阴影级别
var shadowblur = 10;
//阴影宽度
var shadowwidth = 8;
//阴影在x方向上的偏移
var shadowoffsetx = 5;
//阴影在y方向上的便宜
var shadowoffsety = 5;
//深色阴影
var shadowdarkcolor = "rgba(0,0,0,0.8)";
//浅色阴影
var shadowlightcolor = "rgba(0,0,0,0.1)";
//画布中心到边缘的内切圆半径
var canvasradius = 250;
canvas.width = canvasradius * 2;
canvas.height = canvasradius * 2;
//获取画布中心的坐标
var cx = canvasradius;
var cy = canvasradius;
//时钟外圈的贝塞尔花纹个数
var bezierpatterncount = 36;
//时钟外圈的贝塞尔花纹波峰处半径
var bezierpeakradius = canvasradius - 10;
//时钟外圈的贝塞尔花纹一半的角度
var bezierhalfspan = doublepi / bezierpatterncount / 2;
//时钟外圈的贝塞尔花纹底部半径
var bezierradius = bezierpeakradius - 20;
//时钟外圈的贝塞尔花纹颜色
var bezierpatterncolor = "plum";
//时钟外圈半径
var clockborderradius = bezierradius - 10;
//时钟外圈宽度
var clockborderwidth = 10;
//时钟外圈颜色
var clockbordercolor = "aqua";
//时钟外圈阴影半径
var clockbordershadowradius = clockborderradius - shadowwidth + 1;
//时钟整数时间刻度线宽
var clockscalewidth = 2;
//时钟整数时间刻度外半径
var clockscaleouterradius = clockborderradius - shadowwidth;
//时钟整数时间刻度内半径
var clockscaleinnerradius = clockscaleouterradius - 20;
//时钟刻度颜色
var clockscalecolor = "black";
//时钟非整数时间处半径
var clockscalemiddleradius = clockscaleouterradius - 10;
//时钟数字半径
var clocknumradius = clockbordershadowradius - 40;
//时钟数字字体
var clocknumfont = "25px arial";
//时钟数字颜色
var clocknumcolor = "black";
//数字日期距中心的垂直距离
var digitaldatemargincenter = 50;
//数字日期颜色
var digitaldatecolor = "black";
//数字日期字体
var digitaldatefont = "bold 18px arial";
//数字时间距中心的垂直距离
var digitaltimemargincenter = 100;
//数字时间颜色
var digitaltimecolor = "white";
//数字时间背景颜色
var digitaltimebgcolor = "darkslateblue";
//数字时间字体
var digitaltimefont = "bold 25px arial";
//数字时间高度的一半
var digitaltimeheight = 40;
//数字时间分隔线宽度
var digitaltimespanlinewidth = 2;
//时钟中心点内圆的半径
var clockcenterinnerdotradius = 7;
//时钟中心点内圆的颜色
var clockcenterinnerdotcolor = "firebrick";
//时钟中心点外圆的半径
var clockcenterouterdotradius = 10;
//时钟中心点外圆的颜色
var clockcenterouterdotcolor = "maroon";
//时针线宽
var clockneedlewidth = 5;
//时针半径
var clockhourneedleradius = clockbordershadowradius - 120;
//时针颜色
var clockhourneedlecolor = "darkgreen";
//分针半径
var clockminuteneedleradius = clockbordershadowradius - 80;
//分针颜色
var clockminuteneedlecolor = "darkslategray";
//秒针半径
var clocksecondneedleradius = clockbordershadowradius - 40;
//秒针尾部半径
var clocksecondneedlebottomradius = -20;
//秒针颜色
var clocksecondneedlecolor = "firebrick";
//画圆环
function strokecircle(cx, cy, r) {
ctx.beginpath();
ctx.arc(cx, cy, r, 0, doublepi);
ctx.stroke();
}
//画圆
function fillcircle(cx, cy, r) {
ctx.beginpath();
ctx.arc(cx, cy, r, 0, doublepi);
ctx.fill();
}
//绘制线条
function strokeline(x1, y1, x2, y2) {
ctx.beginpath();
ctx.moveto(x1, y1);
ctx.lineto(x2, y2);
ctx.stroke();
}
//根据角度和半径计算圆上相应位置的坐标(最右侧为起始角度,顺时针方向为正)
function circlepos(cx, cy, theta, radius) {
var pos = {
x: cx + radius * math.cos(theta),
y: cy + radius * math.sin(theta),
};
return pos;
}
//在圆环上绘制刻度线
function strokecircleline(cx, cy, theta, r1, r2) {
var pos1 = circlepos(cx, cy, theta, r1);
var pos2 = circlepos(cx, cy, theta, r2);
strokeline(pos1.x, pos1.y, pos2.x, pos2.y);
}
//设置默认阴影
function setshadow(type) {
ctx.linewidth = shadowwidth;
ctx.shadowblur = shadowblur;
ctx.shadowoffsetx = shadowoffsetx;
ctx.shadowoffsety = shadowoffsety;
if(type === 1) {
ctx.shadowcolor = shadowlightcolor;
} else {
ctx.shadowcolor = shadowdarkcolor;
}
}
//取消阴影
function clearshadow() {
ctx.shadowcolor = "rgba(0,0,0,0)";
ctx.shadowblur = 0;
ctx.shadowoffsetx = 0;
ctx.shadowoffsety = 0;
}
//绘制时钟外圈的贝塞尔花纹
function renderbezierpattern() {
ctx.fillstyle = bezierpatterncolor;
ctx.beginpath();
var theta = 0;
//由于circlepos是顺时针方向正, 故圈也是顺时针方向
var beginpos = circlepos(cx, cy, theta, bezierradius);
ctx.moveto(beginpos.x, beginpos.y);
while(theta < doublepi) {
//贝塞尔曲线控制点
var controltheta = theta + bezierhalfspan;
var controlpos = circlepos(cx, cy, controltheta, bezierpeakradius);
//贝塞尔曲线终止点
var endtheta = controltheta + bezierhalfspan;
var endpos = circlepos(cx, cy, endtheta, bezierradius);
ctx.quadraticcurveto(controlpos.x, controlpos.y, endpos.x, endpos.y);
theta = endtheta;
}
//绘制圆counterclockwise=false, 即默认是顺时针方向
ctx.arc(cx, cy, clockborderradius, 0, doublepi, true);
//注意: 两个相反方向的路径内部为填充范围
ctx.fill();
}
//绘制时钟边框
function renderclockborder() {
//画外框
ctx.strokestyle = clockbordercolor;
ctx.linewidth = clockborderwidth;
strokecircle(cx, cy, clockborderradius);
//画外框的内阴影
ctx.strokestyle = shadowlightcolor;
setshadow(1);
strokecircle(cx, cy, clockbordershadowradius);
clearshadow();
}
//绘制时钟圆周上的数字和刻度部分
function renderclocknums() {
ctx.textalign = "center";
ctx.textbaseline = "middle";
ctx.font = clocknumfont;
var span = doublepi / 60;
for(var i = 1, radian = -halfpi + span; i <= 60; i++, radian += span) {
if(i % 5 == 0) {
//绘制刻度
ctx.strokestyle = clockscalecolor;
ctx.linewidth = clockscalewidth;
strokecircleline(cx, cy, radian, clockscaleinnerradius, clockscaleouterradius);
//绘制数字
var pos = circlepos(cx, cy, radian, clocknumradius);
var num = i / 5;
ctx.fillstyle = clocknumcolor;
ctx.filltext(num, pos.x, pos.y);
} else {
ctx.strokestyle = clockscalecolor;
ctx.linewidth = clockscalewidth;
strokecircleline(cx, cy, radian, clockscalemiddleradius, clockscaleouterradius);
}
}
}
//绘制数字时钟
function renderdigital(date) {
//绘制日期
ctx.textalign = "center";
ctx.textbaseline = "middle";
ctx.font = digitaldatefont;
ctx.fillstyle = digitaldatecolor;
var text = date.format("yyyy年mm月dd日 eee");
ctx.filltext(text, cx, cy + digitaldatemargincenter);
//绘制时间
ctx.font = digitaltimefont;
text = date.format(" hh mm ss ");
ctx.fillstyle = digitaltimebgcolor;
var textwidth = ctx.measuretext(text).width;
var textbgx = cx - textwidth / 2;
var textbgy = cy + digitaltimemargincenter - digitaltimeheight / 2;
ctx.fillrect(textbgx, textbgy, textwidth, digitaltimeheight);
ctx.fillstyle = digitaltimecolor;
ctx.filltext(text, cx, cy + digitaltimemargincenter);
//绘制事件中间的分隔线
ctx.linewidth = digitaltimespanlinewidth;
ctx.strokestyle = digitaltimecolor;
var textspan = textwidth / 6;
var leftlinex = cx - textspan;
strokeline(leftlinex, textbgy, leftlinex, textbgy + digitaltimeheight);
var rightlinex = cx + textspan;
strokeline(rightlinex, textbgy, rightlinex, textbgy + digitaltimeheight);
}
//绘制时钟中心最下方红点
function renderclockcenterouterdot() {
ctx.fillstyle = clockcenterouterdotcolor;
fillcircle(cx, cy, clockcenterouterdotradius);
}
//绘制时钟中心最上方红点
function renderclockcenterinnerdot() {
ctx.fillstyle = clockcenterinnerdotcolor;
fillcircle(cx, cy, clockcenterinnerdotradius);
}
//绘制时钟指针
function renderclockneedle(date) {
var hourradian = date.gethours() % 12 / 12 * doublepi - halfpi;
var minuteradian = date.getminutes() / 60 * doublepi - halfpi;
var secondradian = date.getseconds() / 60 * doublepi - halfpi;
setshadow();
ctx.linecap = "round";
ctx.linewidth = clockneedlewidth;
ctx.strokestyle = clockhourneedlecolor;
strokecircleline(cx, cy, hourradian, 0, clockhourneedleradius);
ctx.strokestyle = clockminuteneedlecolor;
strokecircleline(cx, cy, minuteradian, 0, clockminuteneedleradius);
ctx.strokestyle = clocksecondneedlecolor;
strokecircleline(cx, cy, secondradian, clocksecondneedlebottomradius, clocksecondneedleradius);
ctx.linecap = "square";
clearshadow();
}
function render(date) {
ctx.clearrect(0, 0, canvas.width, canvas.height);
renderbezierpattern();
renderclockborder();
renderclocknums();
renderdigital(date);
renderclockcenterouterdot();
renderclockneedle(date);
renderclockcenterinnerdot();
}
var lasttime = 0;
var audio = document.getelementbyid("ticktock");
function loop() {
var date = new date();
var currenttime = date.gettime();
if(currenttime - lasttime >= 1000) {
lasttime = currenttime;
//注意:这里设0非常关键,否则虽然会循环播放,但会从上一次暂停的地方开始播放,造成延迟
audio.currenttime = 0;
audio.play();
render(date);
}
requestanimationframe(loop);
}
loop();
</script>
</body>
</html>
以上所述是小编给大家介绍的javascript实现时钟滴答声效果,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!
更多javascript实现时钟滴答声效果。