Skip to content

Instantly share code, notes, and snippets.

@chapko
Created December 2, 2012 14:49
Show Gist options
  • Save chapko/4189147 to your computer and use it in GitHub Desktop.
Save chapko/4189147 to your computer and use it in GitHub Desktop.
jQuery UI knob
(function($) {
if(!$.fn.rotate){
var style = $('head')[0].style;
var transform = "transform WebkitTransform OTransform msTransform MozTransform".split(" ").filter(function(prop) {
return style[prop] !== undefined;
})[0];
$.fn.rotate = function(deg) {
if(arguments.length) {
return this.each(function(index, el) {
el.style[transform] = 'rotate(' + deg + 'deg)';
})
}
var el = this[0];
var matches = /rotation\((\d+)deg\)/.exec(el.style[transform]);
return (matches && matches[1]) || 0;
}
}
var deg = function(rad) {
return rad / Math.PI * 180;
}
var rad = function(deg) {
return deg * Math.PI / 180;
}
$.widget( "ui.knob", $.ui.rangeable, {
options : {
startAngle : 0,
endAngle : Math.PI * 2
},
_create: function() {
this.knobElement = this.options.knob ? $(this.options.knob) : this.element;
this._super();
},
_addClasses: function() {
this.element.addClass('ui-knob');
this.knobElement.addClass('ui-knob-rotator');
},
_getAngleFromValue: function(value) {
var o = this.options;
return (value - o.min) / (o.max - o.min) * (o.endAngle - o.startAngle);
},
_value: function(newValue, force) {
this.element.rotate(deg(this._getAngleFromValue(newValue)));
}
});
}(jQuery));
(function($) {
$.widget( "ui.rangeable", $.ui.mouse, {
widgetEventPrefix: "range",
options: {
disabled: false,
cancel: '',
max: 100,
min: 0,
step: 1,
stepDistance: 5,
value: 0,
instantUpdate: true, // update value while dragging ?
orientation: "vertical",
nativeValue: true // if element has value property - use it ?
},
_create: function() {
var o = this.options;
this._addClasses();
// max value with proper stepping
this._stepMax = o.min + Math.floor((o.max - o.min) / o.step) * o.step;
this.value(o.value, true);
var that = this;
this.element.on('mousedown', function(event) {
if(event.which === 2) { //middle button
that.value(o.value);
event.preventDefault();
}
})
this._mouseInit();
},
_destroy: function() {
this._removeClasses();
this._mouseDestroy();
},
_addClasses: function() {
this.element.addClass("ui-rangeable");
(this.options.disabled && this.element.addClass("ui-rangeable-disabled"));
},
_removeClasses: function() {
this.element.removeClass("ui-rangeable ui-rangeable-disabled");
},
_mouseStart: function(event) {
this.startX = event.pageX;
this.startY = event.pageY;
this.startV = this.value();
return true;
},
_mouseDrag: function(event) {
this.dragX = event.pageX;
this.dragY = event.pageY;
if(this.options.instantUpdate) {
this.value(this.startV + this._getDraggedValue());
}
},
_mouseStop: function(event) {
this.value(this.startV + this._getDraggedValue());
return true;
},
_getDraggedValue: function() {
var delta = this.options.orientation === "vertical" ?
this.startY - this.dragY :
this.dragX - this.startX;
return delta / this.options.stepDistance;
},
_cropValue: function(value) {
// fit min-max range
var o = this.options;
value = value > o.max ? this._stepMax :
value < o.min ? o.min :
value;
// apply proper step
return Math.round(value / o.step) * o.step;
},
value: function(newValue, force) {
var nativeValue = this.element[0].hasOwnProperty('value') && this.options.nativeValue;
if(arguments.length) {
var oldValue = this.value();
newValue = this._cropValue(newValue);
if(!force && oldValue === newValue) {
return;
}
if(!force && !this._trigger("change", null, { now: newValue, old: oldValue })) {
return;
}
nativeValue ? (this.element.val(newValue)) : (this._value = newValue);
this._value(newValue, force);
return;
}
return nativeValue ? Number(this.element.val()) : this._value;
},
// for overriding
_value: function() {}
});
}(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment