zoukankan      html  css  js  c++  java
  • 学者玩玩Canvas-写个简单的模拟时钟

    最近在看HTML5,随便玩玩Canvas,于是想着写个简单的模拟时钟,不过想象力不够丰富,没啥好创意,做的比较丑~~ 哈哈

    Demon点这儿你懂得 哈哈

    代码:

    /************************************************************************
    *************************************************************************
    case Name :           clock - jQuery Plugin
    case Revison :        1.0
    case Date :         2014-4-02
    case Author:        zy_ding@ctrip.com
    case Support:        FF, IE9, IE10, Chrome, Others(unknown)
    case License :        N/A
    *************************************************************************/
    (function ($) {
        $.fn.clock = function (opt) {
            var defaults = {
                radius: 200,
                ctX: 500,
                ctY: 300,
                speed: 1000 / 60,
                plummetLength: 160
            }
            var options = $.extend(defaults, opt);
            var colors = ['#000', '#104070', '#184F73', '#285F83', '#306090', '#386F93', '#4070A0', '#487FA3', '#5080B0', '#588FB3', '#6090C0', '#689FC3', '#70A0D0', '#78AFD3'];
            var $this = this;
            var time = new Date();
            var milSeconds = time.getMilliseconds();
            var second = time.getSeconds();
            var minute = time.getMinutes();
            var hour = time.getHours() % 12;
            var increase = 1;
            var lastPosition = 30;
            var lastAngle = 155;
            var c = $this[0];
            var cxt = c.getContext("2d");
            var initDraw = function () {
                setInterval(beginDraw, options.speed);
            }
            var beginDraw = function () {
                time = new Date();
                milSeconds = time.getMilliseconds();
                second = time.getSeconds();
                minute = time.getMinutes();
                hour = time.getHours() % 12;
                //清理画布
                cxt.clearRect(0, 0, $this.attr("width"), $this.attr("height"));
                //画表盘
                drawPanel();
                drawMonth();
                //画耳朵
                drawEars();
                //画秒针
                drawSecondPoint();
                //画分针
                drawMinutePoint();
                //画时针
                drawHourPoint();
                //画眼睛
                drawEyes(cxt);
                //画钟摆
                drawPlummet();
            }
            var drawPanel = function () {
                //外盘面
                cxt.beginPath();
                cxt.strokeStyleStyle = colors[3];
                cxt.fillStyle = "#fff";
                cxt.lineWidth = 10;
                cxt.arc(options.ctX, options.ctY, options.radius, 0, Math.PI * 2, true);
                cxt.fill();
                cxt.stroke();
                //中间盘面
                cxt.beginPath();
                cxt.lineWidth = 1;
                cxt.arc(options.ctX, options.ctY, options.radius - 20, 0, Math.PI * 2, true);
                cxt.fillStyle = colors[13];
                cxt.fill();
                cxt.stroke();
                //圆点
                cxt.beginPath();
                cxt.arc(options.ctX, options.ctY, 20, 0, Math.PI * 2, true);
                cxt.fillStyle = colors[3];
                cxt.fill();
                cxt.stroke();
                //刻度
                cxt.beginPath();
                cxt.strokeStyle = colors[3];
                cxt.stroke();
                for (var i = 0; i < 60; i++) {
                    cxt.beginPath();
                    var x1 = options.ctX + (options.radius * Math.sin((i * 6 / 180) * Math.PI));
                    var y1 = options.ctY - (options.radius * Math.cos((i * 6 / 180) * Math.PI));
                    var x2;
                    var y2;
                    if (i % 5 != 0) {
                        x2 = options.ctX + ((options.radius - 10) * Math.sin((i * 6 / 180) * Math.PI));
                        y2 = options.ctY - ((options.radius - 10) * Math.cos((i * 6 / 180) * Math.PI));
                    }
                    else {
                        x2 = options.ctX + ((options.radius - 30) * Math.sin((i * 6 / 180) * Math.PI));
                        y2 = options.ctY - ((options.radius - 30) * Math.cos((i * 6 / 180) * Math.PI));
                    }
                    if (i % 15 == 0) {
                        cxt.beginPath();
                        cxt.fillStyle = colors[11];
                        cxt.arc(x1, y1, 8, 0, Math.PI * 2, true);
                        cxt.fill();
                    }
                    else {
                        cxt.moveTo(x1, y1);
                        cxt.lineTo(x2, y2);
                        cxt.stroke();
                    }
                }
            }
            var drawEars = function () {
                cxt.strokeStyle = colors[11];
                cxt.fillStyle = colors[11];
                var r = 30;
                cxt.beginPath();
                cxt.arc(options.ctX + options.radius * (Math.sin(45 / 180 * Math.PI)) + r, options.ctY - options.radius * (Math.cos(45 / 180 * Math.PI)) - r, r, 0, Math.PI * 2, true);
                cxt.fill();
                cxt.stroke();
                cxt.beginPath();
                cxt.arc(options.ctX - options.radius * (Math.sin(45 / 180 * Math.PI)) - r, options.ctY - options.radius * (Math.cos(45 / 180 * Math.PI)) - r, r, 0, Math.PI * 2, true);
                cxt.fill();
                cxt.stroke();
    
            }
            var drawMonth = function () {
                cxt.strokeStyle = colors[3];
                cxt.fillStyle = colors[6];
                var r = 80;
                cxt.beginPath();
                cxt.arc(options.ctX, options.ctY + r / 2, r, Math.PI / 4, Math.PI * 3 / 4, false);
                cxt.fill();
                cxt.stroke();
            }
            var drawSecondPoint = function () {
    
                for (var i = 0; i < 14; i++) {
                    cxt.beginPath();
                    cxt.strokeStyle = colors[i];
                    var x = options.ctX + ((options.radius - 40) * Math.sin((second * 6 / 180 - i / 360 + milSeconds * 6 / 180000) * Math.PI));
                    var y = options.ctY - ((options.radius - 40) * Math.cos((second * 6 / 180 - i / 360 + milSeconds * 6 / 180000) * Math.PI));
                    cxt.moveTo(options.ctX, options.ctY);
                    cxt.lineTo(x, y);
                    cxt.stroke();
                }
            }
            var drawMinutePoint = function () {
                for (var i = 0; i < 10; i++) {
                    cxt.beginPath();
                    cxt.strokeStyle = colors[i];
                    var x = options.ctX + ((options.radius - 80) * Math.sin((minute * 6 / 180 - i / 360 + (second / 1800)) * Math.PI));
                    var y = options.ctY - ((options.radius - 80) * Math.cos((minute * 6 / 180 - i / 360 + (second / 1800)) * Math.PI));
                    cxt.moveTo(options.ctX, options.ctY);
                    cxt.lineTo(x, y);
                    cxt.stroke();
                }
            }
            var drawHourPoint = function () {
                for (var i = 0; i < 6; i++) {
                    cxt.beginPath();
                    cxt.strokeStyle = colors[i];
                    var x = options.ctX + ((options.radius - 120) * Math.sin((hour * 30 / 180 - i / 360 + minute / 360) * Math.PI));
                    var y = options.ctY - ((options.radius - 120) * Math.cos((hour * 30 / 180 - i / 360 + minute / 360) * Math.PI));
                    cxt.moveTo(options.ctX, options.ctY);
                    cxt.lineTo(x, y);
                    cxt.stroke();
                }
            }
            var drawEyes = function () {
                cxt.beginPath();
                if (lastPosition + increase > 80) {
                    increase = -1;
                } else if (lastPosition + increase < 30) {
                    increase = 1;
                }
                lastPosition += increase;
                cxt.arc(options.ctX - lastPosition, options.ctY - 80, 20, 0, Math.PI * 2, true);
                cxt.arc(options.ctX + lastPosition, options.ctY - 80, 20, 0, Math.PI * 2, true);
                cxt.fillStyle = colors[11];
                cxt.fill();
            }
            var drawPlummet = function () {
                if (lastAngle + increase > 205) {
                    increase = -1;
                } else if (lastAngle + increase < 155) {
                    increase = 1;
                }
                lastAngle += increase;
                cxt.beginPath();
                cxt.strokeStyle = colors[11];
                cxt.fillStyle = colors[11];
                cxt.moveTo(options.ctX, options.ctY + options.radius);
                cxt.lineTo(options.ctX + Math.sin(lastAngle / 180 * Math.PI) * options.plummetLength, options.ctY + options.radius - Math.cos(lastAngle / 180 * Math.PI) * options.plummetLength);
                cxt.stroke();
                cxt.beginPath();
                cxt.arc(options.ctX + Math.sin(lastAngle / 180 * Math.PI) * options.plummetLength, options.ctY + options.radius - Math.cos(lastAngle / 180 * Math.PI) * options.plummetLength, 30, 0, Math.PI * 2, true);
                cxt.fill();
                cxt.stroke();
            }
            return this.each(function () {
                initDraw();
            });
        };
    }
    )(jQuery);
    View Code

    使用:

    <!DOCTYPE html">
    <html>
    <head>
        <title></title>
        <style>
        #myCanvas
        {
            
            border: 1px solid #c3c3c3; 
            background-color:#ddd;
        }
        </style>
    </head>
    <body>
        <canvas width="1400" height="800" id="myCanvas">
    Your browser does not support the canvas element.
    </canvas>
    <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
    <script src="jquery.clock.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            $('#myCanvas').clock();
        });
    
    </script>
    </body>
    </html>
    View Code

     

    超简单,所以思路就不多写了~~

    每次刷新都是全幅重画的,本人比较懒~

    有些固定位置的部位(如耳朵,嘴巴)为了避免每次重绘都要重新计算位置,用circular对象保存

    //用于保存各个部位信息,不用每次重绘都重新计算
        var circular = function (x, y, r, sAngle, eAngle, counterclockwise) {
            this.x = x;
            this.y = y;
            this.r = r;
            this.sAngle = sAngle;
            this.eAngle = eAngle;
            this.counterclockwise = counterclockwise;
        }
    View Code

    为CanvasRenderingContext2D添加方法arc2 使其支持自己建的circular对象,这样在每次画圆的时候就不用写那么一大串了~

    //为CanvasRenderingContext2D添加方法arc2 使其支持circular对象
        CanvasRenderingContext2D.prototype.arc2 = function (circular) {
            this.arc(circular.x, circular.y, circular.r, circular.sAngle, circular.eAngle, circular.counterclockwise);
        }
    View Code

    添加拖拽(耳朵,嘴巴)

    var circulars = [];
            var activePart;
            var isActive = false;
            var xDistance;
            var yDistance;
            //鼠标按下位置
            $this.mousedown(function (e) {
                var x = e.clientX;
                var y = e.clientY;
                cxt.beginPath();
                $.each(circulars, function (index, circular) {
                    if (circular) {
                        cxt.arc2(circular)
                        if (cxt.isPointInPath(x, y)) {
                            activePart = circular;
                            xDistance = x - circular.x;
                            yDistance = y - circular.y;
                            isActive = true;
                            return false;
                        }
                    }
                })
    
            });
            //鼠标弹起位置
            $this.mouseup(function (e) {
                var x = e.clientX;
                var y = e.clientY;
                if (activePart && isActive) {
                    activePart.x = x - xDistance;
                    activePart.y = y - yDistance;
                    isActive = false;
                }
            });
    View Code

    应该有许多不合理的地方,比如指针想实现那种“幻影”的效果,但是没找到好的方法,就一个循环画了14条渐变线条~~ 比较挫~

    for (var i = 0; i < 14; i++) {
                    cxt.beginPath();
                    cxt.strokeStyle = colors[i];
                    var x = options.ctX + ((options.radius - 40) * Math.sin((second * 6 / 180 - i / 360 + milSeconds * 6 / 180000) * Math.PI));
                    var y = options.ctY - ((options.radius - 40) * Math.cos((second * 6 / 180 - i / 360 + milSeconds * 6 / 180000) * Math.PI));
                    cxt.moveTo(options.ctX, options.ctY);
                    cxt.lineTo(x, y);
                    cxt.stroke();
                }
    View Code

    嘴巴就是一个小半圆~~

    var drawMonth = function () {
                cxt.strokeStyle = colors[3];
                cxt.fillStyle = colors[6];
                var r = 80;
                cxt.beginPath();
                if (!circulars[2]) {
                    circulars[2] = new circular(options.ctX, options.ctY + r / 2, r, Math.PI / 4, Math.PI * 3 / 4, false);
                }
                cxt.arc2(circulars[2]);
                cxt.fill();
                cxt.stroke();
            }
    View Code

     

    耳朵,鼻子,钟摆。。。都是圆形 o(╯□╰)o~

    var drawEars = function () {
                cxt.strokeStyle = colors[11];
                cxt.fillStyle = colors[11];
                var r = 30;
                cxt.beginPath();
                if (!circulars[1]) {
                    circulars[1] = new circular(options.ctX + options.radius * (Math.sin(45 / 180 * Math.PI)) + r, options.ctY - options.radius * (Math.cos(45 / 180 * Math.PI)) - r, r, 0, Math.PI * 2, true);
                }
                cxt.arc2(circulars[1]);
                cxt.fill();
                cxt.stroke();
                cxt.beginPath();
                if (!circulars[0]) {
                    circulars[0] = new circular(options.ctX - options.radius * (Math.sin(45 / 180 * Math.PI)) - r, options.ctY - options.radius * (Math.cos(45 / 180 * Math.PI)) - r, r, 0, Math.PI * 2, true);
                }
                cxt.arc2(circulars[0]);
                cxt.fill();
                cxt.stroke();
            }
    View Code

     

    钟摆和眼睛是随刷新平率做往返运动的,位置和时间无关~~  这个大概不合适 不过懒得改~

    var drawPlummet = function () {
                if (lastAngle + increase > 205) {
                    increase = -1;
                } else if (lastAngle + increase < 155) {
                    increase = 1;
                }
                lastAngle += increase;
                cxt.beginPath();
                cxt.strokeStyle = colors[11];
                cxt.fillStyle = colors[11];
                cxt.moveTo(options.ctX, options.ctY + options.radius);
                cxt.lineTo(options.ctX + Math.sin(lastAngle / 180 * Math.PI) * options.plummetLength, options.ctY + options.radius - Math.cos(lastAngle / 180 * Math.PI) * options.plummetLength);
                cxt.stroke();
                cxt.beginPath();
                cxt.arc(options.ctX + Math.sin(lastAngle / 180 * Math.PI) * options.plummetLength, options.ctY + options.radius - Math.cos(lastAngle / 180 * Math.PI) * options.plummetLength, 30, 0, Math.PI * 2, true);
                cxt.fill();
                cxt.stroke();
            }
    View Code

    求喷 求教育 求鄙视 就是无聊~

     

     

  • 相关阅读:
    Proj THUDBFuzz Paper Reading: PMFuzz: Test Case Generation for Persistent Memory Programs
    入围 WF 后训练记
    算法竞赛历程
    2021 多校 杭电 第十场
    2021 多校 杭电 第九场
    2021 多校 牛客 第十场
    2021 多校 牛客 第九场
    2021 多校 杭电 第八场
    2021 多校 杭电 第六场
    2021 多校 杭电 第七场
  • 原文地址:https://www.cnblogs.com/ziyeyimeng/p/3642376.html
Copyright © 2011-2022 走看看