如何实现* object *来改善我的时钟示例javascript程序 [英] How to implement *object* for improve my clock sample javascript program

查看:50
本文介绍了如何实现* object *来改善我的时钟示例javascript程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这项工作的目标是理解和理解我所听到的某些 object 概念的含义.

The goal of this work is to understand and play with meaning of some object concept I've heard arround.

有很多不同的方法来实现此目的.

There is a lot of different way / approach to do this.

我的尝试并不是很干净:要添加第二个时钟和另一个时区,我必须编辑3个不同的时钟的地方.这不好(请参阅答案底部).

My tries are not really clean: for adding a 2st clock, with another timezone, I have to edit 3 different places. This is not well (see at bottom of the answer).

我该怎么做有用的?

后期最初的问题是关于在jquery和mootools之间进行选择,现在已经确定了;目标是通过使用 mootools 来改善这一点.

post-edit: the initial question was about choosing between jquery and mootools, now choice as been made; the goal is to improve this, with the use of mootools.

我写了一些样本/演示来玩javascript和svg:

There is a little sample/demo i wrote to play with javascript and svg:

var cx  =128;
var cy  =128;
var slen=120;
var mlen=116;
var hlen= 80;
var selem;
var melem;
var helem;
function setvars() {
    selem=document.getElementById("seconds");
    melem=document.getElementById("minutes");
    helem=document.getElementById("hours");
    drawtime();
};
function drawtime() {
    var now=new Date();
    var nows=now.getTime()%60000;
    var nowm=now.getMinutes()*1.0+1.0*nows/60000;
    var nowh=now.getHours()*1.0+1.0*nowm/60;
    var sposx=cx + slen * Math.sin( nows / 30000 * Math.PI );
    var sposy=cy - slen * Math.cos( nows / 30000 * Math.PI );
    var mposx=cx + mlen * Math.sin( nowm / 30 * Math.PI );
    var mposy=cy - mlen * Math.cos( nowm / 30 * Math.PI );
    var hposx=cx + hlen * Math.sin( nowh / 6 * Math.PI );
    var hposy=cy - hlen * Math.cos( nowh / 6 * Math.PI );
    selem.setAttribute("x1",sposx);
    selem.setAttribute("y1",sposy);
    selem.setAttribute("x2",sposx);
    selem.setAttribute("y2",sposy);
    melem.setAttribute("x2",mposx);
    melem.setAttribute("y2",mposy);
    helem.setAttribute("x2",hposx);
    helem.setAttribute("y2",hposy);
    window.setTimeout(drawtime,80)
};
setvars();

#box1    { stroke: black; }
#minutes { stroke: #2266AA; }
#hours   { stroke: #3388CC; }
#seconds { stroke: #CCCC22; }
line,circle {
    opacity:0.65;
    fill:none;
    stroke-width:8;
    stroke-linecap:round;
    stroke-linejoin:round;
    marker:none;
    stroke-miterlimit:4;
    stroke-dasharray:none;
    stroke-opacity:1;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}

<svg xmlns="http://www.w3.org/2000/svg" id="svg2" width="100%"
     height="100%" viewBox="0 0 900 256" version="1.0">
    <title  id="title1">Clock</title>
    <circle id="box1"    cy="128" cx="128"  r="124" />
    <line   id="hours"   x1="128" y1="128" x2="128"  y2="48" />
    <line   id="minutes" x1="128" y1="128" x2="244" y2="128" />
    <line   id="seconds" x1="128"   y1="8" x2="128"   y2="8" />
</svg>

(最初发布于 jsfiddle ),因为我对javascript jquery和/不太熟悉或mootools,我想知道是否存在一些更简单的方法,也许是用其他方式编写的.

(Originaly posted at jsfiddle) as I'm not very experienced with javascript jquery and/or mootools, I would like to know if some simplier methods exists, maybe in writting this in a different manner.

如何使用jquery或mootools围绕固定中心进行简单旋转:

how to do simple rotation about a fixed center, using jquery or mootools:

var hposx=cx + hlen * Math.sin( nowh / 6 * Math.PI );
var hposy=cy - hlen * Math.cos( nowh / 6 * Math.PI );
helem.setAttribute("x2",hposx);
helem.setAttribute("y2",hposy);

