国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

使用h5canvas實現(xiàn)時鐘的動態(tài)效果

來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 15:04:55
文檔

使用h5canvas實現(xiàn)時鐘的動態(tài)效果

使用h5canvas實現(xiàn)時鐘的動態(tài)效果:canvas 繪制好時鐘界面,使用定時器定時重繪整個canvas,就實現(xiàn)了仿真動態(tài)時鐘的效果。難點在于:秒鐘刻度和時鐘刻度的繪制整點文字沿著內(nèi)邊圓形環(huán)繞其中刻度的環(huán)繞并不難計算,文字的環(huán)繞就比較坑爹了,canvas繪制的文字是在繪制坐標(biāo)之上的(文字基線和對齊
推薦度:
導(dǎo)讀使用h5canvas實現(xiàn)時鐘的動態(tài)效果:canvas 繪制好時鐘界面,使用定時器定時重繪整個canvas,就實現(xiàn)了仿真動態(tài)時鐘的效果。難點在于:秒鐘刻度和時鐘刻度的繪制整點文字沿著內(nèi)邊圓形環(huán)繞其中刻度的環(huán)繞并不難計算,文字的環(huán)繞就比較坑爹了,canvas繪制的文字是在繪制坐標(biāo)之上的(文字基線和對齊

下圖是計算刻度線坐標(biāo)和整點文字繪制坐標(biāo)的參考圖:

這里寫圖片描述

canvas畫時鐘效果的代碼編寫

下面是全部代碼:

<!DOCTYPE html><html lang="en"><head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=1024, height=768,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
 <title>時鐘</title></head><body><p style="margin: 50px">
 <canvas width="300" height="300"></canvas>
 <canvas width="200" height="200" style="background-color: #bbbbbb"></canvas>
 <canvas width="200" height="200"></canvas>
 <canvas width="200" height="200"></canvas></p><script>

 var clockHelper = function (canvas, config) {
 if (!config) {
 config = {}
 } var ctx = canvas.getContext('2d'); var deColor = config.deColor ? config.deColor : '#333333'; var deConfig = {
 ringWidth: config.ringWidth ? config.ringWidth : 6,//圓環(huán)寬度
 ringColor: config.ringColor ? config.ringColor : deColor,//圓環(huán)顏色
 hSaleL: config.hSaleL ? config.hSaleL : 8,//時刻度線長
 hScaleWidth: config.hScaleWidth ? config.hScaleWidth : 4,//時刻度線寬
 hScaleColor: config.hScaleColor ? config.hScaleColor : deColor,//時刻度顏色
 msSaleL: config.msSaleL ? config.msSaleL : 4,//分秒刻度線長
 msScaleWidth: config.msScaleWidth ? config.msScaleWidth : 2,//分秒刻度線寬
 msScaleColor: deColor,//分秒刻度顏色
 hFontSize: config.hFontSize ? config.hFontSize : 18,//整點文字大小
 hHandWidth: config.hHandWidth ? config.hHandWidth : 10,//時針寬度
 mHandWidth: config.mHandWidth ? config.mHandWidth : 5,//分針寬度
 sHandWidth: config.sHandWidth ? config.sHandWidth : 2,//秒針寬度

 hHandColor: config.hHandColor ? config.hHandColor : deColor,//時針顏色
 mHandColor: config.mHandColor ? config.mHandColor : deColor,//分針顏色
 sHandColor: config.sHandColor ? config.sHandColor : '#bb3333',//秒針顏色
 handMode: ['ms', 's'].indexOf("" + config.handMode) !== -1 ? config.handMode : 's',//指針讀秒模式,ms:毫秒,s:秒。
 clockFaceColor: config.clockFaceColor ? config.clockFaceColor : '',
 }; var ox = canvas.width / 2; var oy = canvas.height / 2; var width = canvas.width; var height = canvas.height;

 ctx.font = deConfig.hFontSize + "px 黑體"; //中線圓環(huán)半徑
 var ringR = (width < height) ? (width / 2 - deConfig.ringWidth / 2) : (height / 2 - deConfig.ringWidth / 2); //內(nèi)圓環(huán)半徑
 var ringInnerR = (width < height) ? (width / 2 - deConfig.ringWidth) : (height / 2 - deConfig.ringWidth); var timer; var timeSleep = 100; var isStart = false; function start() {
 if (isStart) { return;
 }
 isStart = true; if (deConfig.handMode == 'ms') {
 timeSleep = 100;
 } else {
 timeSleep = 1000;
 }

 ctx.clearRect(0, 0, width, height);
 draw();

 timer = setInterval(function () {
 if (isStart) {
 ctx.clearRect(0, 0, width, height);
 draw();
 }
 }, timeSleep);

 } function stop() {
 isStart = false;
 clearInterval(timer)
 } function draw() {

 beforeDraw();

 drawCircleFace();
 drawHands();

 afterDraw();

 } function drawCircleFace() {

 ctx.fillStyle = deConfig.ringColor;
 ctx.strokeStyle = deConfig.ringColor;

 ctx.lineWidth = deConfig.ringWidth;
 ctx.beginPath();
 ctx.arc(ox, oy, ringR, 0, Math.PI * 2);
 ctx.stroke(); if (deConfig.clockFaceColor) {
 ctx.fillStyle = deConfig.clockFaceColor;
 ctx.fill();
 } var x1 = ox; var y1 = oy; var x2 = ox; var y2 = oy; var radin = 0;
 ctx.lineWidth = deConfig.hScaleWidth; // ctx.beginPath();
 for (var i = 1; i <= 60; i++) {
 radin = i * 6 * Math.PI / 180;
 x1 = ox + ringInnerR * Math.sin(radin);
 y1 = oy - ringInnerR * Math.cos(radin); if (i % 5 === 0) {
 ctx.lineWidth = deConfig.hScaleWidth;
 x2 = ox + (ringInnerR - deConfig.hSaleL) * Math.sin(radin);
 y2 = oy - (ringInnerR - deConfig.hSaleL) * Math.cos(radin);

 ctx.fillStyle = deConfig.hScaleColor; var numText = i / 5 + ""; var textWidth = ctx.measureText(numText).width; var x3 = ox + (ringInnerR - deConfig.hSaleL - deConfig.hFontSize) * Math.sin(radin); var y3 = oy - (ringInnerR - deConfig.hSaleL - deConfig.hFontSize) * Math.cos(radin);
 ctx.textAlign = 'center';
 ctx.textBaseline = 'middle'; //不設(shè)置文字居中,基線居中,自己計算。貌似都有誤差。因為旋轉(zhuǎn)過程中,角度變化,且文字寬高不盡相同
 // var x3 = ox + (ringInnerR - deConfig.hSaleL - deConfig.hFontSize) * Math.sin(radin) - textWidth / 2;
 // var y3 = oy - (ringInnerR - deConfig.hSaleL - deConfig.hFontSize) * Math.cos(radin) + deConfig.hFontSize/ 2;
 //x2,y2已經(jīng)求過,化簡為:
 // var x3 = x2 - deConfig.hFontSize * Math.sin(radin) - textWidth / 2;
 // var y3 = y2 + deConfig.hFontSize * Math.cos(radin) + textWidth / 2;
 //文字x軸向左偏移一半文字寬,使之水平居中;向下偏移一半高度,使之垂直居中。
 // 實際中發(fā)現(xiàn),字高沒法測(api無),而使用fontSize不準(zhǔn)。但y軸加上字寬,位置倒是更對齊一些。

 // var x3 = x2 + textWidth / 2;
 // var y3 = y2 - deConfig.hFontSize / 2;

 ctx.fillText(numText, x3, y3);

 } else {
 ctx.lineWidth = deConfig.msScaleWidth;
 x2 = ox + (ringInnerR - deConfig.msSaleL) * Math.sin(radin);
 y2 = oy - (ringInnerR - deConfig.msSaleL) * Math.cos(radin);
 }


 ctx.beginPath();
 ctx.moveTo(x1, y1);
 ctx.lineTo(x2, y2);
 ctx.stroke();

 }

 } //改變坐標(biāo)中點,并旋轉(zhuǎn)畫布也許是更好的選擇。
 function drawHands() {
 var date = new Date(); var h = date.getHours() % 12; var m = date.getMinutes(); var s = date.getSeconds(); var ms = date.getMilliseconds(); // console.log(h + ":" + m + ":" + s);
 // 時針

 var hRadin = (h + m / 60 + s / 3600) * Math.PI * 2 / 12; var mRadin = (m + s / 60) * Math.PI * 2 / 60; var sRadin; if (deConfig.handMode == 'ms') {
 sRadin = (s + ms / 1000) * Math.PI * 2 / 60;
 } else {
 sRadin = s * Math.PI * 2 / 60;
 } var x = 0; var y = 0; var hDotR = deConfig.hHandWidth + 2; var mDotR = 0.6 * hDotR var sDotR = 0.5 * hDotR //秒針半徑
 var sHandR = ringInnerR - deConfig.hSaleL * 2
 //分針半徑
 var mHandR = 0.8 * sHandR; //時針半徑
 var hHandR = 0.7 * mHandR; //時針
 ctx.beginPath();
 ctx.lineWidth = deConfig.hHandWidth;
 ctx.strokeStyle = deConfig.hHandColor;
 ctx.strokeStyle = deConfig.hHandColor;
 ctx.moveTo(ox, oy);
 x = ox + hHandR * Math.cos(hRadin - Math.PI / 2);
 y = oy + hHandR * Math.sin(hRadin - Math.PI / 2);
 ctx.lineTo(x, y);
 ctx.stroke(); //針尖。直接圓型了(矩形指針來繪制針尖,計算復(fù)雜。。)
 ctx.beginPath();
 ctx.lineWidth = 0;
 ctx.arc(x, y, deConfig.hHandWidth / 2, 0, 2 * Math.PI);
 ctx.fill(); //中心
 ctx.beginPath(); // ctx.lineWidth = hDotR;
 ctx.arc(ox, oy, hDotR / 2, 0, Math.PI * 2);
 ctx.fill();
 ctx.stroke(); //分針
 ctx.beginPath();
 ctx.lineWidth = deConfig.mHandWidth;
 ctx.strokeStyle = deConfig.mHandColor;
 ctx.fillStyle = deConfig.mHandColor;
 ctx.moveTo(ox, oy);
 x = ox + mHandR * Math.cos(mRadin - Math.PI / 2);
 y = oy + mHandR * Math.sin(mRadin - Math.PI / 2);
 ctx.lineTo(x, y);
 ctx.stroke(); //針尖。直接圓型了(矩形指針來繪制針尖,計算復(fù)雜。。)
 ctx.beginPath();
 ctx.lineWidth = 0;
 ctx.arc(x, y, deConfig.mHandWidth / 2, 0, 2 * Math.PI);
 ctx.fill(); //中心
 ctx.beginPath();
 ctx.arc(ox, oy, mDotR / 2, 0, Math.PI * 2);
 ctx.stroke(); //秒針
 ctx.beginPath();
 ctx.strokeStyle = deConfig.sHandColor;
 ctx.fillStyle = deConfig.sHandColor;
 ctx.lineWidth = deConfig.sHandWidth; //秒針有長短兩線
 x = ox - sHandR / 4 * Math.cos(sRadin - Math.PI / 2);
 y = oy - sHandR / 4 * Math.sin(sRadin - Math.PI / 2);
 ctx.moveTo(x, y);
 x = ox + sHandR * Math.cos(sRadin - Math.PI / 2);
 y = oy + sHandR * Math.sin(sRadin - Math.PI / 2);
 ctx.lineTo(x, y);
 ctx.stroke(); //針尖。直接圓型了(矩形指針來繪制針尖,計算復(fù)雜。。)
 ctx.beginPath();
 ctx.lineWidth = 0;
 ctx.arc(x, y, deConfig.sHandWidth / 2, 0, 2 * Math.PI);
 ctx.fill(); //中心
 ctx.beginPath();
 ctx.fillStyle = deColor;
 ctx.arc(ox, oy, sDotR, 0, Math.PI * 2);
 ctx.fill();
 ctx.stroke();

 } function beforeDraw() {
 if (typeof exp.beforeDraw === 'function') {
 exp.beforeDraw(ctx, deConfig);
 }
 } function afterDraw() {
 if (typeof exp.afterDraw === 'function') {
 exp.afterDraw(ctx, deConfig);
 }
 } var exp = {
 start: start,
 stop: stop,
 beforeDraw: null,
 afterDraw: null,
 } return exp;


 } var clockCanvas1 = document.getElementsByTagName('canvas')[0]; var clockCanvas2 = document.getElementsByTagName('canvas')[1]; var clockCanvas3 = document.getElementsByTagName('canvas')[2]; var clockCanvas4 = document.getElementsByTagName('canvas')[3]; var clock = clockHelper(clockCanvas1, {mHandColor: '#3333bb', sHandColor: '#bb3333'});
 clock.start();
 setTimeout(function () {
 clock.stop()
 }, 5000)
 setTimeout(function () {
 clock.start();
 }, 8000)

 clockHelper(clockCanvas2, {
 mHandColor: 'green',
 hHandWidth: 6,
 mHandWidth: 4,
 hFontSize: 14,
 hScaleWidth: 2,
 handMode: 'ms'
 }).start();


 clockHelper(clockCanvas2, {
 mHandColor: 'green',
 hHandWidth: 6,
 mHandWidth: 4,
 hFontSize: 14,
 hScaleWidth: 2,
 handMode: 'ms'
 }).start();


 clockHelper(clockCanvas3, {
 deColor: '#bbbbbb',
 sHandColor: '#bbbbbb',
 clockFaceColor: '#112233',//鐘面
 hHandWidth: 6,
 mHandWidth: 4,
 hFontSize: 14,
 hScaleWidth: 2,
 handMode: 's'
 }).start(); var clock4 = clockHelper(clockCanvas4, {
 deColor: '#bbbbbb',
 sHandColor: '#bbbbbb', // clockFaceColor: '#112233',
 hHandWidth: 6,
 mHandWidth: 4,
 hFontSize: 14,
 hScaleWidth: 2,
 handMode: 's'
 });

 clock4.afterDraw = function (ctx, deConfig) {
 var grd = ctx.createLinearGradient(0, 0, clockCanvas4.width, clockCanvas4.height);
 grd.addColorStop(0, "rgba(255,0,0,0.3)");
 grd.addColorStop(1, "rgba(0,0,255,0.5)");
 ctx.fillStyle = grd;
 ctx.arc(clockCanvas4.width/2,clockCanvas4.height/2,clockCanvas4.width/2,0,Math.PI*2); // ctx.fillRect(0, 0, clockCanvas4.width, clockCanvas4.height);
 ctx.fill();

 ctx.fillText('時鐘繪制完成后,自定義其他繪制',clockCanvas4.width/2,clockCanvas4.height - deConfig.hFontSize);
 };

 clock4.start();</script></body></html>

說明:

1、clockHelper第一個參數(shù)傳入畫布。第二個參數(shù)傳入時鐘界面的配置對象,包括指針、刻度的顏色、大小等,配置項和clockHelper中的deConfig默認(rèn)對象是相對的,參考deConfig的屬性傳入?yún)?shù)即可。

