source: Dev/branches/rest-dojo-ui/client/dojox/gfx/demos/clock.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: 7.3 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/tests/css/dijitTests.css";
8</style>
9<script type="text/javascript" src="../../../dojo/dojo.js"></script>
10<script type="text/javascript">
11
12dojo.require("dojox.gfx");
13dojo.require("dojo.date.locale");
14
15var current_time = new Date();
16
17var hour_hand   = null;
18var minute_hand = null;
19var second_hand = null;
20
21var hour_shadow   = null;
22var minute_shadow = null;
23var second_shadow = null;
24
25var center = {x: 385 / 2, y: 385 / 2};
26
27var hour_shadow_shift   = {dx: 2, dy: 2};
28var minute_shadow_shift = {dx: 3, dy: 3};
29var second_shadow_shift = {dx: 4, dy: 4};
30
31var selected_hand = null;
32var container = null;
33var container_position = null;
34var text_time = null;
35var diff_time = new Date();
36
37placeHand = function(shape, angle, shift){
38        var move = {dx: center.x + (shift ? shift.dx : 0), dy: center.y + (shift ? shift.dy : 0)};
39        return shape.setTransform([move, dojox.gfx.matrix.rotateg(angle)]);
40};
41
42placeHourHand = function(h, m, s){
43        var angle = 30 * (h % 12 + m / 60 + s / 3600);
44        placeHand(hour_hand, angle);
45        placeHand(hour_shadow, angle, hour_shadow_shift);
46};
47
48placeMinuteHand = function(m, s){
49        var angle = 6 * (m + s / 60);
50        placeHand(minute_hand, angle);
51        placeHand(minute_shadow, angle, minute_shadow_shift);
52};
53
54placeSecondHand = function(s){
55        var angle = 6 * s;
56        placeHand(second_hand, angle);
57        placeHand(second_shadow, angle, second_shadow_shift);
58};
59
60reflectTime = function(time, hold_second_hand, hold_minute_hand, hold_hour_hand){
61        if(!time) time = current_time;
62        var h = time.getHours();
63        var m = time.getMinutes();
64        var s = time.getSeconds();
65        if(!hold_hour_hand) placeHourHand(h, m, s);
66        if(!hold_minute_hand) placeMinuteHand(m, s);
67        if(!hold_second_hand) placeSecondHand(s);
68        text_time.innerHTML = dojo.date.locale.format(
69                time, {selector: "time", timePattern: "h:mm:ss a"});
70};
71
72resetTime = function(){
73        current_time = new Date();
74        reflectTime();
75};
76
77tick = function(){
78        current_time.setSeconds(current_time.getSeconds() + 1);
79        reflectTime();
80};
81
82advanceTime = function(){
83        if(!selected_hand) {
84                tick();
85        }
86};
87
88normalizeAngle = function(angle){
89        if(angle > Math.PI) {
90                angle -= 2 * Math.PI;
91        } else if(angle < -Math.PI) {
92                angle += 2 * Math.PI;
93        }
94        return angle;
95};
96
97calculateAngle = function(x, y, handAngle){
98        try {
99                return normalizeAngle(Math.atan2(y - center.y, x - center.x) - handAngle);
100        } catch(e) {
101                // supress
102        }
103        return 0;
104};
105
106getSecondAngle = function(time){
107        if(!time) time = current_time;
108        return (6 * time.getSeconds() - 90) / 180 * Math.PI;
109};
110
111getMinuteAngle = function(time){
112        if(!time) time = current_time;
113        return (6 * (time.getMinutes() + time.getSeconds() / 60) - 90) / 180 * Math.PI;
114};
115
116getHourAngle = function(time){
117        if(!time) time = current_time;
118        return (30 * (time.getHours() + (time.getMinutes() + time.getSeconds() / 60) / 60) - 90) / 180 * Math.PI;
119};
120
121onMouseDown = function(evt){
122        selected_hand = evt.target;
123        diff_time.setTime(current_time.getTime());
124        dojo.stopEvent(evt);
125};
126
127onMouseMove = function(evt){
128        if(!selected_hand) return;
129        if(evt.target == second_hand.getEventSource() ||
130                        evt.target == minute_hand.getEventSource() ||
131                        evt.target == hour_hand.getEventSource()){
132                dojo.stopEvent(evt);
133                return;
134        }
135        if(dojox.gfx.equalSources(selected_hand, second_hand.getEventSource())){
136                var angle = calculateAngle(
137                        evt.clientX - container_position.x,
138                        evt.clientY - container_position.y,
139                        normalizeAngle(getSecondAngle())
140                );
141                var diff = Math.round(angle / Math.PI * 180 / 6); // in whole seconds
142                current_time.setSeconds(current_time.getSeconds() + Math.round(diff));
143                reflectTime();
144        }else if(dojox.gfx.equalSources(selected_hand, minute_hand.getEventSource())){
145                var angle = calculateAngle(
146                        evt.clientX - container_position.x,
147                        evt.clientY - container_position.y,
148                        normalizeAngle(getMinuteAngle(diff_time))
149                );
150                var diff = Math.round(angle / Math.PI * 180 / 6 * 60); // in whole seconds
151                diff_time.setTime(diff_time.getTime() + 1000 * diff);
152                reflectTime(diff_time, true);
153               
154        }else if(dojox.gfx.equalSources(selected_hand, hour_hand.getEventSource())){
155                var angle = calculateAngle(
156                        evt.clientX - container_position.x,
157                        evt.clientY - container_position.y,
158                        normalizeAngle(getHourAngle(diff_time))
159                );
160                var diff = Math.round(angle / Math.PI * 180 / 30 * 60 * 60); // in whole seconds
161                diff_time.setTime(diff_time.getTime() + 1000 * diff);
162                reflectTime(diff_time, true, true);
163        }else{
164                return;
165        }
166        dojo.stopEvent(evt);
167};
168
169onMouseUp = function(evt){
170        if(selected_hand && !dojox.gfx.equalSources(selected_hand, second_hand.getEventSource())){
171                current_time.setTime(diff_time.getTime());
172                reflectTime();
173        }
174        selected_hand = null;
175        dojo.stopEvent(evt);
176};
177
178makeShapes = function(){
179        // prerequisites
180        container = dojo.byId("gfx_holder");
181        container_position = dojo.coords(container, true);
182        text_time = dojo.byId("time");
183        var surface = dojox.gfx.createSurface(container, 385, 385);
184    surface.createImage({width: 385, height: 385, src: "images/clock_face.jpg"});
185   
186    // hand shapes
187    var hour_hand_points = [{x: -7, y: 15}, {x: 7, y: 15}, {x: 0, y: -60}, {x: -7, y: 15}];
188    var minute_hand_points = [{x: -5, y: 15}, {x: 5, y: 15}, {x: 0, y: -100}, {x: -5, y: 15}];
189    var second_hand_points = [{x: -2, y: 15}, {x: 2, y: 15}, {x: 2, y: -105}, {x: 6, y: -105}, {x: 0, y: -116}, {x: -6, y: -105}, {x: -2, y: -105}, {x: -2, y: 15}];
190   
191    // create shapes
192    hour_shadow = surface.createPolyline(hour_hand_points)
193                .setFill([0, 0, 0, 0.1])
194                ;
195    hour_hand = surface.createPolyline(hour_hand_points)
196                .setStroke({color: "black", width: 2})
197                .setFill("#889")
198                ;
199    minute_shadow = surface.createPolyline(minute_hand_points)
200                .setFill([0, 0, 0, 0.1])
201                ;
202    minute_hand = surface.createPolyline(minute_hand_points)
203                .setStroke({color: "black", width: 2})
204                .setFill("#ccd")
205                ;
206    second_shadow = surface.createPolyline(second_hand_points)
207                .setFill([0, 0, 0, 0.1])
208                ;
209    second_hand = surface.createPolyline(second_hand_points)
210                .setStroke({color: "#800", width: 1})
211                .setFill("#d00")
212                ;
213
214        // next 3 lines kill Silverlight because its nodes do not support CSS           
215        //dojox.gfx._addClass(hour_hand  .getEventSource(), "movable");
216        //dojox.gfx._addClass(minute_hand.getEventSource(), "movable");
217        //dojox.gfx._addClass(second_hand.getEventSource(), "movable");
218               
219        surface.createCircle({r: 1}).setFill("black").setTransform({dx: 192.5, dy: 192.5});
220       
221        // attach events
222        hour_hand  .connect("onmousedown", onMouseDown);
223        minute_hand.connect("onmousedown", onMouseDown);
224        second_hand.connect("onmousedown", onMouseDown);
225        dojo.connect(container, "onmousemove", onMouseMove);
226        dojo.connect(container, "onmouseup",   onMouseUp);
227        dojo.connect(dojo.byId("reset"), "onclick", resetTime);
228
229        // start the clock             
230        resetTime();
231        window.setInterval(advanceTime, 1000);
232};
233
234dojo.addOnLoad(makeShapes);
235
236</script>
237<style type="text/css">
238.movable { cursor: hand; }
239</style>
240</head>
241<body>
242<h1>dojox.gfx: interactive analog clock</h1>
243<p>Grab hands and set your own time.</p>
244<p>Warning: Canvas renderer doesn't implement event handling.</p>
245<div id="gfx_holder" style="width: 385px; height: 385px;"></div>
246<p>Current time: <span id="time"></span>.</p>
247<p><button id="reset">Reset</button></p>
248</body>
249</html>
Note: See TracBrowser for help on using the repository browser.