欲观看效果请点击下载,然后用浏览器打开index.html查看。

本作 Github地址:https://github.com/horn19782016/StopWatch

图例:

代码:

<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head>
     <title>秒表 19.3.5 8:28 by:逆火狂飙 horn19782016@163.com</title>

     <style>
     #canvas{
        background:#ffffff;
        cursor:pointer;
        margin-left:10px;
        margin-top:10px;
        -webkit-box-shadow:3px 3px 6px rgba(0,0,0,0.5);
        -moz-box-shadow:3px 3px 6px rgba(0,0,0,0.5);
        box-shadow:3px 3px 6px rgba(0,0,0,0.5);
     }

     #controls{
        margin-top:10px;
        margin-left:15px;
     }
     </style>

    </head>

     <body onload="init()">
        <div id="controls">
            <input id='animateBtn' type='button' value='开始'/>
            <input id='elapsedTxt' type='text' value='' readonly/>
        </div>

        <canvas id="canvas" width="400px" height="400px" >
            出现文字表示你的浏览器不支持HTML5
        </canvas>
     </body>
</html>
<script type="text/javascript">
<!--
var paused=true;
animateBtn.onclick=function(e){
    paused=! paused;

    if(paused){
        animateBtn.value="开始";
        writeElapsed();
        stopWatch.stop();
    }else{
        animateBtn.value="停止";
        elapsedTxt.value='0';
        stopWatch.start();
        window.requestAnimationFrame(animate);
    }

    //alert("isRunning()="+stopWatch.isRunning());
    //alert("getElapsedTime()="+stopWatch.getElapsedTime());
    //alert("getPointerAngle()="+stopWatch.getPointerAngle());
}

var stopWatch;// 秒表对象
var ctx;// 绘图环境
var r;// 表盘半径
function init(){
    // init Canvas
    var canvas=document.getElementById('canvas');
    r=200;
    canvas.width =2*r;
    canvas.height=2*r;
    ctx=canvas.getContext('2d');

    stopWatch=new Stopwatch();
    stopWatch.reset();

    index=0;
};

function writeElapsed(){
    var date3=stopWatch.getElapsedTime();

    //计算出相差天数
    var days=Math.floor(date3/(24*3600*1000))

    //计算出小时数
    var leave1=date3%(24*3600*1000)    //计算天数后剩余的毫秒数
    var hours=Math.floor(leave1/(3600*1000))

    //计算相差分钟数
    var leave2=leave1%(3600*1000)        //计算小时数后剩余的毫秒数
    var minutes=Math.floor(leave2/(60*1000))

    //计算相差秒数
    var leave3=leave2%(60*1000)      //计算分钟数后剩余的毫秒数
    var seconds=Math.round(leave3/1000)

    var str="共用时";
    if(days>0){
        str=str+days+"天";
    }
    if(hours>0){
        str=str+hours+"小时";
    }
    if(minutes>0){
        str=str+minutes+"分钟";
    }
    if(seconds>0){
        str=str+seconds+"秒";
    }
    str=str+(date3 % 1000)+"毫秒";

    elapsedTxt.value=str;
}

function writeUsed(){
    var date3=stopWatch.getElapsedTime();

    //计算出相差天数
    var days=Math.floor(date3/(24*3600*1000))

    //计算出小时数
    var leave1=date3%(24*3600*1000)    //计算天数后剩余的毫秒数
    var hours=Math.floor(leave1/(3600*1000))

    //计算相差分钟数
    var leave2=leave1%(3600*1000)        //计算小时数后剩余的毫秒数
    var minutes=Math.floor(leave2/(60*1000))

    //计算相差秒数
    var leave3=leave2%(60*1000)      //计算分钟数后剩余的毫秒数
    var seconds=Math.round(leave3/1000)

    var str="已用时";
    if(days>0){
        str=str+days+"天";
    }
    if(hours>0){
        str=str+hours+"小时";
    }
    if(minutes>0){
        str=str+minutes+"分钟";
    }
    if(seconds>0){
        str=str+seconds+"秒";
    }
    //str=str+(date3 % 1000)+"毫秒";

    elapsedTxt.value=str;
}

