source: Dev/branches/rest-dojo-ui/client/dojox/gfx/demos/clockWidget.html @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 9.6 KB
Line 
1<html>
2<head>
3<title>dojox.gfx: interactive analog clock</title>
4<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5<style type="text/css">
6        @import "../../../dojo/resources/dojo.css";
7        @import "../../../dijit/themes/dijit.css";
8        @import "../../../dijit/tests/css/dijitTests.css";
9</style>
10<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
11<script type="text/javascript">
12        dojo.require("dijit._Widget");
13        dojo.require("dijit._Templated");
14        dojo.require("dojox.gfx");
15        dojo.require("dojo.date.locale");
16        dojo.declare("demo.Clock",dijit._Widget,{
17               
18                time:"",
19               
20                img:"images/clock_face_black.jpg",
21               
22                postCreate:function(){
23                        this.inherited(arguments);
24                        if(!this.time){ this.current_time = new Date(); }else{
25                                this.current_time = this.time;
26                        }
27                        dojo.mixin(this,{
28                               
29                                diff_time: new Date(),
30                               
31                                hour_hand:null,
32                                hour_shadow:null,
33                                hour_shadow_shift:{dx: 2, dy: 2},
34
35                                minute_hand:null,
36                                minute_shadow:null,
37                                minute_shadow_shift:{dx: 3, dy: 3},
38                               
39                                second_hand:null,
40                                second_shadow:null,
41                                second_shadow_shift:{dx: 4, dy: 4},
42                               
43                                container_position: null
44                               
45                        });
46
47                        this._setSize();
48
49                        this._init();
50                },
51               
52                _setSize:function(){
53
54                        this.container_position = dojo.coords(this.domNode, true);
55                        this.mb = dojo.marginBox(this.domNode);
56                        this.center = {
57                                x: (this.mb.w / 2),
58                                y: (this.mb.h / 2)
59                        };
60                       
61                },
62               
63                _init:function(){
64                       
65                        this.surface = dojox.gfx.createSurface(this.domNode, this.mb.w, this.mb.h);
66                        this.group = this.surface.createGroup();
67                        this.group.createImage({
68                                width: this.center.x * 2,
69                                height:this.center.y * 2,
70                                src: this.img
71                        });
72                       
73                        // hand shapes
74                        var _off = 15;
75                        var mar = ((this.mb.w / 2) - _off) * -1;
76                        var _c = mar * 0.7; // -105;
77                        var _a = mar * 0.5; //-60;
78                        var _b = mar * 0.75; // -100;
79                        var _d = mar * 0.8; // -116;
80                        var _e = mar * 0.0523; // -7ish
81                        var _f = mar * 0.042;
82                        var _g = mar * 0.01234;
83                       
84                        var hour_hand_points = [{x: _e, y: _off }, {x: _e * -1, y: _off }, {x: 0, y: _a }, {x: _e, y: _off }];
85                        var minute_hand_points = [{x: _f, y: _off }, {x: _f * -1, y: _off }, {x: 0, y: _b }, {x: _f, y: _off }];
86                        var second_hand_points = [
87                                {x: _g, y: _off }, {x: _g * -1, y: _off }, {x: _g * -1, y: _c },
88                                {x: _e * -1, y: _c }, {x: 0, y: _d }, {x: _e, y: _c },
89                                {x: _g, y: _c }, {x: _g, y: _off }
90                        ];
91                       
92                        // create shapes
93                        this.hour_shadow = this.group.createPolyline(hour_hand_points)
94                                .setFill([0, 0, 0, 0.1])
95                                ;
96                        this.hour_hand = this.group.createPolyline(hour_hand_points)
97                                .setStroke({color: "black", width: 2})
98                                .setFill("#889")
99                                ;
100                        this.minute_shadow = this.group.createPolyline(minute_hand_points)
101                                .setFill([0, 0, 0, 0.1])
102                                ;
103                        this.minute_hand = this.group.createPolyline(minute_hand_points)
104                                .setStroke({color: "black", width: 2})
105                                .setFill("#ccd")
106                                ;
107                        this.second_shadow = this.group.createPolyline(second_hand_points)
108                                .setFill([0, 0, 0, 0.1])
109                                ;
110                        this.second_hand = this.group.createPolyline(second_hand_points)
111                                .setStroke({color: "#800", width: 1})
112                                .setFill("#d00")
113                                ;
114                                               
115                        this.group.createCircle({r: 1}).setFill("black").setTransform({dx: this.center.x, dy: this.center.y });
116                       
117                        // start the clock             
118                        this.resetTime();
119               
120                        window.setInterval(dojo.hitch(this,"advanceTime"), 1000);
121                },
122               
123                placeHand: function(shape, angle, shift){
124                        var move = {dx: this.center.x + (shift ? shift.dx : 0), dy: this.center.y + (shift ? shift.dy : 0)};
125                        return shape.setTransform([move, dojox.gfx.matrix.rotateg(angle)]);
126                },
127               
128                placeHourHand: function(h, m, s){
129                        var angle = 30 * (h % 12 + m / 60 + s / 3600);
130                        this.placeHand(this.hour_hand, angle);
131                        this.placeHand(this.hour_shadow, angle, this.hour_shadow_shift);
132                },
133               
134                placeMinuteHand: function(m, s){
135                        var angle = 6 * (m + s / 60);
136                        this.placeHand(this.minute_hand, angle);
137                        this.placeHand(this.minute_shadow, angle, this.minute_shadow_shift);
138                },
139               
140                placeSecondHand:function(s){
141                        var angle = 6 * s;
142                        this.placeHand(this.second_hand, angle);
143                        this.placeHand(this.second_shadow, angle, this.second_shadow_shift);
144                },
145               
146                reflectTime: function(time, hold_second_hand, hold_minute_hand, hold_hour_hand){
147                        if(!time){ time = this.current_time; }
148                        var h = time.getHours();
149                        var m = time.getMinutes();
150                        var s = time.getSeconds();
151
152                        if(!hold_hour_hand) this.placeHourHand(h, m, s);
153                        if(!hold_minute_hand) this.placeMinuteHand(m, s);
154                        if(!hold_second_hand) this.placeSecondHand(s);
155
156                        this.text_time = dojo.date.locale.format(
157                                time, {selector: "time", timePattern: "h:mm:ss a"}
158                        );
159                },
160               
161                resetTime: function(){
162                        this.current_time = new Date();
163                        this.reflectTime();
164                },
165               
166                tick: function(){
167                        this.current_time.setSeconds(this.current_time.getSeconds()+1);
168                        this.reflectTime();
169                },
170               
171                advanceTime: function(){
172                        if(!this.selected_hand){
173                                this.tick();
174                        }
175                },
176
177                normalizeAngle: function(angle){
178                        if(angle > Math.PI) {
179                                angle -= 2 * Math.PI;
180                        } else if(angle < -Math.PI) {
181                                angle += 2 * Math.PI;
182                        }
183                        return angle;
184                },
185       
186                calculateAngle: function(x, y, handAngle){
187                        try {
188                                return this.normalizeAngle(Math.atan2(y - this.center.y, x - this.center.x) - handAngle);
189                        }catch(e){ /* supress */ }
190                        return 0;
191                },
192       
193                getSecondAngle: function(time){
194                        if(!time) time = this.current_time;
195                        return (6 * time.getSeconds() - 90) / 180 * Math.PI;
196                },
197       
198                getMinuteAngle: function(time){
199                        if(!time) time = this.current_time;
200                        return (6 * (time.getMinutes() + time.getSeconds() / 60) - 90) / 180 * Math.PI;
201                },
202       
203                getHourAngle: function(time){
204                        if(!time) time = this.current_time;
205                        return (30 * (time.getHours() + (time.getMinutes() + time.getSeconds() / 60) / 60) - 90) / 180 * Math.PI;
206                },
207               
208                resize: function(size){
209                        this.surface.setDimensions(size.w, size.h);
210                        this.group.setTransform(dojox.gfx.matrix.scale(size.w/this.mb.w, size.h/this.mb.h));
211                        this._setSize();
212                }
213       
214        });
215       
216        dojo.declare("demo.InteractiveClock",demo.Clock,{
217         
218                _init: function(){
219                        this.inherited(arguments);
220                        // attach events
221                        this.diff_time = new Date();
222                        this.hour_hand  .connect("onmousedown", this,"onMouseDown");
223                        this.minute_hand.connect("onmousedown", this,"onMouseDown");
224                        this.second_hand.connect("onmousedown", this,"onMouseDown");
225                        this.connect(this.domNode, "onmousemove", "onMouseMove");
226                        this.connect(this.domNode, "onmouseup", "onMouseUp");
227                       
228                },
229       
230                onMouseDown: function(evt){
231                        this.selected_hand = evt.target;
232                        this.diff_time.setTime(this.current_time.getTime());
233                        dojo.stopEvent(evt);
234                },
235       
236                onMouseMove: function(evt){
237                        if(!this.selected_hand) return;
238                        if(evt.target == this.second_hand.getEventSource() ||
239                                        evt.target == this.minute_hand.getEventSource() ||
240                                        evt.target == this.hour_hand.getEventSource()){
241                                        dojo.stopEvent(evt);
242                                return;
243                        }
244                        if(dojox.gfx.equalSources(this.selected_hand, this.second_hand.getEventSource())){
245                                var angle = this.calculateAngle(
246                                        evt.clientX - this.container_position.x,
247                                        evt.clientY - this.container_position.y,
248                                        this.normalizeAngle(this.getSecondAngle())
249                                );
250                                var diff = Math.round(angle / Math.PI * 180 / 6); // in whole seconds
251                                this.current_time.setSeconds(this.current_time.getSeconds() + Math.round(diff));
252                                this.reflectTime();
253                        }else if(dojox.gfx.equalSources(this.selected_hand, this.minute_hand.getEventSource())){
254                                var angle = this.calculateAngle(
255                                        evt.clientX - this.container_position.x,
256                                        evt.clientY - this.container_position.y,
257                                        this.normalizeAngle(this.getMinuteAngle(this.diff_time))
258                                );
259                                var diff = Math.round(angle / Math.PI * 180 / 6 * 60); // in whole seconds
260                                this.diff_time.setTime(this.diff_time.getTime() + 1000 * diff);
261                                this.reflectTime(this.diff_time, true);
262                               
263                        }else if(dojox.gfx.equalSources(this.selected_hand, this.hour_hand.getEventSource())){
264                                var angle = this.calculateAngle(
265                                        evt.clientX - this.container_position.x,
266                                        evt.clientY - this.container_position.y,
267                                        this.normalizeAngle(this.getHourAngle(this.diff_time))
268                                );
269                                var diff = Math.round(angle / Math.PI * 180 / 30 * 60 * 60); // in whole seconds
270                                this.diff_time.setTime(this.diff_time.getTime() + 1000 * diff);
271                                this.reflectTime(this.diff_time, true, true);
272                        }else{
273                                return;
274                        }
275                        dojo.stopEvent(evt);
276                },
277               
278                onMouseUp:function(evt){
279                        if(this.selected_hand && !dojox.gfx.equalSources(this.selected_hand, this.second_hand.getEventSource())){
280                                this.current_time.setTime(this.diff_time.getTime());
281                                this.reflectTime();
282                        }
283                        this.selected_hand = null;
284                        dojo.stopEvent(evt);
285                }
286        });
287        dojo.require("dijit.form.Button");
288        dojo.addOnLoad(function(){
289                var n = dojo.doc.createElement('div');
290                dojo.body().appendChild(n);
291                dojo.style(n,{
292                        height:"200px", width:"200px",
293                        border:"5px solid #ededed"
294                });
295                new demo.Clock({},n);
296        });
297
298</script>
299<style type="text/css">
300.movable { cursor: hand; }
301</style>
302</head>
303<body>
304<h1>dojox.gfx: interactive analog clock</h1>
305<p>Grab hands and set your own time.</p>
306<p>Warning: Canvas renderer doesn't implement event handling.</p>
307
308<button dojoType="dijit.form.Button">
309        Resize
310        <script type="dojo/method" event="onClick">
311                dijit.byId("one").resize({ w:250, h:250 });
312        </script>
313</button>
314
315<hr noshade size="0" />
316
317<div class="dijitInline" dojoType="demo.Clock" id="gfx_holder" style="width: 300px; height: 300px;"></div>
318<div class="dijitInline" img="images/clock_face.jpg" dojoType="demo.InteractiveClock" style="width: 225px; height: 225px;"></div>
319<div class="dijitInline" id="one" dojoType="demo.Clock" style="width: 150px; height: 150px;"></div>
320<div class="dijitInline" dojoType="demo.Clock" style="width: 75px; height: 75px;"></div>
321
322<hr noshade size="0" />
323
324
325
326
327</body>
328</html>
Note: See TracBrowser for help on using the repository browser.