如何物镜化此代码? (即使这可能是一件好事)...

how to objectize this code? (if even it could be a good thing)...

欢迎使用面向对象,特定库或其他所有示例!

All samples using object orientation, specific library, or else are welcome!

推荐答案

经赏金转到此底部!

第一个答案

在阅读了 pete (非常感谢!给我很好的研究方法)和 SoonDead (感谢转换的第一步)的第一条评论之后, 我浏览了一下 jquery mootools 代码,最后我选择了 mootools 来减少代码,例如 mootools 让我为object.get提交array,为objet.set提交hash(关联数组):

Edited from bounty: Go to bottom of this!

First answer

After reading first comments from pete (many thanks! you give me good ways of research) and SoonDead (thanks too for the first step of conversion), I've a little look around, jquery and mootools code and finally i've choose mootools to reduce my code, as mootools let me submit an array for object.get and a hash (associative array) for objet.set:

(function () {
    "use strict";
    var Point = function(x,y) {
         this.x=x;
         this.y=y;
    };
    var Path = function(center,length,both) {
        this.center = center;
        this.length = length;
        this.both   = both;
        this.end    = function(alpha) {
            var retx = 1.0*this.center.x +
                this.length*Math.sin(alpha);
            var rety = 1.0*this.center.y -
                this.length*Math.cos(alpha);
            if (typeof(this.both)!=='undefined')
              return { x1:retx, x2:retx, y1:rety, y2:rety }
            else return { x2:retx, y2:rety };
        };
    };
    var Hand = function(svgline,both) {
        this.elem = document.id(svgline);
        var p     = this.elem.get(['x1','y1','x2','y2']);
        this.path = new Path (
          new Point(p.x1,p.y1),Math.sqrt(
            Math.pow(1.0*p.x2-1.0*p.x1,2) +
            Math.pow(1.0*p.y2-1.0*p.y1,2)) ,both);
        this.setPos = function(angle) {
            this.elem.set(this.path.end(angle));
        };
    };
    var Clock = function(hour,minute,second,refresh) {
        this.hour    = new Hand(hour);
        this.minute  = new Hand(minute);
        this.second  = new Hand(second,true);
        this.refresh = refresh;
        this.setTime = function(timePos) {
            var self= this;
            var tps = 1.0*timePos.getTime() % 60000;
            var tpm = timePos.getMinutes()*1.0 +
                1.0* tps/60000;
            var tph = timePos.getHours()*1.0   + 1.0* tpm/60;
            this.second.setPos(tps / 30000 * Math.PI);
            this.minute.setPos(tpm / 30    * Math.PI);
            this.hour  .setPos(tph / 6     * Math.PI);
            setTimeout(function() {
              self.setTime(new Date())},this.refresh) };
    };
    var clock=new Clock('hours','minutes','seconds',120);
    clock.setTime(new Date());
}());

#box1    { stroke: black; fill:#ccc }
#minutes { stroke: #2288AA; }
#hours   { stroke: #3388CC; }
#seconds { stroke: #CCCC22; }
line,circle {
    opacity:0.65;
    fill:none;
    stroke-width:8;
    stroke-linecap:round;
    stroke-linejoin:round;
    marker:none;
    stroke-miterlimit:4;
    stroke-dasharray:none;
    stroke-opacity:1;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}

<script
  src="http://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-nocompat.js"
  ></script>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2" width="100%"
     height="100%" viewBox="0 0 900 256" version="1.0">
    <title  id="title1">Clock</title>
    <circle id="box1"    cy="128" cx="128"  r="124" />
    <line   id="hours"   x1="128" y1="128" x2="128"  y2="48" />
    <line   id="minutes" x1="128" y1="128" x2="244" y2="128" />
    <line   id="seconds" x1="128" y1="128" x2="128"   y2="8" />
</svg>

好吧,现在我的新代码缩小了8行,甚至始终可读.

Well, now my new code is 8 lines smaller and even alway readable.

这是一个步骤,但objectization表示将其作为对象 ... 以

This is a step, but objectization mean make it as an object... With the goals of

  1. 保持可靠
  2. 保持高效(不要两次进行无用的操作或相同的操作)
  3. 使其可重复使用(作为一个对象,将所有固定变量排除在外...)

