├── img ├── screenshot.png ├── glyphicons-halflings.png └── glyphicons-halflings-white.png ├── css ├── smoothness │ ├── images │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_2e83ff_256x240.png │ │ ├── ui-icons_454545_256x240.png │ │ ├── ui-icons_888888_256x240.png │ │ ├── ui-icons_cd0a0a_256x240.png │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── jquery-ui-1.9.1.custom.min.css │ └── jquery-ui-1.9.1.custom.css ├── webkitSynth.css ├── bootstrap-responsive.min.css └── bootstrap-responsive.css ├── README.md ├── index.html └── js ├── webkitSynth.js ├── jquery.knob.js ├── bootstrap.min.js └── jquery.kontrol.js /img/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/img/screenshot.png -------------------------------------------------------------------------------- /img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeremywen/webkitSynth/HEAD/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | Demo: http://jeremywentworth.com/projects/webkitSynth 4 | 5 | Audio Demo: https://soundcloud.com/jeremywentworth/demo-of-webkitsynth 6 | -------------------------------------------------------------------------------- /css/webkitSynth.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 40px; 4 | } 5 | .container{ 6 | margin-left: 40px; 7 | margin-right: 10px; 8 | } 9 | input[type="text"]{ 10 | -webkit-box-shadow: inset 0 0px 0px; 11 | } 12 | 13 | .knobwell{ 14 | text-align:center; 15 | float:left; 16 | width:240px; 17 | height: 240px; 18 | color:rgb(135, 206, 235); 19 | margin: 10px; 20 | padding: 7px; 21 | } 22 | 23 | 24 | h3{ 25 | padding: 0px; 26 | margin: 10px; 27 | line-height: 25px; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
34 |
35 |
36 |
53 |
54 |
42 | * k.o.call(this);
43 | *
44 | */
45 | k.o = function () {
46 | var s = this;
47 |
48 | this.o = null; // array of options
49 | this.$ = null; // jQuery wrapped element
50 | this.i = null; // mixed HTMLInputElement or array of HTMLInputElement
51 | this.g = null; // 2D graphics context for 'pre-rendering'
52 | this.v = null; // value ; mixed array or integer
53 | this.cv = null; // change value ; not commited value
54 | this.x = 0; // canvas x position
55 | this.y = 0; // canvas y position
56 | this.$c = null; // jQuery canvas element
57 | this.c = null; // rendered canvas context
58 | this.t = 0; // touches index
59 | this.isInit = false;
60 | this.fgColor = null; // main color
61 | this.pColor = null; // previous color
62 | this.dH = null; // draw hook
63 | this.cH = null; // change hook
64 | this.eH = null; // cancel hook
65 | this.rH = null; // release hook
66 |
67 | this.run = function () {
68 | var cf = function (e, conf) {
69 | var k;
70 | for (k in conf) {
71 | s.o[k] = conf[k];
72 | }
73 | s.init();
74 | s._configure()
75 | ._draw();
76 | };
77 |
78 | if(this.$.data('kontroled')) return;
79 | this.$.data('kontroled', true);
80 |
81 | this.extend();
82 | this.o = $.extend(
83 | {
84 | // Config
85 | min : this.$.data('min') || 0,
86 | max : this.$.data('max') || 100,
87 | stopper : true,
88 | readOnly : this.$.data('readonly'),
89 |
90 | // UI
91 | cursor : (this.$.data('cursor') === true && 30)
92 | || this.$.data('cursor')
93 | || 0,
94 | thickness : this.$.data('thickness') || 0.35,
95 | width : this.$.data('width') || 200,
96 | height : this.$.data('height') || 200,
97 | displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'),
98 | displayPrevious : this.$.data('displayprevious'),
99 | fgColor : this.$.data('fgcolor') || '#87CEEB',
100 | inline : false,
101 |
102 | // Hooks
103 | draw : null, // function () {}
104 | change : null, // function (value) {}
105 | cancel : null, // function () {}
106 | release : null // function (value) {}
107 | }, this.o
108 | );
109 |
110 | // routing value
111 | if(this.$.is('fieldset')) {
112 |
113 | // fieldset = array of integer
114 | this.v = {};
115 | this.i = this.$.find('input')
116 | this.i.each(function(k) {
117 | var $this = $(this);
118 | s.i[k] = $this;
119 | s.v[k] = $this.val();
120 |
121 | $this.bind(
122 | 'change'
123 | , function () {
124 | var val = {};
125 | val[k] = $this.val();
126 | s.val(val);
127 | }
128 | );
129 | });
130 | this.$.find('legend').remove();
131 |
132 | } else {
133 | // input = integer
134 | this.i = this.$;
135 | this.v = this.$.val();
136 | (this.v == '') && (this.v = this.o.min);
137 |
138 | this.$.bind(
139 | 'change'
140 | , function () {
141 | s.val(s.$.val());
142 | }
143 | );
144 | }
145 |
146 | (!this.o.displayInput) && this.$.hide();
147 |
148 | this.$c = $('');
151 | this.c = this.$c[0].getContext("2d");
152 |
153 | this.$
154 | .wrap($(''))
157 | .before(this.$c);
158 |
159 | if (this.v instanceof Object) {
160 | this.cv = {};
161 | this.copy(this.v, this.cv);
162 | } else {
163 | this.cv = this.v;
164 | }
165 |
166 | this.$
167 | .bind("configure", cf)
168 | .parent()
169 | .bind("configure", cf);
170 |
171 | this._listen()
172 | ._configure()
173 | ._xy()
174 | .init();
175 |
176 | this.isInit = true;
177 |
178 | this._draw();
179 |
180 | return this;
181 | };
182 |
183 | this._draw = function () {
184 |
185 | // canvas pre-rendering
186 | var d = true,
187 | c = document.createElement('canvas');
188 |
189 | c.width = s.o.width;
190 | c.height = s.o.height;
191 | s.g = c.getContext('2d');
192 |
193 | s.clear();
194 |
195 | s.dH
196 | && (d = s.dH());
197 |
198 | (d !== false) && s.draw();
199 |
200 | s.c.drawImage(c, 0, 0);
201 | c = null;
202 | };
203 |
204 | this._touch = function (e) {
205 |
206 | var touchMove = function (e) {
207 |
208 | var v = s.xy2val(
209 | e.originalEvent.touches[s.t].pageX,
210 | e.originalEvent.touches[s.t].pageY
211 | );
212 |
213 | if (v == s.cv) return;
214 |
215 | if (
216 | s.cH
217 | && (s.cH(v) === false)
218 | ) return;
219 |
220 |
221 | s.change(v);
222 | s._draw();
223 | };
224 |
225 | // get touches index
226 | this.t = k.c.t(e);
227 |
228 | // First touch
229 | touchMove(e);
230 |
231 | // Touch events listeners
232 | k.c.d
233 | .bind("touchmove.k", touchMove)
234 | .bind(
235 | "touchend.k"
236 | , function () {
237 | k.c.d.unbind('touchmove.k touchend.k');
238 |
239 | if (
240 | s.rH
241 | && (s.rH(s.cv) === false)
242 | ) return;
243 |
244 | s.val(s.cv);
245 | }
246 | );
247 |
248 | return this;
249 | };
250 |
251 | this._mouse = function (e) {
252 |
253 | var mouseMove = function (e) {
254 | var v = s.xy2val(e.pageX, e.pageY);
255 | if (v == s.cv) return;
256 |
257 | if (
258 | s.cH
259 | && (s.cH(v) === false)
260 | ) return;
261 |
262 | s.change(v);
263 | s._draw();
264 | };
265 |
266 | // First click
267 | mouseMove(e);
268 |
269 | // Mouse events listeners
270 | k.c.d
271 | .bind("mousemove.k", mouseMove)
272 | .bind(
273 | // Escape key cancel current change
274 | "keyup.k"
275 | , function (e) {
276 | if (e.keyCode === 27) {
277 | k.c.d.unbind("mouseup.k mousemove.k keyup.k");
278 |
279 | if (
280 | s.eH
281 | && (s.eH() === false)
282 | ) return;
283 |
284 | s.cancel();
285 | }
286 | }
287 | )
288 | .bind(
289 | "mouseup.k"
290 | , function (e) {
291 | k.c.d.unbind('mousemove.k mouseup.k keyup.k');
292 |
293 | if (
294 | s.rH
295 | && (s.rH(s.cv) === false)
296 | ) return;
297 |
298 | s.val(s.cv);
299 | }
300 | );
301 |
302 | return this;
303 | };
304 |
305 | this._xy = function () {
306 | var o = this.$c.offset();
307 | this.x = o.left;
308 | this.y = o.top;
309 | return this;
310 | };
311 |
312 | this._listen = function () {
313 |
314 | if (!this.o.readOnly) {
315 | this.$c
316 | .bind(
317 | "mousedown"
318 | , function (e) {
319 | e.preventDefault();
320 | s._xy()._mouse(e);
321 | }
322 | )
323 | .bind(
324 | "touchstart"
325 | , function (e) {
326 | e.preventDefault();
327 | s._xy()._touch(e);
328 | }
329 | );
330 | this.listen();
331 | } else {
332 | this.$.attr('readonly', 'readonly');
333 | }
334 |
335 | return this;
336 | };
337 |
338 | this._configure = function () {
339 |
340 | // Hooks
341 | if (this.o.draw) this.dH = this.o.draw;
342 | if (this.o.change) this.cH = this.o.change;
343 | if (this.o.cancel) this.eH = this.o.cancel;
344 | if (this.o.release) this.rH = this.o.release;
345 |
346 | if (this.o.displayPrevious) {
347 | this.pColor = this.h2rgba(this.o.fgColor, "0.4");
348 | this.fgColor = this.h2rgba(this.o.fgColor, "0.6");
349 | } else {
350 | this.fgColor = this.o.fgColor;
351 | }
352 |
353 | return this;
354 | };
355 |
356 | this._clear = function () {
357 | this.$c[0].width = this.$c[0].width;
358 | };
359 |
360 | // Abstract methods
361 | this.listen = function () {}; // on start, one time
362 | this.extend = function () {}; // each time configure triggered
363 | this.init = function () {}; // each time configure triggered
364 | this.change = function (v) {}; // on change
365 | this.val = function (v) {}; // on release
366 | this.xy2val = function (x, y) {}; //
367 | this.draw = function () {}; // on change / on release
368 | this.clear = function () { this._clear(); };
369 |
370 | // Utils
371 | this.h2rgba = function (h, a) {
372 | var rgb;
373 | h = h.substring(1,7)
374 | rgb = [parseInt(h.substring(0,2),16)
375 | ,parseInt(h.substring(2,4),16)
376 | ,parseInt(h.substring(4,6),16)];
377 | return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")";
378 | };
379 |
380 | this.copy = function (f, t) {
381 | for (var i in f) { t[i] = f[i]; }
382 | };
383 | };
384 |
385 |
386 | /**
387 | * k.Dial
388 | */
389 | k.Dial = function () {
390 | k.o.call(this);
391 |
392 | this.startAngle = null;
393 | this.xy = null;
394 | this.radius = null;
395 | this.lineWidth = null;
396 | this.cursorExt = null;
397 | this.w2 = null;
398 | this.PI2 = 2*Math.PI;
399 |
400 | this.extend = function () {
401 | this.o = $.extend(
402 | {
403 | bgColor : this.$.data('bgcolor') || '#EEEEEE',
404 | angleOffset : this.$.data('angleoffset') || 0,
405 | angleArc : this.$.data('anglearc') || 360,
406 | inline : true
407 | }, this.o
408 | );
409 | };
410 |
411 | this.val = function (v) {
412 | if (null != v) {
413 | this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v;
414 | this.v = this.cv;
415 | this.$.val(this.v);
416 | this._draw();
417 | } else {
418 | return this.v;
419 | }
420 | };
421 |
422 | this.xy2val = function (x, y) {
423 | var a, ret;
424 |
425 | a = Math.atan2(
426 | x - (this.x + this.w2)
427 | , - (y - this.y - this.w2)
428 | ) - this.angleOffset;
429 |
430 | if(this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) {
431 | // if isset angleArc option, set to min if .5 under min
432 | a = 0;
433 | } else if (a < 0) {
434 | a += this.PI2;
435 | }
436 |
437 | ret = ~~ (0.5 + (a * (this.o.max - this.o.min) / this.angleArc))
438 | + this.o.min;
439 |
440 | this.o.stopper
441 | && (ret = max(min(ret, this.o.max), this.o.min));
442 |
443 | return ret;
444 | };
445 |
446 | this.listen = function () {
447 | // bind MouseWheel
448 | var s = this,
449 | mw = function (e) {
450 | e.preventDefault();
451 |
452 | var ori = e.originalEvent
453 | ,deltaX = ori.detail || ori.wheelDeltaX
454 | ,deltaY = ori.detail || ori.wheelDeltaY
455 | ,v = parseInt(s.$.val()) + (deltaX>0 || deltaY>0 ? 1 : deltaX<0 || deltaY<0 ? -1 : 0);
456 |
457 | if (
458 | s.cH
459 | && (s.cH(v) === false)
460 | ) return;
461 |
462 | s.val(v);
463 | }
464 | , kval, to, m = 1, kv = {37:-1, 38:1, 39:1, 40:-1};
465 |
466 | this.$
467 | .bind(
468 | "keydown"
469 | ,function (e) {
470 | var kc = e.keyCode;
471 |
472 | // numpad support
473 | if(kc >= 96 && kc <= 105) {
474 | kc = e.keyCode = kc - 48;
475 | }
476 |
477 | kval = parseInt(String.fromCharCode(kc));
478 |
479 | if (isNaN(kval)) {
480 |
481 | (kc !== 13) // enter
482 | && (kc !== 8) // bs
483 | && (kc !== 9) // tab
484 | && (kc !== 189) // -
485 | && e.preventDefault();
486 |
487 | // arrows
488 | if ($.inArray(kc,[37,38,39,40]) > -1) {
489 | e.preventDefault();
490 |
491 | var v = parseInt(s.$.val()) + kv[kc] * m;
492 |
493 | s.o.stopper
494 | && (v = max(min(v, s.o.max), s.o.min));
495 |
496 | s.change(v);
497 | s._draw();
498 |
499 | // long time keydown speed-up
500 | to = window.setTimeout(
501 | function () { m*=2; }
502 | ,30
503 | );
504 | }
505 | }
506 | }
507 | )
508 | .bind(
509 | "keyup"
510 | ,function (e) {
511 | if (isNaN(kval)) {
512 | if (to) {
513 | window.clearTimeout(to);
514 | to = null;
515 | m = 1;
516 | s.val(s.$.val());
517 | }
518 | } else {
519 | // kval postcond
520 | (s.$.val() > s.o.max && s.$.val(s.o.max))
521 | || (s.$.val() < s.o.min && s.$.val(s.o.min));
522 | }
523 |
524 | }
525 | );
526 |
527 | this.$c.bind("mousewheel DOMMouseScroll", mw);
528 | this.$.bind("mousewheel DOMMouseScroll", mw)
529 | };
530 |
531 | this.init = function () {
532 |
533 | if (
534 | this.v < this.o.min
535 | || this.v > this.o.max
536 | ) this.v = this.o.min;
537 |
538 | this.$.val(this.v);
539 | this.w2 = this.o.width / 2;
540 | this.cursorExt = this.o.cursor / 100;
541 | this.xy = this.w2;
542 | this.lineWidth = this.xy * this.o.thickness;
543 | this.radius = this.xy - this.lineWidth / 2;
544 |
545 | this.o.angleOffset
546 | && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset);
547 |
548 | this.o.angleArc
549 | && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc);
550 |
551 | // deg to rad
552 | this.angleOffset = this.o.angleOffset * Math.PI / 180;
553 | this.angleArc = this.o.angleArc * Math.PI / 180;
554 |
555 | // compute start and end angles
556 | this.startAngle = 1.5 * Math.PI + this.angleOffset;
557 | this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc;
558 |
559 | var s = max(
560 | String(Math.abs(this.o.max)).length
561 | , String(Math.abs(this.o.min)).length
562 | , 2
563 | ) + 2;
564 |
565 | this.o.displayInput
566 | && this.i.css({
567 | 'width' : ((this.o.width / 2 + 4) >> 0) + 'px'
568 | ,'height' : ((this.o.width / 3) >> 0) + 'px'
569 | ,'position' : 'absolute'
570 | ,'vertical-align' : 'middle'
571 | ,'margin-top' : ((this.o.width / 3) >> 0) + 'px'
572 | ,'margin-left' : '-' + ((this.o.width * 3 / 4 + 2) >> 0) + 'px'
573 | ,'border' : 0
574 | ,'background' : 'none'
575 | ,'font' : 'bold ' + ((this.o.width / s) >> 0) + 'px Arial'
576 | ,'text-align' : 'center'
577 | ,'color' : this.o.fgColor
578 | ,'padding' : '0px'
579 | ,'-webkit-appearance': 'none'
580 | })
581 | || this.i.css({
582 | 'width' : '0px'
583 | ,'visibility' : 'hidden'
584 | });
585 | };
586 |
587 | this.change = function (v) {
588 | this.cv = v;
589 | this.$.val(v);
590 | };
591 |
592 | this.angle = function (v) {
593 | return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min);
594 | };
595 |
596 | this.draw = function () {
597 |
598 | var c = this.g, // context
599 | a = this.angle(this.cv) // Angle
600 | , sat = this.startAngle // Start angle
601 | , eat = sat + a // End angle
602 | , sa, ea // Previous angles
603 | , r = 1;
604 |
605 | c.lineWidth = this.lineWidth;
606 |
607 | this.o.cursor
608 | && (sat = eat - this.cursorExt)
609 | && (eat = eat + this.cursorExt);
610 |
611 | c.beginPath();
612 | c.strokeStyle = this.o.bgColor;
613 | c.arc(this.xy, this.xy, this.radius, this.endAngle, this.startAngle, true);
614 | c.stroke();
615 |
616 | if (this.o.displayPrevious) {
617 | ea = this.startAngle + this.angle(this.v);
618 | sa = this.startAngle;
619 | this.o.cursor
620 | && (sa = ea - this.cursorExt)
621 | && (ea = ea + this.cursorExt);
622 |
623 | c.beginPath();
624 | c.strokeStyle = this.pColor;
625 | c.arc(this.xy, this.xy, this.radius, sa, ea, false);
626 | c.stroke();
627 | r = (this.cv == this.v);
628 | }
629 |
630 | c.beginPath();
631 | c.strokeStyle = r ? this.o.fgColor : this.fgColor ;
632 | c.arc(this.xy, this.xy, this.radius, sat, eat, false);
633 | c.stroke();
634 | };
635 |
636 | this.cancel = function () {
637 | this.val(this.v);
638 | };
639 | };
640 |
641 | $.fn.dial = $.fn.knob = function (o) {
642 | return this.each(
643 | function () {
644 | var d = new k.Dial();
645 | d.o = o;
646 | d.$ = $(this);
647 | d.run();
648 | }
649 | ).parent();
650 | };
651 |
652 | })(jQuery);
--------------------------------------------------------------------------------
/js/bootstrap.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap.js by @fat & @mdo
3 | * Copyright 2012 Twitter, Inc.
4 | * http://www.apache.org/licenses/LICENSE-2.0.txt
5 | */
6 | !function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()},e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")},e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=n,this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},to:function(t){var n=this.$element.find(".item.active"),r=n.parent().children(),i=r.index(n),s=this;if(t>r.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){s.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",e(r[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0]});if(i.hasClass("active"))return;if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}},e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e(document).on("click.carousel.data-api","[data-slide]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data());i.carousel(s),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning)return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning)return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=typeof n=="object"&&n;i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;return n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=e(n),r.length||(r=t.parent()),r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||(s.toggleClass("open"),n.focus()),!1},keydown:function(t){var n,r,s,o,u,a;if(!/(38|40|27)/.test(t.keyCode))return;n=e(this),t.preventDefault(),t.stopPropagation();if(n.is(".disabled, :disabled"))return;o=i(n),u=o.hasClass("open");if(!u||u&&t.keyCode==27)return n.click();r=e("[role=menu] li:not(.divider) a",o);if(!r.length)return;a=r.index(r.filter(":focus")),t.keyCode==38&&a>0&&a--,t.keyCode==40&&a
43 | * k.o.call(this);
44 | *
45 | */
46 | k.o = function () {
47 | var s = this;
48 |
49 | this.o = null; // array of options
50 | this.$ = null; // jQuery wrapped element
51 | this.i = null; // mixed HTMLInputElement or array of HTMLInputElement
52 | this.g = null; // 2D graphics context for 'pre-rendering'
53 | this.v = null; // value ; mixed array or integer
54 | this.cv = null; // change value ; not commited value
55 | this.x = 0; // canvas x position
56 | this.y = 0; // canvas y position
57 | this.mx = 0; // x value of mouse down point of the current mouse move
58 | this.my = 0; // y value of mouse down point of the current mose move
59 | this.$c = null; // jQuery canvas element
60 | this.c = null; // rendered canvas context
61 | this.t = 0; // touches index
62 | this.isInit = false;
63 | this.fgColor = null; // main color
64 | this.pColor = null; // previous color
65 | this.sH = null; // start hook
66 | this.dH = null; // draw hook
67 | this.cH = null; // change hook
68 | this.eH = null; // cancel hook
69 | this.rH = null; // release hook
70 |
71 | this.run = function () {
72 | var cf = function (e, conf) {
73 | var k;
74 | for (k in conf) {
75 | s.o[k] = conf[k];
76 | }
77 | s.init();
78 | s._configure()
79 | ._draw();
80 | };
81 |
82 | if(this.$.data('kontroled')) return;
83 | this.$.data('kontroled', true);
84 |
85 | this.extend();
86 | this.o = $.extend(
87 | {
88 | // Config
89 | min : this.$.data('min') || 0,
90 | max : this.$.data('max') || 100,
91 | stopper : true,
92 | readOnly : this.$.data('readonly'),
93 | noScroll : this.$.data('noScroll'),
94 |
95 | // UI
96 | cursor : (this.$.data('cursor') === true && 30)
97 | || this.$.data('cursor')
98 | || 0,
99 | thickness : this.$.data('thickness') || 0.35,
100 | width : this.$.data('width') || 200,
101 | height : this.$.data('height') || 200,
102 | displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'),
103 | displayPrevious : this.$.data('displayprevious'),
104 | fgColor : this.$.data('fgcolor') || '#87CEEB',
105 | inline : false,
106 | //context : {'lineCap' : 'butt'},
107 |
108 | // Hooks
109 | start:null, // function () {}
110 | draw : null, // function () {}
111 | change : null, // function (value) {}
112 | cancel : null, // function () {}
113 | release : null // function (value) {}
114 | }, this.o
115 | );
116 |
117 | // routing value
118 | if(this.$.is('fieldset')) {
119 |
120 | // fieldset = array of integer
121 | this.v = {};
122 | this.i = this.$.find('input')
123 | this.i.each(function(k) {
124 | var $this = $(this);
125 | s.i[k] = $this;
126 | s.v[k] = $this.val();
127 |
128 | $this.bind(
129 | 'change'
130 | , function () {
131 | var val = {};
132 | val[k] = $this.val();
133 | s.val(val);
134 | }
135 | );
136 | });
137 | this.$.find('legend').remove();
138 |
139 | } else {
140 | // input = integer
141 | this.i = this.$;
142 | this.v = this.$.val();
143 | (this.v == '') && (this.v = this.o.min);
144 |
145 | this.$.bind(
146 | 'change'
147 | , function () {
148 | s.val(s.$.val());
149 | }
150 | );
151 | }
152 |
153 | (!this.o.displayInput) && this.$.hide();
154 |
155 | this.$c = $('');
158 | this.c = this.$c[0].getContext("2d");
159 |
160 | this.$
161 | .wrap($(''))
164 | .before(this.$c);
165 |
166 | if (this.v instanceof Object) {
167 | this.cv = {};
168 | this.copy(this.v, this.cv);
169 | } else {
170 | this.cv = this.v;
171 | }
172 |
173 | this.$
174 | .bind("configure", cf)
175 | .parent()
176 | .bind("configure", cf);
177 |
178 | this._listen()
179 | ._configure()
180 | ._xy()
181 | .init();
182 |
183 | this.isInit = true;
184 |
185 | this._draw();
186 |
187 | return this;
188 | };
189 |
190 | this._draw = function () {
191 |
192 | // canvas pre-rendering
193 | var d = true,
194 | c = document.createElement('canvas');
195 |
196 | c.width = s.o.width;
197 | c.height = s.o.height;
198 | s.g = c.getContext('2d');
199 |
200 | s.clear();
201 |
202 | s.dH
203 | && (d = s.dH());
204 |
205 | (d !== false) && s.draw();
206 |
207 | s.c.drawImage(c, 0, 0);
208 | c = null;
209 | };
210 |
211 | this._touch = function (e) {
212 |
213 | var touchMove = function (e) {
214 |
215 | var v = s.xy2val(
216 | e.originalEvent.touches[s.t].pageX,
217 | e.originalEvent.touches[s.t].pageY,
218 | 'touch'
219 | );
220 |
221 | if (v == s.cv) return;
222 |
223 | if (
224 | s.cH
225 | && (s.cH(v) === false)
226 | ) return;
227 |
228 |
229 | s.change(v);
230 | s._draw();
231 | };
232 |
233 | // get touches index
234 | this.t = k.c.t(e);
235 |
236 | if (
237 | this.sH
238 | && (this.sH() === false)
239 | ) return;
240 |
241 | // First touch
242 | touchMove(e);
243 |
244 | // Touch events listeners
245 | k.c.d
246 | .bind("touchmove.k", touchMove)
247 | .bind(
248 | "touchend.k"
249 | , function () {
250 | k.c.d.unbind('touchmove.k touchend.k');
251 |
252 | if (
253 | s.rH
254 | && (s.rH(s.cv) === false)
255 | ) return;
256 |
257 | s.val(s.cv);
258 | }
259 | );
260 |
261 | return this;
262 | };
263 |
264 | this._mouse = function (e) {
265 |
266 | var mouseMove = function (e) {
267 | var v = s.xy2val(e.pageX, e.pageY, 'mouse');
268 | if (v == s.cv) return;
269 |
270 | if (
271 | s.cH
272 | && (s.cH(v) === false)
273 | ) return;
274 |
275 | s.change(v);
276 | s._draw();
277 | };
278 |
279 | if (
280 | this.sH
281 | && (this.sH() === false)
282 | ) return;
283 |
284 | // First click
285 | s.mx = e.pageX;
286 | s.my = e.pageY;
287 | mouseMove(e);
288 |
289 | // Mouse events listeners
290 | k.c.d
291 | .bind("mousemove.k", mouseMove)
292 | .bind(
293 | // Escape key cancel current change
294 | "keyup.k"
295 | , function (e) {
296 | if (e.keyCode === 27) {
297 | k.c.d.unbind("mouseup.k mousemove.k keyup.k");
298 |
299 | if (
300 | s.eH
301 | && (s.eH() === false)
302 | ) return;
303 |
304 | s.cancel();
305 | }
306 | }
307 | )
308 | .bind(
309 | "mouseup.k"
310 | , function (e) {
311 | k.c.d.unbind('mousemove.k mouseup.k keyup.k');
312 |
313 | if (
314 | s.rH
315 | && (s.rH(s.cv) === false)
316 | ) return;
317 |
318 | s.val(s.cv);
319 | }
320 | );
321 |
322 | return this;
323 | };
324 |
325 | this._xy = function () {
326 | var o = this.$c.offset();
327 | this.x = o.left;
328 | this.y = o.top;
329 | return this;
330 | };
331 |
332 | this._listen = function () {
333 |
334 | if (!this.o.readOnly) {
335 | this.$c
336 | .bind(
337 | "mousedown"
338 | , function (e) {
339 | e.preventDefault();
340 | s._xy()._mouse(e);
341 | }
342 | )
343 | .bind(
344 | "touchstart"
345 | , function (e) {
346 | e.preventDefault();
347 | s._xy()._touch(e);
348 | }
349 | );
350 | this.listen();
351 | } else {
352 | this.$.attr('readonly', 'readonly');
353 | }
354 |
355 | return this;
356 | };
357 |
358 | this._configure = function () {
359 |
360 | // Hooks
361 | if (this.o.start) this.sH = this.o.start;
362 | if (this.o.draw) this.dH = this.o.draw;
363 | if (this.o.change) this.cH = this.o.change;
364 | if (this.o.cancel) this.eH = this.o.cancel;
365 | if (this.o.release) this.rH = this.o.release;
366 |
367 | if (this.o.displayPrevious) {
368 | this.pColor = this.h2rgba(this.o.fgColor, "0.4");
369 | this.fgColor = this.h2rgba(this.o.fgColor, "0.6");
370 | } else {
371 | this.fgColor = this.o.fgColor;
372 | }
373 |
374 | return this;
375 | };
376 |
377 | this._clear = function () {
378 | this.$c[0].width = this.$c[0].width;
379 | };
380 |
381 | // Abstract methods
382 | this.listen = function () {}; // on start, one time
383 | this.extend = function () {}; // each time configure triggered
384 | this.init = function () {}; // each time configure triggered
385 | this.change = function (v) {}; // on change
386 | this.val = function (v) {}; // on release
387 | this.xy2val = function (x, y, method) {}; //
388 | this.draw = function () {}; // on change / on release
389 | this.clear = function () { this._clear(); };
390 |
391 | // Utils
392 | this.h2rgba = function (h, a) {
393 | var rgb;
394 | h = h.substring(1,7)
395 | rgb = [parseInt(h.substring(0,2),16)
396 | ,parseInt(h.substring(2,4),16)
397 | ,parseInt(h.substring(4,6),16)];
398 | return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")";
399 | };
400 |
401 | this.copy = function (f, t) {
402 | for (var i in f) { t[i] = f[i]; }
403 | };
404 | };
405 |
406 |
407 | /**
408 | * k.Dial
409 | */
410 | k.Dial = function () {
411 | k.o.call(this);
412 |
413 | this.startAngle = null;
414 | this.xy = null;
415 | this.radius = null;
416 | this.lineWidth = null;
417 | this.cursorExt = null;
418 | this.w2 = null;
419 | this.PI2 = 2*Math.PI;
420 |
421 | this.extend = function () {
422 | this.o = $.extend(
423 | {
424 | bgColor : this.$.data('bgcolor') || '#EEEEEE',
425 | angleOffset : this.$.data('angleoffset') || 0,
426 | angleArc : this.$.data('anglearc') || 360,
427 | flatMouse : this.$.data('flatMouse'),
428 | inline : true
429 | }, this.o
430 | );
431 | };
432 |
433 | this.val = function (v) {
434 | if (null != v) {
435 | this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v;
436 | this.v = this.cv;
437 | this.$.val(this.v);
438 | this._draw();
439 | } else {
440 | return this.v;
441 | }
442 | };
443 |
444 | this.xy2val = function (x, y, m) {
445 | var a, ret;
446 |
447 | if ((m === 'mouse') && (this.o.flatMouse)) {
448 | a = ((this.my - y) + (x - this.mx)) / (this.o.height);
449 | ret = ~~ (a * (this.o.max - this.o.min) + parseFloat(this.v));
450 | ret = max(min(ret, this.o.max), this.o.min);
451 | } else {
452 | a = Math.atan2(
453 | x - (this.x + this.w2)
454 | , - (y - this.y - this.w2)
455 | ) - this.angleOffset;
456 |
457 | if(this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) {
458 | // if isset angleArc option, set to min if .5 under min
459 | a = 0;
460 | } else if (a < 0) {
461 | a += this.PI2;
462 | }
463 |
464 | ret = ~~ (0.5 + (a * (this.o.max - this.o.min) / this.angleArc))
465 | + this.o.min;
466 | }
467 |
468 | this.o.stopper
469 | && (ret = max(min(ret, this.o.max), this.o.min));
470 |
471 | return ret;
472 | };
473 |
474 | this.listen = function () {
475 | // bind MouseWheel
476 | var s = this,
477 | mw = function (e) {
478 | if(s.o.noScroll)
479 | return;
480 |
481 | e.preventDefault();
482 |
483 | var ori = e.originalEvent
484 | ,deltaX = ori.detail || ori.wheelDeltaX
485 | ,deltaY = ori.detail || ori.wheelDeltaY
486 | ,v = parseInt(s.$.val()) + (deltaX>0 || deltaY>0 ? 1 : deltaX<0 || deltaY<0 ? -1 : 0);
487 |
488 | if (
489 | s.cH
490 | && (s.cH(v) === false)
491 | ) return;
492 |
493 | s.val(v);
494 | }
495 | , kval, to, m = 1, kv = {37:-1, 38:1, 39:1, 40:-1};
496 |
497 | this.$
498 | .bind(
499 | "keydown"
500 | ,function (e) {
501 |
502 | var kc = e.keyCode;
503 |
504 | // numpad support
505 | if(kc >= 96 && kc <= 105) {
506 | kc = e.keyCode = kc - 48;
507 | }
508 |
509 | kval = parseInt(String.fromCharCode(kc));
510 |
511 | if (isNaN(kval)) {
512 |
513 | (kc !== 13) // enter
514 | && (kc !== 8) // bs
515 | && (kc !== 9) // tab
516 | && (kc !== 189) // -
517 | && e.preventDefault();
518 |
519 | // arrows
520 | if ($.inArray(kc,[37,38,39,40]) > -1) {
521 | e.preventDefault();
522 |
523 | var v = parseInt(s.$.val()) + kv[kc] * m;
524 |
525 | s.o.stopper
526 | && (v = max(min(v, s.o.max), s.o.min));
527 |
528 | s.change(v);
529 | s._draw();
530 |
531 | // long time keydown speed-up
532 | to = window.setTimeout(
533 | function () { m*=2; }
534 | ,30
535 | );
536 | }
537 | }
538 | }
539 | )
540 | .bind(
541 | "keyup"
542 | ,function (e) {
543 | if (isNaN(kval)) {
544 | if (to) {
545 | window.clearTimeout(to);
546 | to = null;
547 | m = 1;
548 | s.val(s.$.val());
549 | }
550 | } else {
551 | // kval postcond
552 | (s.$.val() > s.o.max && s.$.val(s.o.max))
553 | || (s.$.val() < s.o.min && s.$.val(s.o.min));
554 | }
555 |
556 | }
557 | );
558 |
559 | this.$c.bind("mousewheel DOMMouseScroll", mw);
560 | this.$.bind("mousewheel DOMMouseScroll", mw)
561 | };
562 |
563 | this.init = function () {
564 |
565 | if (
566 | this.v < this.o.min
567 | || this.v > this.o.max
568 | ) this.v = this.o.min;
569 |
570 | this.$.val(this.v);
571 | this.w2 = this.o.width / 2;
572 | this.cursorExt = this.o.cursor / 100;
573 | this.xy = this.w2;
574 | this.lineWidth = this.xy * this.o.thickness;
575 | this.radius = this.xy - this.lineWidth / 2;
576 |
577 | this.o.angleOffset
578 | && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset);
579 |
580 | this.o.angleArc
581 | && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc);
582 |
583 | // deg to rad
584 | this.angleOffset = this.o.angleOffset * Math.PI / 180;
585 | this.angleArc = this.o.angleArc * Math.PI / 180;
586 |
587 | // compute start and end angles
588 | this.startAngle = 1.5 * Math.PI + this.angleOffset;
589 | this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc;
590 |
591 | var s = max(
592 | String(Math.abs(this.o.max)).length
593 | , String(Math.abs(this.o.min)).length
594 | , 2
595 | ) + 2;
596 |
597 | this.o.displayInput
598 | && this.i.css({
599 | 'width' : ((this.o.width / 2 + 4) >> 0) + 'px'
600 | ,'height' : ((this.o.width / 3) >> 0) + 'px'
601 | ,'position' : 'absolute'
602 | ,'vertical-align' : 'middle'
603 | ,'margin-top' : ((this.o.width / 3) >> 0) + 'px'
604 | ,'margin-left' : '-' + ((this.o.width * 3 / 4 + 2) >> 0) + 'px'
605 | ,'border' : 0
606 | ,'background' : 'none'
607 | ,'font' : 'bold ' + ((this.o.width / s) >> 0) + 'px Arial'
608 | ,'text-align' : 'center'
609 | ,'color' : this.o.fgColor
610 | ,'padding' : '0px'
611 | ,'-webkit-appearance': 'none'
612 | })
613 | || this.i.css({
614 | 'width' : '0px'
615 | ,'visibility' : 'hidden'
616 | });
617 | };
618 |
619 | this.change = function (v) {
620 | this.cv = v;
621 | this.$.val(v);
622 | };
623 |
624 | this.angle = function (v) {
625 | return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min);
626 | };
627 |
628 | this.draw = function () {
629 |
630 | var c = this.g, // context
631 | a = this.angle(this.cv) // Angle
632 | , sat = this.startAngle // Start angle
633 | , eat = sat + a // End angle
634 | , sa, ea // Previous angles
635 | , r = 1;
636 |
637 | c.lineWidth = this.lineWidth;
638 |
639 | /*for(o in this.o.context) {
640 | c[o] = this.o.context[o];
641 | }*/
642 |
643 | this.o.cursor
644 | && (sat = eat - this.cursorExt)
645 | && (eat = eat + this.cursorExt);
646 |
647 | c.beginPath();
648 | c.strokeStyle = this.o.bgColor;
649 | c.arc(this.xy, this.xy, this.radius, this.endAngle, this.startAngle, true);
650 | c.stroke();
651 |
652 | if (this.o.displayPrevious) {
653 | ea = this.startAngle + this.angle(this.v);
654 | sa = this.startAngle;
655 | this.o.cursor
656 | && (sa = ea - this.cursorExt)
657 | && (ea = ea + this.cursorExt);
658 |
659 | c.beginPath();
660 | c.strokeStyle = this.pColor;
661 | c.arc(this.xy, this.xy, this.radius, sa, ea, false);
662 | c.stroke();
663 | r = (this.cv == this.v);
664 | }
665 |
666 | c.beginPath();
667 | c.strokeStyle = r ? this.o.fgColor : this.fgColor ;
668 | c.arc(this.xy, this.xy, this.radius, sat, eat, false);
669 | c.stroke();
670 | };
671 |
672 | this.cancel = function () {
673 | this.val(this.v);
674 | };
675 | };
676 |
677 | $.fn.dial = $.fn.knob = function (o) {
678 | return this.each(
679 | function () {
680 | var d = new k.Dial();
681 | d.o = o;
682 | d.$ = $(this);
683 | d.run();
684 | }
685 | ).parent();
686 | };
687 |
688 |
689 | /**
690 | * k.XY
691 | */
692 | k.XY = function () {
693 | k.o.call(this);
694 |
695 | this.m = [];
696 | this.p = [];
697 | this.f = []; // factor
698 | this.s = {0:1,1:-1};
699 | this.cur2 = 0;
700 | this.cursor = 0;
701 | this.v = {};
702 | this.div = null;
703 |
704 | this.extend = function () {
705 | this.o = $.extend(
706 | {
707 | min : this.$.data('min') || 0,
708 | max : this.$.data('max') || 100,
709 | width : this.$.data('width') || 200,
710 | height : this.$.data('height') || 200
711 | }, this.o
712 | );
713 | };
714 |
715 | this._coord = function() {
716 | for(var i in this.v) {
717 | this.m[i] = ~~ (0.5 + ((this.s[i] * this.v[i] - this.o.min) / this.f[i]) + this.cur2) ;
718 | this.p[i] = this.m[i];
719 | }
720 | };
721 |
722 | this.init = function () {
723 | this.cursor = this.o.cursor || 30;
724 | this.cur2 = this.cursor / 2;
725 |
726 | this.f[0] = (this.o.max - this.o.min) / (this.o.width - this.cursor);
727 | this.f[1] = (this.o.max - this.o.min) / (this.o.height - this.cursor);
728 |
729 | if (!this.isInit) {
730 | this._coord();
731 | }
732 |
733 | if(this.o.displayInput) {
734 | var s = this;
735 | this.$.css({
736 | 'margin-top' : '-30px'
737 | , 'border' : 0
738 | , 'font' : '11px Arial'
739 | });
740 |
741 | this.i.each(
742 | function (){
743 | $(this).css({
744 | 'width' : (s.o.width / 4) + 'px'
745 | ,'border' : 0
746 | ,'background' : 'none'
747 | ,'color' : s.o.fgColor
748 | ,'padding' : '0px'
749 | ,'-webkit-appearance': 'none'
750 | });
751 | });
752 | } else {
753 | this.$.css({
754 | 'width' : '0px'
755 | ,'visibility' : 'hidden'
756 | });
757 | }
758 | };
759 |
760 | this.xy2val = function (x, y) {
761 | this.m[0] = max(this.cur2, min(x - this.x, this.o.width - this.cur2));
762 | this.m[1] = max(this.cur2, min(y - this.y, this.o.height - this.cur2));
763 |
764 | return {
765 | 0 : ~~ (this.o.min + (this.m[0] - this.cur2) * this.f[0]),
766 | 1 : ~~ (this.o.min + (this.o.height - this.m[1] - this.cur2) * this.f[1])
767 | };
768 | };
769 |
770 | this.change = function (v) {
771 | this.cv = v;
772 | this.i[0].val(this.cv[0]);
773 | this.i[1].val(this.cv[1]);
774 | };
775 |
776 | this.val = function (v) {
777 | if (null !== v) {
778 | this.cv = v;
779 | this.copy(this.cv, this.v);
780 | this._coord();
781 | this._draw();
782 | } else {
783 | return this.v;
784 | }
785 | };
786 |
787 | this.cancel = function () {
788 | this.copy(this.v, this.cv);
789 | this.i[0].val(this.cv[0]);
790 | this.i[1].val(this.cv[1]);
791 | this.m[0] = this.p[0];
792 | this.m[1] = this.p[1];
793 | this._draw();
794 | };
795 |
796 | this.draw = function () {
797 |
798 | var c = this.g
799 | , r = 1;
800 |
801 | if (this.o.displayPrevious) {
802 | c.beginPath();
803 | c.lineWidth = this.cursor;
804 | c.strokeStyle = this.pColor;
805 | c.moveTo(this.p[0], this.p[1] + this.cur2);
806 | c.lineTo(this.p[0], this.p[1] - this.cur2);
807 | c.stroke();
808 | r = (this.cv[0] == this.v[0] && this.cv[1] == this.v[1]);
809 | }
810 |
811 | c.beginPath();
812 | c.lineWidth = this.cursor;
813 | c.strokeStyle = r ? this.o.fgColor : this.fgColor;
814 | c.moveTo(this.m[0], this.m[1] + this.cur2);
815 | c.lineTo(this.m[0], this.m[1] - this.cur2);
816 | c.stroke();
817 | };
818 | };
819 |
820 | $.fn.xy = function (o) {
821 | return this.each(
822 | function () {
823 | var x = new k.XY();
824 | x.$ = $(this);
825 | x.o = o;
826 | x.run();
827 | }
828 | ).parent();
829 | };
830 |
831 |
832 | /**
833 | * k.Bars
834 | */
835 | k.Bars = function () {
836 | k.o.call(this);
837 |
838 | this.bar = null;
839 | this.mid = null;
840 | this.col = null;
841 | this.colWidth = null;
842 | this.fontSize = null;
843 | this.displayMidLine = false;
844 |
845 | this.extend = function () {
846 |
847 | this.o = $.extend(
848 | {
849 | min : this.$.data('min') || 0,
850 | max : this.$.data('max') || 100,
851 | width : this.$.data('width') || 600,
852 | displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'),
853 | height : (this.$.data('height') || 200),
854 | fgColor : this.$.data('fgcolor') || '#87CEEB',
855 | bgColor : this.$.data('bgcolor') || '#CCCCCC',
856 | cols : this.$.data('cols') || 8,
857 | spacing : this.$.data('spacing') || 1
858 | }
859 | ,this.o
860 | );
861 |
862 | // initialize colWith
863 | (this.o.cols == 1) && (this.o.spacing = 0);
864 | this.colWidth = (((this.o.width - this.o.spacing * this.o.cols) / this.o.cols) >> 0);
865 |
866 | if(this.o.displayInput) {
867 | this.fontSize = max(~~ (this.colWidth/3), 10);
868 | this.o.height -= this.fontSize;
869 | }
870 | };
871 |
872 | this.xy2val = function (x, y) {
873 | var cw = this.colWidth + this.o.spacing
874 | ,val = (
875 | max(this.o.min
876 | , min(this.o.max, - ( - this.mid + (y - this.y)) / this.bar))
877 | ) >> 0
878 | ,ret = {};
879 |
880 | this.col = max(0, min(this.o.cols-1, ((x - this.x) / cw) >> 0));
881 | ret[this.col] = val;
882 | return ret;
883 | };
884 |
885 | this.init = function () {
886 |
887 | this.bar = this.o.height / (this.o.max - this.o.min);
888 | this.mid = (this.o.max * this.bar) >> 0;
889 | this.displayMidLine = this.o.cursor && this.o.min < 0;
890 |
891 | if(this.o.displayInput) {
892 | var s = this;
893 | this.$.css({
894 | 'margin' : '0px'
895 | ,'border' : 0
896 | ,'padding' : '0px'
897 | });
898 |
899 | this.i.each(
900 | function (){
901 | $(this).css({
902 | 'width' : (s.colWidth - 4 + s.o.spacing) + 'px'
903 | ,'border' : 0
904 | ,'background' : 'none'
905 | ,'font' : s.fontSize+'px Arial' //this.fontSize
906 | ,'color' : s.o.fgColor
907 | ,'margin' : '0px'
908 | ,'padding' : '0px'
909 | ,'-webkit-appearance': 'none'
910 | ,'text-align' : 'center'
911 | });
912 | });
913 | } else {
914 | this.$.css({
915 | 'width' : '0px'
916 | ,'visibility' : 'hidden'
917 | });
918 | }
919 | };
920 |
921 | this.change = function (v) {
922 | for (var i in v) {
923 | this.cv[i] = v[i];
924 | this.i[i].val(this.cv[i]);
925 | }
926 | };
927 |
928 | this.val = function (v) {
929 | if (null !== v) {
930 | this.copy(v, this.cv);
931 | this.copy(this.cv, this.v);
932 |
933 | // reset cur col
934 | this.col = null;
935 | this._draw();
936 | } else {
937 | return this.v;
938 | }
939 | };
940 |
941 | this.cancel = function () {
942 | this.copy(this.v, this.cv);
943 |
944 | // reset cur col
945 | this.col = null;
946 | this._draw();
947 | };
948 |
949 | this._bar = function (col) {
950 |
951 | var x = (col * (this.colWidth + this.o.spacing) + this.colWidth / 2);
952 |
953 | if (this.displayMidLine) {
954 | this.g.beginPath();
955 | this.g.lineWidth = this.colWidth;
956 | this.g.strokeStyle = this.o.fgColor;
957 | this.g.moveTo(x, this.mid);
958 | this.g.lineTo(x, this.mid + 1);
959 | this.g.stroke();
960 | }
961 |
962 | if (this.o.displayPrevious) {
963 | this.g.beginPath();
964 | this.g.lineWidth = this.colWidth;
965 | this.g.strokeStyle = (this.cv[col] == this.v[col]) ? this.o.fgColor : this.pColor;
966 | if (this.o.cursor) {
967 | this.g.lineTo(x, this.mid - ((this.v[col] * this.bar) >> 0) + this.o.cursor / 2);
968 | } else {
969 | this.g.moveTo(x, this.mid);
970 | }
971 | this.g.lineTo(x, this.mid - ((this.v[col] * this.bar) >> 0) - this.o.cursor / 2);
972 | this.g.stroke();
973 | }
974 |
975 | this.g.beginPath();
976 | this.g.lineWidth = this.colWidth;
977 | this.g.strokeStyle = this.fgColor;
978 | if (this.o.cursor) {
979 | this.g.lineTo(x, this.mid - ((this.cv[col] * this.bar) >> 0) + this.o.cursor / 2);
980 | } else {
981 | this.g.moveTo(x, this.mid);
982 | }
983 | this.g.lineTo(x, this.mid - ((this.cv[col] * this.bar) >> 0) - this.o.cursor / 2);
984 | this.g.stroke();
985 | };
986 |
987 | this.clear = function () {
988 | if (this.col) {
989 | // current col
990 | this.c.clearRect(
991 | this.col * (this.colWidth + this.o.spacing)
992 | , 0
993 | , this.colWidth + this.o.spacing
994 | , this.o.height
995 | );
996 | } else {
997 | this._clear();
998 | }
999 | }
1000 |
1001 | this.draw = function () {
1002 | if (this.col) {
1003 | this._bar(this.col);
1004 | } else {
1005 | for (var i = 0; i < this.o.cols; i++) {
1006 | this._bar(i);
1007 | }
1008 | }
1009 | };
1010 | };
1011 |
1012 | $.fn.bars = function (o) {
1013 | return this.each(
1014 | function () {
1015 | var b = new k.Bars();
1016 | b.$ = $(this);
1017 | b.o = o;
1018 | b.run();
1019 | }
1020 | ).parent();
1021 | };
1022 | })(jQuery);
--------------------------------------------------------------------------------