如何实现*object*来改进我的时钟示例javascript程序

F. *_*uri 7 javascript object javascript-objects

这项工作的目标是理解和发挥我听过的一些对象概念的含义.

关于赏金

有很多不同的方法/方法来做到这一点.

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

我怎么能做更有用的事情?

一开始:

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

我用javascript和svg写了一个小样本/ demo:

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();
Run Code Online (Sandbox Code Playgroud)
#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
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

(最初发布在jsfiddle)因为我对javascript jquery和/或mootools不是很有经验,我想知道是否存在一些更简单的方法,可能是以不同的方式写这个.

如何使用jquery或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);
Run Code Online (Sandbox Code Playgroud)

如何客观化这段代码?(即使它可能是一件好事)......

所有样品都使用面向对象,特定库,或者欢迎使用!

F. *_*uri 2

编辑自赏金:转到底部!

第一个答案

在阅读了pete(非常感谢!你给了我很好的研究方法)和SoonDead(也感谢第一步转换)的第一条评论后,我环顾四周, jquerymootools代码,最后我选择了mootools为了减少我的代码,因为mootools让我提交一个arrayforobject.get和一个hash(关联数组)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());
}());
Run Code Online (Sandbox Code Playgroud)
#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
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

好吧,现在我的新代码减少了 8 行,甚至始终可读。

这是一个步骤,但objectization意味着将其作为一个对象......目标是

  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);
}());
Run Code Online (Sandbox Code Playgroud)

如果所有部分都保持很小,我的clock就是一个真正的可重用对象(现在可以工作 4 次)。

该函数setTime必须一起计算所有手牌,因为每个值都包含其他值的一部分,但每个操作只能完成一次。

对于我的时钟, a是由固定 a和 变量Path定义的,Path.end 是指定的计算终点start pointlengthdirectiondirection

aHand是一个给定的SVG line,其原始的Path,以及一个可选标志指定在设置时,起点和终点都必须定位在相同的值(零长度线,圆形终止给出一个圆形点)。

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

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

更新2

我认为,这是现在的最终版本,其中对象很简单,使用了mootools(可能不是太多,欢迎评论),我的最终时钟可以多次使用来显示不同的时区。

(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);
}());
Run Code Online (Sandbox Code Playgroud)
(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);
}());
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)

新的尝试完全重写

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

"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


Copyright Info

© Copyright 2013-2021 admin@qa.1r1g.com

如未特别说明,本网站的内容使用如下协议:
Creative Commons Atution-NonCommercial-ShareAlike 4.0 International license
.

用以下方式浏览
回到顶部