一个个人中间结果

但是现在代码如下:

(function () {
    "use strict";
    var Point = function(x,y) {
         this.x=x;
         this.y=y;
    };
    var Path = function(center,length,both) {
        this.center = center;
        this.length = length;
        this.both   = both;
        this.end    = function(alpha) {
            var retx=1.0*this.center.x+this.length*Math.sin(alpha);
            var rety=1.0*this.center.y-this.length*Math.cos(alpha);
            if (typeof(this.both)!=='undefined')
                 return { x1:retx, x2:retx, y1:rety, y2:rety }
            else return { x2:retx, y2:rety };
        };
    };
    var Hand = function(svgline,both) {
        this.elem   = document.id(svgline);
        var p=this.elem.get(['x1','y1','x2','y2']);
        this.path   = new Path ( new Point(p.x1,p.y1),
                                Math.sqrt(Math.pow(1.0*p.x2-1.0*p.x1,2)+
                                          Math.pow(1.0*p.y2-1.0*p.y1,2)),
                                 both);
        this.setPos = function(angle) {
            this.elem.set(this.path.end(angle));
        };
    };
    var Clock = function(hour,minute,second,refresh) {
        this.hour    = new Hand(hour);
        this.minute  = new Hand(minute);
        this.second  = new Hand(second,true);
        this.setTime = function(timePos) {
            var self= this;
            var tps = 1.0*timePos.getTime() % 60000;
            var tpm = timePos.getMinutes()*1.0 + 1.0* tps/60000;
            var tph = timePos.getHours()*1.0   + 1.0* tpm/60;
            this.second.setPos(tps / 30000 * Math.PI);
            this.minute.setPos(tpm / 30    * Math.PI);
            this.hour  .setPos(tph / 6     * Math.PI);
        };
    };
    var RefreshLoop = function(refresh) {
        var newdate=new Date();
        clock1.setTime(newdate);
        newdate=newdate.getTime()+newdate.getTimezoneOffset()*60000;
        clock2.setTime(new Date(newdate));
        clock3.setTime(new Date(newdate+20700000));
        clock4.setTime(new Date(newdate+28800000));
    };
    var clock1=new Clock('hours','minutes','seconds',120);
    var clock2=new Clock('hours2','minutes2','seconds2',120);
    var clock3=new Clock('hours3','minutes3','seconds3',120);
    var clock4=new Clock('hours4','minutes4','seconds4',120);
    RefreshLoop.periodical(500);
}());

在所有零件都很小的地方,我的clock是一个真正的可重用对象(现在工作了4次).

Where all part stay small, my clock is a real reuseable object (now work 4 times).

函数setTime必须作为每个值一起计算所有手 保留其他部分的一部分,但是每个操作只能执行一次.

The function setTime have to compute all hands together as each value hold a portion of other, but each operation have to be done one time only.

对于我的时钟,Path由固定的start point固定的length和变量direction定义,Path.end是指定的direction

For my clock, a Path is defined by a fixed start point a fixed length and a variable direction, the Path.end is the computed end point for a specified direction

Hand是给定的SVG line,带有其原始的Path和一个可选标志 尤其是在设置时,必须同时定位起点和终点 值相同(零长度线,带有圆形终止点的圆形点).

And a Hand is a given SVG line, with his original Path, and a optional flag speficying that on setting, both start point and end point have to be positionned at same values (zero length line, with round termination give a round point).

(备注(错误?):由于在SVG中定义了每个元素,并且Path是根据Path两端之间的距离计算得出的,因此必须绘制seconds路径首先将[x1,y1]置于时钟中心,! = [x2,y2]!)

(Remark (bug?): As each elements are defined in the SVG and Path.length is computed from the distance between each end of a Path, the seconds path have to be drawn first with [x1,y1] in the center of the clock, ! = [x2,y2]! )

希望有些人想纠正/改善/讨论我的objectization ...

In the hope some want to correct/improve/discuss my objectization...

UPDATE2

我认为,现在是最终版本,其中对象很简单,使用了mootools(可能不算太多,欢迎表示),并且我的最终时钟可能会用很多时间来显示不同的时区.

I think, this is now the final version, where object are simple, mootools is used (maybe not too much, remarks welcomes) and my final clock could be used many time to display different timezome.