function draw(){
    // Clear Canvas
    ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
    ctx.fillStyle="#ECF5FF";
    ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);

    // Paint Scales
    var width = ctx.canvas.width;
    var height = ctx.canvas.height;
    var BL = width / 200;

    ctx.save();
        ctx.translate(r,r);// 平移到几何中心

        // 画外面的蓝边
        ctx.beginPath();
        ctx.lineWidth = 5 * BL;//线要 乘上 比例
        ctx.strokeStyle = "#2894FF";
        ctx.arc(0, 0, r - 18 * BL, 2 * Math.PI, false);//乘上比例
        ctx.stroke();
        ctx.closePath();

        ctx.beginPath();
        ctx.lineWidth = 1 * BL;//线要 乘上 比例
        ctx.strokeStyle = "#2894FF";
        ctx.arc(0, 0, 2 * BL, 2 * Math.PI, false);//乘上比例
        ctx.stroke();
        ctx.closePath();

        // 画表盘数字
        ctx.fillStyle="#2894FF";
        var hourNumber = [15, 20, 25, 30, 35, 40, 45,50, 55, 0, 5,10,];
        ctx.font = 10 * BL + 'px Arial';//字体也有乘比例 字符串拼接
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        hourNumber.forEach(function (number, i) {
            var rad = 2 * Math.PI / 12 * i;
            var x = Math.cos(rad) * (r - 8 * BL);
            var y = Math.sin(rad) * (r - 8 * BL);
            ctx.fillText(number, x, y);
        });

        // 画刻度
        for (var i = 0; i < 60; i+=0.5) {
            var rad = 2 * Math.PI / 60 * i;

            var x1 = Math.cos(rad) * (r - 20 * BL);
            var y1 = Math.sin(rad) * (r - 20 * BL);
            var x2 = Math.cos(rad) * (r - 24 * BL);
            var y2 = Math.sin(rad) * (r - 24 * BL);

            if (i % 2.5 == 0) {
                x2 = Math.cos(rad) * (r - 26 * BL);
                y2 = Math.sin(rad) * (r - 26 * BL);
            } 

            ctx.beginPath();
            ctx.lineWidth = 0.5 * BL;//线要 乘上 比例
            ctx.strokeStyle = "#2894FF";
            ctx.moveTo(x1,y1);
            ctx.lineTo(x2,y2);

            ctx.stroke();
            ctx.closePath();
        }

        // 画秒针
        var date = new Date();
        var second=date.getSeconds();
        var angleS=second*6;

        ctx.save();
            //ctx.rotate(getRad(-90));
            ctx.lineWidth=0.5;

            ctx.strokeStyle = "black";
            ctx.beginPath();

            var angle=stopWatch.getPointerAngle();
            if(Math.abs(angle%90,0)<2){
                writeUsed();
            }
            ctx.rotate(getRad(angle));

            ctx.moveTo(-1 * BL, 16 * BL);//画出一个秒针 x轴-2 y轴20
            ctx.lineTo(1 * BL,16 * BL);
            ctx.lineTo(1, -r + 26 * BL);
            ctx.lineTo(-1, -r + 26 * BL);
            ctx.fill();

            ctx.stroke();
            ctx.closePath();
        ctx.restore();

    ctx.restore();
}

function animate(){
    if(!paused){
        draw();

        //setTimeout( function(){
            window.requestAnimationFrame(animate); /// 让浏览器自行决定帧速率
        //}, 0.20 * 1000 );// 延时执行
    }
}

//---------------------------------------------------Stopwatch类定义开始------------------------------------------------------------------->>
Stopwatch=function(){}
Stopwatch.prototype={
    // Property
    startTime:0,
    running:false,
    elapsed:0,

    // method
    start:function(){
        this.startTime=+new Date();
        this.elapsed=0;
        this.running=true;
    },

    stop:function(){
        this.elapsed=(+new Date())-this.startTime;
        this.running=false;
    },

    getElapsedTime:function(){
        if(this.running){
            return (+new Date())-this.startTime;
        }else{
            return this.elapsed;
        }
    },

    getPointerAngle:function(){
        var sec=this.getElapsedTime()/1000;
        return (sec*6) % 360;
    },

    getSeconds:function(){
        var sec=this.getElapsedTime()/1000;
        return sec;
    },

    isRunning:function(){
        return this.running;
    },

    reset:function(){
        this.elapsed=0;
    },
}
//---------------------------------------------------Stopwatch类定义结束-------------------------------------------------------------------<<
//  常规函数:角度得到弧度
function getRad(degree){
    return degree/180*Math.PI;
}
//-->
</script>

2019年3月5日14点19分

