vendor: 6,473 bytes, lines 1-192
1/*!jQuery Knob*/ 2/** 3 * Downward compatible, touchable dial 4 * 5 * Version: 1.2.8 6 * Requires: jQuery v1.7+ 7 * 8 * Copyright (c) 2012 Anthony Terrien 9 * Under MIT License (http://www.opensource.org/licenses/mit-license.php) 10 * 11 * Thanks to vor, eskimoblood, spiffistan, FabrizioC 12 */ 13(function (factory) { 14 if (typeof define === 'function' && define.amd) { 15 // AMD. Register as an anonymous module. 16 define(['jquery'], factory); 17 } else { 18 // Browser globals 19 factory(jQuery); 20 } 21}(function ($) { 22 23 /** 24 * Kontrol library 25 */ 26 "use strict"; 27 28 /** 29 * Definition of globals and core 30 */ 31 var k = {}, // kontrol 32 max = Math.max, 33 min = Math.min; 34 35 k.c = {}; 36 k.c.d = $(document); 37 k.c.t = function (e) { 38 return e.originalEvent.touches.length - 1; 39 }; 40 41 /** 42 * Kontrol Object 43 * 44 * Definition of an abstract UI control 45 * 46 * Each concrete component must call this one. 47 * <code> 48 * k.o.call(this); 49 * </code> 50 */ 51 k.o = function () { 52 var s = this; 53 54 this.o = null; // array of options 55 this.$ = null; // jQuery wrapped element 56 this.i = null; // mixed HTMLInputElement or array of HTMLInputElement 57 this.g = null; // deprecated 2D graphics context for 'pre-rendering' 58 this.v = null; // value ; mixed array or integer 59 this.cv = null; // change value ; not commited value 60 this.x = 0; // canvas x position 61 this.y = 0; // canvas y position 62 this.w = 0; // canvas width 63 this.h = 0; // canvas height 64 this.$c = null; // jQuery canvas element 65 this.c = null; // rendered canvas context 66 this.t = 0; // touches index 67 this.isInit = false; 68 this.fgColor = null; // main color 69 this.pColor = null; // previous color 70 this.dH = null; // draw hook 71 this.cH = null; // change hook 72 this.eH = null; // cancel hook 73 this.rH = null; // release hook 74 this.scale = 1; // scale factor 75 this.relative = false; 76 this.relativeWidth = false; 77 this.relativeHeight = false; 78 this.$div = null; // component div 79 80 this.run = function () { 81 var cf = function (e, conf) { 82 var k; 83 for (k in conf) { 84 s.o[k] = conf[k]; 85 } 86 s._carve().init(); 87 s._configure() 88 ._draw(); 89 }; 90 91 if(this.$.data('kontroled')) return; 92 this.$.data('kontroled', true); 93 94 this.extend(); 95 this.o = $.extend( 96 { 97 // Config 98 min : this.$.data('min') !== undefined ? this.$.data('min') : 0, 99 max : this.$.data('max') !== undefined ? this.$.data('max') : 100, 100 stopper : true, 101 readOnly : this.$.data('readonly') || (this.$.attr('readonly') === 'readonly'), 102 103 // UI 104 cursor : (this.$.data('cursor') === true && 30) || 105 this.$.data('cursor') || 0, 106 thickness : ( 107 this.$.data('thickness') && 108 Math.max(Math.min(this.$.data('thickness'), 1), 0.01) 109 ) || 0.35, 110 lineCap : this.$.data('linecap') || 'butt', 111 width : this.$.data('width') || 200, 112 height : this.$.data('height') || 200, 113 displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'), 114 displayPrevious : this.$.data('displayprevious'), 115 fgColor : this.$.data('fgcolor') || '#87CEEB', 116 inputColor: this.$.data('inputcolor'), 117 font: this.$.data('font') || 'Arial', 118 fontWeight: this.$.data('font-weight') || 'bold', 119 inline : false, 120 step : this.$.data('step') || 1, 121 rotation: this.$.data('rotation'), 122 123 // Hooks 124 draw : null, // function () {} 125 change : null, // function (value) {} 126 cancel : null, // function () {} 127 release : null, // function (value) {} 128 129 // Output formatting, allows to add unit: %, ms ... 130 format: function(v) { 131 return v; 132 }, 133 parse: function (v) { 134 return parseFloat(v); 135 } 136 }, this.o 137 ); 138 139 // finalize options 140 this.o.flip = this.o.rotation === 'anticlockwise' || this.o.rotation === 'acw'; 141 if(!this.o.inputColor) { 142 this.o.inputColor = this.o.fgColor; 143 } 144 145 // routing value 146 if(this.$.is('fieldset')) { 147 148 // fieldset = array of integer 149 this.v = {}; 150 this.i = this.$.find('input'); 151 this.i.each(function(k) { 152 var $this = $(this); 153 s.i[k] = $this; 154 s.v[k] = s.o.parse($this.val()); 155 156 $this.bind( 157 'change blur' 158 , function () { 159 var val = {}; 160 val[k] = $this.val(); 161 s.val(val); 162 } 163 ); 164 }); 165 this.$.find('legend').remove(); 166 167 } else { 168 169 // input = integer 170 this.i = this.$; 171 this.v = this.o.parse(this.$.val()); 172 (this.v === '') && (this.v = this.o.min); 173 174 this.$.bind( 175 'change blur' 176 , function () { 177 s.val(s._validate(s.o.parse(s.$.val()))); 178 } 179 ); 180 181 } 182 183 (!this.o.displayInput) && this.$.hide(); 184 185 // adds needed DOM elements (canvas, div) 186 this.$c = $(document.createElement('canvas')).attr({ 187 width: this.o.width, 188 height: this.o.height 189 }); 190 191 // wraps all elements in a div 192 // add to DOM before Canvas init is triggered
193 this.$div = $('<div style="' 194 + (this.o.inline ? 'display:inline;' : '') 195 + 'width:' + this.o.width + 'px;height:' + this.o.height + 'px;' 196 + '"></div>'); 197 198 this.$.wrap(this.$div).before(this.$c); 199 this.$div = this.$.parent(); 200 201 if (typeof G_vmlCanvasManager !== 'undefined') { 202 G_vmlCanvasManager.initElement(this.$c[0]); 203 } 204 205 this.c = this.$c[0].getContext ? this.$c[0].getContext('2d') : null; 206 207 if (!this.c) { 208 throw { 209 name: "CanvasNotSupportedException", 210 message: "Canvas not supported. Please use excanvas on IE8.0.", 211 toString: function(){return this.name + ": " + this.message} 212 } 213 } 214 215 // hdpi support 216 this.scale = (window.devicePixelRatio || 1) / 217 ( 218 this.c.webkitBackingStorePixelRatio || 219 this.c.mozBackingStorePixelRatio || 220 this.c.msBackingStorePixelRatio || 221 this.c.oBackingStorePixelRatio || 222 this.c.backingStorePixelRatio || 1 223 ); 224 225 // detects relative width / height 226 this.relativeWidth = ((this.o.width % 1 !== 0) && 227 this.o.width.indexOf('%')); 228 this.relativeHeight = ((this.o.height % 1 !== 0) && 229 this.o.height.indexOf('%')); 230 this.relative = (this.relativeWidth || this.relativeHeight); 231 232 // computes size and carves the component 233 this._carve(); 234 235 // prepares props for transaction 236 if (this.v instanceof Object) { 237 this.cv = {}; 238 this.copy(this.v, this.cv); 239 } else { 240 this.cv = this.v; 241 } 242 243 // binds configure event 244 this.$ 245 .bind("configure", cf) 246 .parent() 247 .bind("configure", cf); 248 249 // finalize init 250 this._listen() 251 ._configure() 252 ._xy() 253 .init(); 254 255 this.isInit = true; 256 257 this.$.val(this.o.format(this.v)); 258 this._draw(); 259 260 return this; 261 }; 262 263 this._carve = function() { 264 if(this.relative) { 265 var w = this.relativeWidth ? 266 this.$div.parent().width() * 267 parseInt(this.o.width) / 100 : 268 this.$div.parent().width(), 269 h = this.relativeHeight ? 270 this.$div.parent().height() * 271 parseInt(this.o.height) / 100 : 272 this.$div.parent().height(); 273 274 // apply relative 275 this.w = this.h = Math.min(w, h); 276 } else { 277 this.w = this.o.width; 278 this.h = this.o.height; 279 } 280 281 // finalize div 282 this.$div.css({ 283 'width': this.w + 'px', 284 'height': this.h + 'px' 285 }); 286 287 // finalize canvas with computed width 288 this.$c.attr({ 289 width: this.w, 290 height: this.h 291 }); 292 293 // scaling 294 if (this.scale !== 1) { 295 this.$c[0].width = this.$c[0].width * this.scale; 296 this.$c[0].height = this.$c[0].height * this.scale; 297 this.$c.width(this.w); 298 this.$c.height(this.h); 299 } 300 301 return this; 302 } 303 304 this._draw = function () { 305 306 // canvas pre-rendering 307 var d = true; 308 309 s.g = s.c; 310 311 s.clear(); 312 313 s.dH 314 && (d = s.dH()); 315 316 (d !== false) && s.draw(); 317 318 }; 319 320 this._touch = function (e) { 321 322 var touchMove = function (e) { 323 324 var v = s.xy2val( 325 e.originalEvent.touches[s.t].pageX, 326 e.originalEvent.touches[s.t].pageY 327 ); 328 329 if (v == s.cv) return; 330 331 if (s.cH && (s.cH(v) === false)) return; 332 333 s.change(s._validate(v)); 334 s._draw(); 335 }; 336 337 // get touches index 338 this.t = k.c.t(e); 339 340 // First touch 341 touchMove(e); 342 343 // Touch events listeners 344 k.c.d 345 .bind("touchmove.k", touchMove) 346 .bind( 347 "touchend.k" 348 , function () { 349 k.c.d.unbind('touchmove.k touchend.k'); 350 s.val(s.cv); 351 } 352 ); 353 354 return this; 355 }; 356 357 this._mouse = function (e) { 358 359 var mouseMove = function (e) { 360 var v = s.xy2val(e.pageX, e.pageY); 361 362 if (v == s.cv) return; 363 364 if (s.cH && (s.cH(v) === false)) return; 365 366 s.change(s._validate(v)); 367 s._draw(); 368 }; 369 370 // First click 371 mouseMove(e); 372 373 // Mouse events listeners 374 k.c.d 375 .bind("mousemove.k", mouseMove) 376 .bind( 377 // Escape key cancel current change 378 "keyup.k" 379 , function (e) { 380 if (e.keyCode === 27) { 381 k.c.d.unbind("mouseup.k mousemove.k keyup.k"); 382 383 if ( 384 s.eH 385 && (s.eH() === false) 386 ) return; 387 388 s.cancel(); 389 } 390 } 391 ) 392 .bind( 393 "mouseup.k" 394 , function (e) { 395 k.c.d.unbind('mousemove.k mouseup.k keyup.k'); 396 s.val(s.cv); 397 } 398 ); 399 400 return this; 401 }; 402 403 this._xy = function () { 404 var o = this.$c.offset(); 405 this.x = o.left; 406 this.y = o.top; 407 return this; 408 }; 409 410 this._listen = function () { 411 412 if (!this.o.readOnly) { 413 this.$c 414 .bind( 415 "mousedown" 416 , function (e) { 417 e.preventDefault(); 418 s._xy()._mouse(e); 419 } 420 ) 421 .bind( 422 "touchstart" 423 , function (e) { 424 e.preventDefault(); 425 s._xy()._touch(e); 426 } 427 ); 428 429 this.listen(); 430 } else { 431 this.$.attr('readonly', 'readonly'); 432 } 433 434 if(this.relative) { 435 $(window).resize(function() { 436 s._carve()
437 .init(); 438 s._draw(); 439 }); 440 } 441 442 return this; 443 }; 444 445 this._configure = function () { 446 447 // Hooks 448 if (this.o.draw) this.dH = this.o.draw; 449 if (this.o.change) this.cH = this.o.change; 450 if (this.o.cancel) this.eH = this.o.cancel; 451 if (this.o.release) this.rH = this.o.release; 452 453 if (this.o.displayPrevious) { 454 this.pColor = this.h2rgba(this.o.fgColor, "0.4"); 455 this.fgColor = this.h2rgba(this.o.fgColor, "0.6"); 456 } else { 457 this.fgColor = this.o.fgColor; 458 } 459 460 return this; 461 }; 462 463 this._clear = function () { 464 this.$c[0].width = this.$c[0].width; 465 }; 466 467 this._validate = function(v) { 468 return (~~ (((v < 0) ? -0.5 : 0.5) + (v/this.o.step))) * this.o.step; 469 }; 470 471 // Abstract methods 472 this.listen = function () {}; // on start, one time 473 this.extend = function () {}; // each time configure triggered 474 this.init = function () {}; // each time configure triggered 475 this.change = function (v) {}; // on change 476 this.val = function (v) {}; // on release 477 this.xy2val = function (x, y) {}; // 478 this.draw = function () {}; // on change / on release 479 this.clear = function () { this._clear(); }; 480 481 // Utils 482 this.h2rgba = function (h, a) { 483 var rgb; 484 h = h.substring(1,7) 485 rgb = [parseInt(h.substring(0,2),16) 486 ,parseInt(h.substring(2,4),16) 487 ,parseInt(h.substring(4,6),16)]; 488 return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")"; 489 }; 490 491 this.copy = function (f, t) { 492 for (var i in f) { t[i] = f[i]; } 493 }; 494 }; 495 496 497 /** 498 * k.Dial 499 */ 500 k.Dial = function () { 501 k.o.call(this); 502 503 this.startAngle = null; 504 this.xy = null; 505 this.radius = null; 506 this.lineWidth = null; 507 this.cursorExt = null; 508 this.w2 = null; 509 this.PI2 = 2*Math.PI; 510 511 this.extend = function () { 512 this.o = $.extend( 513 { 514 bgColor : this.$.data('bgcolor') || '#EEEEEE', 515 angleOffset : this.$.data('angleoffset') || 0, 516 angleArc : this.$.data('anglearc') || 360, 517 inline : true 518 }, this.o 519 ); 520 }; 521 522 this.val = function (v, triggerRelease) { 523 if (null != v) { 524 525 // reverse format 526 v = this.o.parse(v); 527 528 if ( 529 triggerRelease !== false && (v != this.v) && this.rH && 530 (this.rH(v) === false) 531 ) return; 532 533 this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v; 534 this.v = this.cv; 535 this.$.val(this.o.format(this.v)); 536 this._draw(); 537 } else { 538 return this.v; 539 } 540 }; 541 542 this.xy2val = function (x, y) { 543 var a, ret; 544 545 a = Math.atan2( 546 x - (this.x + this.w2) 547 , - (y - this.y - this.w2) 548 ) - this.angleOffset; 549 550 if (this.o.flip) { 551 a = this.angleArc - a - this.PI2; 552 } 553 554 if(this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) { 555 // if isset angleArc option, set to min if .5 under min 556 a = 0; 557 } else if (a < 0) { 558 a += this.PI2; 559 } 560 561 ret = ~~ (0.5 + (a * (this.o.max - this.o.min) / this.angleArc)) 562 + this.o.min; 563 564 this.o.stopper && (ret = max(min(ret, this.o.max), this.o.min)); 565 566 return ret; 567 }; 568 569 this.listen = function () { 570 // bind MouseWheel 571 var s = this, mwTimerStop, mwTimerRelease, 572 mw = function (e) { 573 e.preventDefault(); 574 575 var ori = e.originalEvent 576 ,deltaX = ori.detail || ori.wheelDeltaX 577 ,deltaY = ori.detail || ori.wheelDeltaY 578 ,v = s._validate(s.o.parse(s.$.val())) 579 + (deltaX>0 || deltaY>
vendor: 4,362 bytes, lines 579-696
5790 ? s.o.step : deltaX<0 || deltaY<0 ? -s.o.step : 0); 580 581 v = max(min(v, s.o.max), s.o.min); 582 583 s.val(v, false); 584 585 if(s.rH) { 586 // Handle mousewheel stop 587 clearTimeout(mwTimerStop); 588 mwTimerStop = setTimeout(function() { 589 s.rH(v); 590 mwTimerStop = null; 591 }, 100); 592 593 // Handle mousewheel releases 594 if(!mwTimerRelease) { 595 mwTimerRelease = setTimeout(function() { 596 if(mwTimerStop) s.rH(v); 597 mwTimerRelease = null; 598 }, 200); 599 } 600 } 601 } 602 , kval, to, m = 1, kv = {37:-s.o.step, 38:s.o.step, 39:s.o.step, 40:-s.o.step}; 603 604 this.$ 605 .bind( 606 "keydown" 607 ,function (e) { 608 var kc = e.keyCode; 609 610 // numpad support 611 if(kc >= 96 && kc <= 105) { 612 kc = e.keyCode = kc - 48; 613 } 614 615 kval = parseInt(String.fromCharCode(kc)); 616 617 if (isNaN(kval)) { 618 619 (kc !== 13) // enter 620 && (kc !== 8) // bs 621 && (kc !== 9) // tab 622 && (kc !== 189) // - 623 && (kc !== 190 || s.$.val().match(/\./)) // . only allowed once 624 && e.preventDefault(); 625 626 // arrows 627 if ($.inArray(kc,[37,38,39,40]) > -1) { 628 e.preventDefault(); 629 630 var v = s.o.parse(s.$.val()) + kv[kc] * m; 631 s.o.stopper && (v = max(min(v, s.o.max), s.o.min)); 632 633 s.change(v); 634 s._draw(); 635 636 // long time keydown speed-up 637 to = window.setTimeout( 638 function () { m *= 2; }, 30 639 ); 640 } 641 } 642 } 643 ) 644 .bind( 645 "keyup" 646 ,function (e) { 647 if (isNaN(kval)) { 648 if (to) { 649 window.clearTimeout(to); 650 to = null; 651 m = 1; 652 s.val(s.$.val()); 653 } 654 } else { 655 // kval postcond 656 (s.$.val() > s.o.max && s.$.val(s.o.max)) 657 || (s.$.val() < s.o.min && s.$.val(s.o.min)); 658 } 659 660 } 661 ); 662 663 this.$c.bind("mousewheel DOMMouseScroll", mw); 664 this.$.bind("mousewheel DOMMouseScroll", mw) 665 }; 666 667 this.init = function () { 668 669 if ( 670 this.v < this.o.min 671 || this.v > this.o.max 672 ) this.v = this.o.min; 673 674 this.$.val(this.v); 675 this.w2 = this.w / 2; 676 this.cursorExt = this.o.cursor / 100; 677 this.xy = this.w2 * this.scale; 678 this.lineWidth = this.xy * this.o.thickness; 679 this.lineCap = this.o.lineCap; 680 this.radius = this.xy - this.lineWidth / 2; 681 682 this.o.angleOffset 683 && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset); 684 685 this.o.angleArc 686 && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc); 687 688 // deg to rad 689 this.angleOffset = this.o.angleOffset * Math.PI / 180; 690 this.angleArc = this.o.angleArc * Math.PI / 180; 691 692 // compute start and end angles 693 this.startAngle = 1.5 * Math.PI + this.angleOffset; 694 this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc; 695 696 var s = max(
697 String(Math.abs(this.o.max)).length 698 , String(Math.abs(this.o.min)).length 699 , 2 700 ) + 2; 701 702 this.o.displayInput 703 && this.i.css({ 704 'width' : ((this.w / 2 + 4) >> 0) + 'px' 705 ,'height' : ((this.w / 3) >> 0) + 'px' 706 ,'position' : 'absolute' 707 ,'vertical-align' : 'middle' 708 ,'margin-top' : ((this.w / 3) >> 0) + 'px' 709 ,'margin-left' : '-' + ((this.w * 3 / 4 + 2) >> 0) + 'px' 710 ,'border' : 0 711 ,'background' : 'none' 712 ,'font' : this.o.fontWeight + ' ' + ((this.w / s) >> 0) + 'px ' + this.o.font 713 ,'text-align' : 'center' 714 ,'color' : this.o.inputColor || this.o.fgColor 715 ,'padding' : '0px' 716 ,'-webkit-appearance': 'none' 717 }) 718 || this.i.css({ 719 'width' : '0px' 720 ,'visibility' : 'hidden' 721 }); 722 }; 723 724 this.change = function (v) { 725 this.cv = v; 726 this.$.val(this.o.format(v)); 727 }; 728 729 this.angle = function (v) { 730 return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min); 731 }; 732 733 this.arc = function (v) { 734 var sa, ea; 735 v = this.angle(v); 736 if (this.o.flip) { 737 sa = this.endAngle + 0.00001; 738 ea = sa - v - 0.00001; 739 } else { 740 sa = this.startAngle - 0.00001; 741 ea = sa + v + 0.00001; 742 } 743 this.o.cursor 744 && (sa = ea - this.cursorExt) 745 && (ea = ea + this.cursorExt); 746 return { 747 s: sa, 748 e: ea, 749 d: this.o.flip && !this.o.cursor 750 }; 751 }; 752 753 this.draw = function () { 754 755 var c = this.g, // context 756 a = this.arc(this.cv) // Arc 757 , pa // Previous arc 758 , r = 1; 759 760 c.lineWidth = this.lineWidth; 761 c.lineCap = this.lineCap; 762 763 c.beginPath(); 764 c.strokeStyle = this.o.bgColor; 765 c.arc(this.xy, this.xy, this.radius, this.endAngle - 0.00001, this.startAngle + 0.00001, true); 766 c.stroke(); 767 768 if (this.o.displayPrevious) { 769 pa = this.arc(this.v); 770 c.beginPath(); 771 c.strokeStyle = this.pColor; 772 c.arc(this.xy, this.xy, this.radius, pa.s, pa.e, pa.d); 773 c.stroke(); 774 r = (this.cv == this.v); 775 } 776 777 c.beginPath(); 778 c.strokeStyle = r ? this.o.fgColor : this.fgColor ; 779 c.arc(this.xy, this.xy, this.radius, a.s, a.e, a.d); 780 c.stroke(); 781 }; 782 783 this.cancel = function () { 784 this.val(this.v); 785 }; 786 }; 787 788 $.fn.dial = $.fn.knob = function (o) { 789 return this.each( 790 function () { 791 var d = new k.Dial(); 792 d.o = o; 793 d.$ = $(this); 794 d.run(); 795 } 796 ).parent(); 797 }; 798 799})); 800
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.