(function () {
    "use strict";
    var Point = function(x,y) {
         this.x=x;
         this.y=y;
    };
    var Path = function(center,length,both) {
        this.center = center;
        this.length = length;
        this.both   = both;
        this.end    = function(alpha) {
            var retx=1.0*this.center.x+this.length*Math.sin(alpha);
            var rety=1.0*this.center.y-this.length*Math.cos(alpha);
            if (typeof(this.both)!=='undefined')
                 return { x1:retx, x2:retx, y1:rety, y2:rety }
            else return { x2:retx, y2:rety };
        };
    };
    var Hand = function(svgline,both) {
        this.elem   = document.id(svgline);
        var p=this.elem.get(['x1','y1','x2','y2']);
        this.path   = new Path ( new Point(p.x1,p.y1),
                                Math.sqrt(Math.pow(1.0*p.x2-1.0*p.x1,2)+
                                          Math.pow(1.0*p.y2-1.0*p.y1,2)),
                                 both);
        this.setPos = function(angle) {
            this.elem.set(this.path.end(angle));
        };
    };
    var Clock = function(hour,minute,second,refresh) {
        this.hour    = new Hand(hour);
        this.minute  = new Hand(minute);
        this.second  = new Hand(second,true);
        this.setTime = function(timePos) {
            var self= this;
            var tps = 1.0*timePos.getTime() % 60000;
            var tpm = timePos.getMinutes()*1.0 + 1.0* tps/60000;
            var tph = timePos.getHours()*1.0 + 1.0* tpm/60;
            this.second.setPos(tps / 30000 * Math.PI);
            this.minute.setPos(tpm / 30    * Math.PI);
            this.hour  .setPos(tph / 6     * Math.PI);
        };
    };
    var RefreshLoop = function(refresh) {
        var newdate=new Date();
        clock1.setTime(newdate);
        newdate=newdate.getTime()+newdate.getTimezoneOffset()*60000;
        clock2.setTime(new Date(newdate));
        clock3.setTime(new Date(newdate+20700000));
    };
    var clock1=new Clock('hours','minutes','seconds',120);
    var clock2=new Clock('hours2','minutes2','seconds2',120);
    var clock3=new Clock('hours3','minutes3','seconds3',120);
    RefreshLoop.periodical(500);
}());