2、clockHelper的封裝性略差,僅是基本能用型。但屬性不多,改造應(yīng)該并不困難。

3、提供了時鐘界面繪制之前和之后的方法,可以在beforeDraw和afterDraw這兩個方法中執(zhí)行自己的邏輯。但是由于事先設(shè)計沒有留出足夠的空白像素,用處不大。只能進行一些簡單的再繪制。比如給鐘面添加色彩、漸變。

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

使用h5canvas實現(xiàn)時鐘的動態(tài)效果

使用h5canvas實現(xiàn)時鐘的動態(tài)效果:canvas 繪制好時鐘界面,使用定時器定時重繪整個canvas,就實現(xiàn)了仿真動態(tài)時鐘的效果。難點在于:秒鐘刻度和時鐘刻度的繪制整點文字沿著內(nèi)邊圓形環(huán)繞其中刻度的環(huán)繞并不難計算,文字的環(huán)繞就比較坑爹了,canvas繪制的文字是在繪制坐標(biāo)之上的(文字基線和對齊
推薦度:
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 91中文字幕在线观看 | 亚洲国产成人精品久久 | 免费在线观看一区二区 | 国产一级成人毛片 | 国产日韩欧美一区 | 精品日韩二区三区精品视频 | 日韩一级精品久久久久 | 91精品久久久久久久久网影视 | 国产精品视频免费一区二区三区 | 欧美色图一区二区 | 色网电影| 国产l精品国产亚洲区在线观看 | 精品久久久久久中文字幕 | 亚洲国产日韩欧美在线as乱码 | 欧美极品另类xxx | 欧美日韩亚洲高清不卡一区二区三区 | 青青国产成人久久激情91麻豆 | 亚洲国产精品一区二区久久 | 国产欧美日韩综合精品无毒 | 国产在线观看网站 | 日韩精品免费看 | 国产免费高清视频在线观看不卡 | 亚洲色图欧美激情 | 成人特黄午夜性a一级毛片 成人国产一区二区三区精品 | 欧美日韩 国产区 在线观看 | 老司机精品视频一区二区 | 亚洲韩国日本欧美一区二区三区 | 91中文视频 | 免费看黄视频网站 | 亚洲欧美综合区自拍另类 | 亚洲一二三区视频 | 久久无码精品一区二区三区 | 亚洲久草 | 欧美日韩国产一区二区 | caoprom在线| 日韩欧美国产另类 | 91精品欧美 | 午夜视频久久久久一区 | 欧美影院在线 | 日韩欧美高清视频 | 欧美一区二区在线播放 |