[Canvas]计时表/秒表的更多相关文章

  1. HTML5 Canvas核心技术:图形、动画与游戏开发 PDF扫描版​

    HTML5 Canvas核心技术:图形.动画与游戏开发 内容简介: <HTML5 Canvas核心技术:图形.动画与游戏开发>中,畅销书作家David Geary(基瑞)先生以实用的范例程 ...

  2. html5 canvas常用api总结(三)--图像变换API

    canvas的图像变换api,可以帮助我们更加方便的绘画出一些酷炫的效果,也可以用来制作动画.接下来将总结一下canvas的变换方法,文末有一个例子来更加深刻的了解和利用这几个api. 1.画布旋转a ...

  3. 【探索】利用 canvas 实现数据压缩

    前言 HTTP 支持 GZip 压缩,可节省不少传输资源.但遗憾的是,只有下载才有,上传并不支持.如果上传也能压缩,那就完美了.特别适合大量文本提交的场合,比如博客园,就是很好的例子. 虽然标准不支持 ...

  4. 简单入门canvas - 通过刮奖效果来学习

    一 .前言 一直在做PC端的前端开发,从互联网到行业软件.最近发现移动端已经成为前端必备技能了,真是不能停止学习.HTML5新增的一些东西,canvas是用的比较多也比较复杂的一个,简单的入门了一下, ...

  5. 获取Canvas当前坐标系矩阵

    前言 在我的另一篇博文 Canvas坐标系转换 中,我们知道了所有的平移缩放旋转操作都会影响到画布坐标系.那在我们对画布进行了一系列操作之后,怎么再知道当前矩阵数据状态呢. 具体代码 首先请看下面的一 ...

  6. Canvas坐标系转换

    默认坐标系与当前坐标系 canvas中的坐标是从左上角开始的,x轴沿着水平方向(按像素)向右延伸,y轴沿垂直方向向下延伸.左上角坐标为x=0,y=0的点称作原点.在默认坐标系中,每一个点的坐标都是直接 ...

  7. Canvas绘图之平移translate、旋转rotate、缩放scale

    画布操作介绍 画布绘图的环境通过translate(),scale(),rotate(), setTransform()和transform()来改变,它们会对画布的变换矩阵产生影响. 函数 方法 描 ...

  8. 用html5的canvas和JavaScript创建一个绘图程序

    本文将引导你使用canvas和JavaScript创建一个简单的绘图程序. 创建canvas元素 首先准备容器Canvas元素,接下来所有的事情都会在JavaScript里面. <canvas ...

  9. html5标签canvas函数drawImage使用方法

    html5中标签canvas,函数drawImage(): 使用drawImage()方法绘制图像.绘图环境提供了该方法的三个不同版本.参数传递三种形式: drawImage(image,x,y):在 ...

随机推荐

  1. redis详解(三)-- 面试题

    1. 使用Redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,li ...

  2. How do I debug a published XBAP file in VS2010?

    I need to debug a full-trust application either by specifying a URL or, ideally, from within the web ...

  3. C++学习笔记23,类内函数重载

    该博文仅用于交流学习.请慎用于不论什么商业用途,本博主保留对该博文的一切权利. 博主博客:http://blog.csdn.net/qq844352155 转载请注明出处: 在一个类内,最常见的就是构 ...

  4. 在ASP.NET MVC下有关上传图片脏数据的解决方案

    在"在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片"中,已经实现了在客户端和服务端限制图片大小和格式,以及在服务端裁剪图片.但还 ...

  5. 实习医生格蕾第一季/全集Grey’s Anatomy迅雷下载

    第一季 Grey's Anatomy Season 1 (2005)看点:欢迎来到格雷斯医院,哈佛医学院西区最艰苦的外科住院医实习程序,医务新人最残酷的训练场.Meredith.Izzie和Chris ...

  6. 通过泛型来简化findViewById

    我们一般写findViewById都要加个强制转换,感觉很麻烦,现在你可以在你的BaseActivity中写入如下方法: @SuppressWarnings(“unchecked”) public f ...

  7. 部署maven的一些要点、遇到的问题和心得体会

    maven的部署.遇到的问题和心得体会 2013-10-24 | 阅:  转:  |  分享         部署maven的一些要点.遇到的问题和心得体会 (图片看不了,可以下载doc文件) 一.  ...

  8. .AVLFile Extension

    .AVLFile Extension File Type 1ArcView Legend File   Developer ESRI Popularity           4.1 (7 Votes ...

  9. 用Razor語法寫範本-RazorEngine組件介紹

    最近剛好有要寫寄Email的程式,在代碼中寫HTML覺得很呆,抽出代碼外寫到txt或html檔當範本,由程式執行時在載入檔案時用Regex換關鍵字又覺得不夠好用,而且因為有時會有要判斷一些條件,就會寫 ...

  10. iOS:在cell中使用倒计时的最佳方法

    一.简单介绍 在UITableViewCell中每条数据中显示该内容的倒计时, 并随时间进行倒数,这是很多电商app最常见的活动推销功能模块,自然想到用的就是计时器了. 二.基本想法 想法1:在每个c ...