circle   { stroke: black; }
.startbg { stop-color: #eeeeee; }
.endbg   { stop-color: #777777; }
.box     { fill:url(#grad0); }
.box1    { fill:url(#grad1); }
.box2    { fill:url(#grad2); }
.box3    { fill:url(#grad3); }
.label   { stroke: #424242;fill:#eee;stroke-width:1; }
.minutes { stroke: #2288AA; }
.hours   { stroke: #3388CC; }
.seconds { stroke: #CCCC22; }
line,circle,rect {
    opacity:0.65;
    fill:none;
    stroke-width:8;
    stroke-linecap:round;
    stroke-linejoin:round;
    marker:none;
    stroke-miterlimit:4;
    stroke-dasharray:none;
    stroke-opacity:1;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}
text {
    font-size:15px;
    font-style:normal;
    font-variant:normal;
    font-weight:normal;
    font-stretch:normal;
    text-align:center;
    line-height:100%;
    writing-mode:lr-tb;
    text-anchor:middle;
    fill:#000000;fill-opacity:.7;
    stroke:none;
    font-family:Nimbus Sans L;
}

<script
  src="http://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-nocompat.js"
  ></script>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2" width="100%"
    height="100%" viewBox="-1 -1 900 555" version="1.0"><defs>
    <linearGradient gradientUnits="userSpaceOnUse" id="g0"><stop
        class="startbg" /><stop class="endbg" offset="1" /></linearGradient>
    <linearGradient id="grad0" x1="-1"  y1="-1" x2="256" y2="277" xlink:href="#g0" />
    <linearGradient id="grad1" x1="256" y1="-1" x2="515" y2="277" xlink:href="#g0" />
    <linearGradient id="grad2" x1="512" y1="-1" x2="771" y2="277" xlink:href="#g0" />
    </defs>
    <circle class="box"   id="box1" cy="128" cx="128" r="124" />
    <line class="hours"   id="hours" x1="128" y1="128" x2="128" y2="48" />
    <line class="minutes" id="minutes" x1="128" y1="128" x2="244" y2="128" />
    <line class="seconds" id="seconds" x1="128" y1="128" x2="128" y2="8" />
    <rect class="label"   x="16"  y="256" width="224" height="20" />
    <text x="0" y="0" xml:space="preserve">
        <tspan x="128" y="271">Local time</tspan></text>

    <circle class="box1" id="box2" cy="128" cx="385" r="124" />
    <line class="hours" id="hours2" x1="385" y1="128" x2="385" y2="48" />
    <line class="minutes" id="minutes2" x1="385" y1="128" x2="501" y2="128" />
    <line class="seconds" id="seconds2" x1="385" y1="128" x2="385" y2="8" />
    <rect class="label" x="273" y="256" width="224" height="20" />
    <text x="0" y="0" xml:space="preserve">
        <tspan x="385" y="271">Universal Time Clock</tspan></text>

    <circle class="box2" id="box3" cy="128" cx="642" r="124" />
    <line class="hours" id="hours3" x1="642" y1="128" x2="642" y2="48" />
    <line class="minutes" id="minutes3" x1="642" y1="128" x2="758" y2="128" />
    <line class="seconds" id="seconds3" x1="642" y1="128" x2="642" y2="8" />
    <rect class="label" x="530"  y="256" width="224" height="20" />
    <text x="0" y="0" xml:space="preserve">
        <tspan x="642" y="271">Asia/Katmandu</tspan></text>
</svg>

这使用 momentjs 来获取国际信息,但没有其他库.

This use momentjs for intl infos, but no other lib.

"use strict";
var gv={ clockcount: 1,
         svg:'http://www.w3.org/2000/svg',
         xlnk:'http://www.w3.org/1999/xlink',
         tzlist:['Local'].concat(moment.tz.names()),
         vbox:document.getElementById('svg').getAttribute("viewBox").split(" ")
       };
function mousepos(event) {
    var minxy=innerWidth;
    if (minxy > innerHeight) minxy=innerHeight;
    return {
        x:((event.clientX-(innerWidth-minxy)/2)/minxy)*(gv.vbox[2]-gv.vbox[0]),
        y:((event.clientY-(innerHeight-minxy)/2)/minxy)*(gv.vbox[3]-gv.vbox[1])
    };
};

function myClock(cx,cy,r,tz) {
    var clock=this, elem;
    this.cx=128;
    if (typeof(cx)!=='undefined') this.cx=cx;
    this.cy=128;
    if (typeof(cy)!=='undefined') this.cy=cy;
    this.r=100;
    if (typeof(r)!=='undefined') this.r=r;
    this.tz=new Date().getTimezoneOffset();
    this.setTz=function(tz) {
        if (typeof(tz)!=='undefined') {
            this.label=tz;
            if (tz!=="Local") {
                var ndte=new Date();
                var tzoff=moment(ndte).tz(tz).format('HH mm ss').split(' ');
                var tznow=Math.floor(ndte/1000)%86400;
                this.tz=(tznow-(tzoff[0]*3600+tzoff[1]*60+1*tzoff[2]))/60;
            } else this.tz=new Date().getTimezoneOffset();
        } else this.label="Local";
    };
    this.setTz(tz);
    this.clkid=gv.clockcount++;
    this.floor=0;
    this.toggleFloor=function(e) { e.preventDefault();
                                   clock.floor=1-clock.floor; };
    this.toggleSecDraw=function(e) { e.preventDefault();
                                     clock.secdraw=1-clock.secdraw; };
    this.wheel=function(e) { e.preventDefault();
                             var sens=1;
                             if (typeof(e.detail)!=='undefined') {
                                 if ( 0 > e.detail ) { sens=-1; }
                             } else if ( 0 > e.wheelDelta ) { sens=-1; };
                             var cidx=gv.tzlist.indexOf(clock.label)*1+1*sens;
                             if (cidx < 0) cidx=gv.tzlist.length-1;
                             if (cidx >= gv.tzlist.length) cidx=0;
                             clock.setTz(gv.tzlist[cidx]);
                             clock.draw=0; };
    this.moused = function (evt) {
        evt.preventDefault(); var m=mousepos(evt);
        if ((clock.r/2 > Math.pow(Math.pow(Math.abs(clock.cx-m.x),2)+
                                  Math.pow(Math.abs(clock.cy-m.y),2),.5))) {
            clock.box.addEventListener("mousemove", clock.mousem, true);
        } else {
            clock.box.addEventListener("mousemove", clock.mouser, true);
        };
        clock.box.addEventListener("mouseup", clock.mouseu, true);
    };
    this.mouseu = function(evt) {
        evt.preventDefault(); clock.draw=0;
        clock.box.removeEventListener("mousemove", clock.mouser, true);
        clock.box.removeEventListener("mousemove", clock.mousem, true);
        clock.box.removeEventListener("mouseup", clock.mouseu, true);
    };
    this.mouser = function(evt) {
        evt.preventDefault(); clock.draw=0;
        var m=mousepos(evt);
        clock.r=1.25*Math.pow(Math.pow(Math.abs(clock.cx-m.x),2)+
                              Math.pow(Math.abs(clock.cy-m.y),2),.5);
    };
    this.mousem = function(evt) { evt.preventDefault(); clock.draw=0;
        var m=mousepos(evt); clock.cx=m.x; clock.cy=m.y; };
    this.drop = function(evt) { evt.preventDefault();clearInterval(clock.loop);
                                clock.box.remove(); };
    elem=document.createElementNS(gv.svg,'g');             
    elem.setAttribute('id','box'+this.clkid);
    document.getElementById('myClock').appendChild(elem);
    this.box=document.getElementById('box'+this.clkid);
    this.box.addEventListener("mousedown",     this.moused ,true);
    this.box.addEventListener("click",         this.toggleSecDraw,true);
    this.box.addEventListener("dblclick",      this.toggleFloor ,true);
    this.box.addEventListener('mousewheel',    this.wheel, true);
    this.box.addEventListener('DOMMouseScroll',this.wheel, true);
    this.box.addEventListener('contextmenu',   this.drop, true);
    
    elem=document.createElementNS(gv.svg,'circle');
    this.fill='fill: url(#g'+this.clkid+');'+
        'stroke: url(#gb'+this.clkid+');';
    elem.setAttribute('style',this.fill);
    elem.setAttribute('id','crc'+this.clkid);
    this.box.appendChild(elem);
    this.crc=document.getElementById('crc'+this.clkid);
    
    this.ticks=[];
    for (var i=0;i<60;i++) {
        elem=document.createElementNS(gv.svg,'line');
        elem.setAttribute('class','ticks');
        elem.setAttribute('id','t'+i+'c'+this.clkid);
        this.box.appendChild(elem);
        this.ticks.push(document.getElementById('t'+i+'c'+this.clkid));
    };
    
    elem=document.createElementNS(gv.svg,'rect');
    elem.setAttribute('class','label');
    elem.setAttribute('id','r'+this.clkid);
    this.box.appendChild(elem);
    this.rct=document.getElementById('r'+this.clkid);
    
    elem=document.createElementNS(gv.svg,'text');
    elem.setAttribute('id','x'+this.clkid);
    this.box.appendChild(elem);
    this.tbx=document.getElementById('x'+this.clkid);
    
    elem=document.createElementNS(gv.svg,'tspan');
    elem.setAttribute('id','t'+this.clkid);
    this.tbx.appendChild(elem);
    this.txt=document.getElementById('t'+this.clkid);

    elem=document.createElementNS(gv.svg,'line');
    elem.setAttribute('id','hr'+this.clkid);
    elem.setAttribute('class','hours');
    this.box.appendChild(elem);
    this.hhr=document.getElementById('hr'+this.clkid);

    elem=document.createElementNS(gv.svg,'line');
    elem.setAttribute('id','mn'+this.clkid);
    elem.setAttribute('class','minutes');
    this.box.appendChild(elem);
    this.hmn=document.getElementById('mn'+this.clkid);

    elem=document.createElementNS(gv.svg,'line'); 
    elem.setAttribute('id','sc'+this.clkid);
    elem.setAttribute('class','seconds');
    this.box.appendChild(elem);
    this.hsc=document.getElementById('sc'+this.clkid);
    
    elem=document.createElementNS(gv.svg,'linearGradient');
    elem.setAttribute('id','g'+this.clkid);
    elem.setAttributeNS(gv.xlnk,'xlink:href','#g0');
    document.getElementById('defs').appendChild(elem);
    this.deg=document.getElementById('g'+this.clkid);
    elem=document.createElementNS(gv.svg,'linearGradient');
    elem.setAttribute('id','gb'+this.clkid);
    elem.setAttributeNS(gv.xlnk,'xlink:href','#g0');
    document.getElementById('defs').appendChild(elem);
    this.dgb=document.getElementById('gb'+this.clkid);

    this.getTZ=function() { return this.tz; };
    this.setTZ=function(tz) { this.tz=tz; };
    this.draw=0;
    this.secdraw=1;
    this.adjust=function() {
        if (clock.draw!==1) {
            clock.crc.setAttribute('style','stroke-width:'+.03*clock.r+";"+
                                  clock.fill);
            clock.hhr.setAttribute('style','stroke-width:'+.11*clock.r);
            clock.hmn.setAttribute('style','stroke-width:'+.075*clock.r);
            clock.hsc.setAttribute('style','stroke-width:'+
                                  (clock.secdraw==1?.03:.09)*clock.r);
            clock.crc.setAttribute('cx',clock.cx);
            clock.crc.setAttribute('cy',clock.cy);
            clock.crc.setAttribute('r',clock.r);
            clock.rct.setAttribute('height',.2*clock.r);
            clock.rct.setAttribute('x',clock.cx-.9*clock.r);
            clock.rct.setAttribute('y',clock.cy*1+1.1*clock.r);
            clock.txt.innerHTML=clock.label;
            clock.txt.setAttribute('x',clock.cx);
            clock.txt.setAttribute('y',clock.cy*1+1.25*clock.r);
            clock.txt.setAttribute('style','font-size: '+(.15*clock.r)+"px;");
            var w=clock.label.length*.1*clock.r+20.0;
            clock.rct.setAttribute('x',clock.cx-w/2);
            clock.rct.setAttribute('width',w);
            for (var i=0;i<60;i++) {
                var x=clock.cx*1+.925*clock.r*Math.sin(i/30*Math.PI);
                var y=clock.cy*1+.925*clock.r*Math.cos(i/30*Math.PI);
                clock.ticks[i].setAttribute('x1',x);
                clock.ticks[i].setAttribute('y1',y);
                clock.ticks[i].setAttribute('x2',x);
                clock.ticks[i].setAttribute('y2',y);
                clock.ticks[i].setAttribute('style','stroke-width:'+
                                            (i%5==0?.04:.02)*clock.r);
            };
            clock.hsc.setAttribute('x1',clock.cx);
            clock.hsc.setAttribute('y1',clock.cy);
            clock.hmn.setAttribute('x1',clock.cx);
            clock.hmn.setAttribute('y1',clock.cy);
            clock.hhr.setAttribute('x1',clock.cx);
            clock.hhr.setAttribute('y1',clock.cy);
            clock.deg.setAttribute('x1',clock.cx-1.1*clock.r);
            clock.deg.setAttribute('y1',clock.cy-1.1*clock.r);
            clock.deg.setAttribute('x2',clock.cx+1.1*clock.r);
            clock.deg.setAttribute('y2',clock.cy+1.1*clock.r);
            clock.dgb.setAttribute('x1',clock.cx+1.1*clock.r);
            clock.dgb.setAttribute('y1',clock.cy+1.1*clock.r);
            clock.dgb.setAttribute('x2',clock.cx-1.1*clock.r);
            clock.dgb.setAttribute('y2',clock.cy-1.1*clock.r);
            clock.draw=1;
        };
        var now=new Date()/1000.0-this.tz*60;
        if (this.floor==1) now=Math.floor(now);
        var x=this.cx+(this.secdraw==1?.975:.925)*
            this.r*Math.sin((now % 60)/30*Math.PI);
        var y=this.cy-(this.secdraw==1?.975:.925)*
            this.r*Math.cos((now % 60)/30*Math.PI);
        this.hsc.setAttribute('x2',x);
        this.hsc.setAttribute('y2',y);
        if (this.secdraw==0) {
            this.hsc.setAttribute('x1',x);
            this.hsc.setAttribute('y1',y);
        }
        if (this.floor==1) now=Math.floor(now/60)         
        else now=now/60;
        x=this.cx+.9*this.r*Math.sin((now %60)/30*Math.PI);
        y=this.cy-.9*this.r*Math.cos((now %60)/30*Math.PI);
        this.hmn.setAttribute('x2',x);
        this.hmn.setAttribute('y2',y);
        if (this.floor==1) now=Math.floor(now/60)         
        else now=now/60;
        x=this.cx+.7*this.r*Math.sin((now % 12)/6*Math.PI);
        y=this.cy-.7*this.r*Math.cos((now % 12)/6*Math.PI);
        this.hhr.setAttribute('x2',x);
        this.hhr.setAttribute('y2',y);
    };
    this.animate = function() {        clock.adjust(); };
    this.loop=setInterval(this.animate,66);
    
};

document.getElementById('svg').addEventListener('dblclick', function(e){ if (e.
 target.id!=='svg')return;var m=mousepos(e);new myClock(m.x,m.y,80,'Local'); });

var clocks=['UTC','Local','Asia/Kolkata'];
for (var i=0;i<3;i++) { new myClock( 90+170*i,90,80,clocks[i]); };

circle   { stroke: black; }
.startbg { stop-color: #CCC; }
.endbg   { stop-color: #222; }
.label   { stroke: #424242;fill:#eee;stroke-width:1; }
.minutes { stroke: #2288AA; }
.hours   { stroke: #3388CC; }
.seconds { stroke: #CCCC22; }
.ticks   { stroke: black; }
line,circle,rect,point {
    opacity:0.65;
    stroke-linecap:round;
    stroke-linejoin:round;
    marker:none;
    stroke-miterlimit:4;
    stroke-dasharray:none;
    stroke-opacity:1;
    visibility:visible;
    display:inline;
    overflow:visible;
    enable-background:accumulate
}
text {
    font-style:normal;
    font-variant:normal;
    font-weight:normal;
    font-stretch:normal;
    text-align:center;
    line-height:100%;
    writing-mode:lr-tb;
    text-anchor:middle;
    fill:#000000;fill-opacity:.7;
    stroke:none;
    font-family:Nimbus Sans L;
}

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/css" href="myClock2.css" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600" id="svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" >
   <defs id="defs">
     <linearGradient gradientUnits="userSpaceOnUse" id="g0"><stop
       class="startbg" /><stop class="endbg" offset="1" />
     </linearGradient></defs>
 <script type="text/ecmascript"
         xlink:href="http://momentjs.com/downloads/moment-with-locales.js" />
 <script type="text/ecmascript"
         xlink:href="http://momentjs.com/downloads/moment-timezone-with-data.js" />
 <title id="title">Clock object</title>
 <g id="myClock"></g>
 <script type="text/ecmascript" xlink:href="myClock2.js" />
 <script type="text/ecmascript">
</script>
</svg>

svg绘图上有3个 object 时钟,具有一些功能:

There is 3 object clock on a svg drawing, with some features:

鼠标命令:

  • 当鼠标悬停在时钟上

  • when mouse over a clock

  • 点击=>切换秒数:路径或点
  • 拖动中心=>移动时钟
  • 拖动边框=>调整时钟大小
  • 双击=>切换地板模式
  • 滚动鼠标滚轮=>更改时区
  • 右键单击(contextmenu)=>删除时钟
  • Click => toggle seconds: path or dot
  • Drag center => move clock
  • Drag border => resize clock
  • Double-click => toggle floor mode
  • Roll mouse wheel => change Timezone
  • Right click (contextmenu) => delete clock

当鼠标悬停在背景上时:

when mouse over the background:

  • 双击=>添加新时钟

这不是完美的,因为存在一些错误,大部分是通过width="100%" height="100%"进行的鼠标定位,我认为这是封闭片段的效果,但在这里无关紧要.

This is not perfect, as there are some bugs, mostly in mouse positionning with width="100%" height="100%", I think this is an effect of enclosed snippets, but that' not matter here.

您可以在我的网站上找到完整可用的 SVG图片

You could find a full useable SVG picture on my site

这篇关于如何实现* object *来改善我的时钟示例javascript程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