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

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

     

     

  • 相关阅读:
    iOS开发系列-Category
    OC开发系列-内存管理
    OC开发系列-@property和@synthesize
    OC开发系列-成员变量的作用域
    OC开发系列-类与对象
    MySQL
    JavaWeb
    POJ1845-Sumdiv大数约数和
    poj1159 Palindrome 区间DP
    poj 2955 Brackets 区间DP
  • 原文地址:https://www.cnblogs.com/ziyeyimeng/p/3642376.html
Copyright © 2011-2022 走看看