194 lines
5.9 KiB
JavaScript
194 lines
5.9 KiB
JavaScript
(function($K)
|
|
{
|
|
$K.add('module', 'slider', {
|
|
init: function(app, context)
|
|
{
|
|
this.app = app;
|
|
this.$win = app.$win;
|
|
this.$doc = app.$doc;
|
|
|
|
// defaults
|
|
var defaults = {
|
|
min: 0,
|
|
max: 100,
|
|
step: 1,
|
|
value: 0,
|
|
target: false
|
|
};
|
|
|
|
// context
|
|
this.context = context;
|
|
this.params = context.getParams(defaults);
|
|
this.$element = context.getElement();
|
|
this.$target = context.getTarget();
|
|
|
|
// local
|
|
this.isTicks = false;
|
|
},
|
|
|
|
// public
|
|
start: function()
|
|
{
|
|
this._buildTrack();
|
|
this._buildFill();
|
|
this._buildHandle();
|
|
this._buildTicks();
|
|
|
|
this.update();
|
|
|
|
this.$win.on('resize.kube.slider', this._resize.bind(this));
|
|
this.$element.on('mousedown.kube.slider touchstart.kube.slider', this._handleDown.bind(this));
|
|
},
|
|
stop: function()
|
|
{
|
|
this.$win.off('.kube.slider');
|
|
this.$doc.off('.kube.slider');
|
|
this.$element.off('.kube.slider');
|
|
},
|
|
update: function(value)
|
|
{
|
|
this.value = (value) ? value : this.params.value;
|
|
this.value = (this.value < this.params.min) ? this.params.min : this.value;
|
|
|
|
this.handleWidth = this.$handle.width();
|
|
this.trackWidth = this.$track.width();
|
|
this.maxHandlePosition = this.trackWidth - this.handleWidth;
|
|
this.fixPosition = this.handleWidth / 2;
|
|
this.position = this._getPositionFromValue(this.value);
|
|
|
|
this._setPosition(this.position);
|
|
this._setTarget();
|
|
},
|
|
// private
|
|
_resize: function()
|
|
{
|
|
this._buildTicks();
|
|
this.update(this.value);
|
|
},
|
|
_isDisabled: function()
|
|
{
|
|
return (this.$element.hasClass('is-disabled') || this.$element.attr('disabled'));
|
|
},
|
|
_buildTrack: function()
|
|
{
|
|
this.$track = $K.dom('<div />');
|
|
this.$track.addClass('slider-track');
|
|
|
|
this.$element.prepend(this.$track);
|
|
},
|
|
_buildFill: function()
|
|
{
|
|
this.$fill = $K.dom('<div />');
|
|
this.$fill.addClass('slider-fill');
|
|
|
|
this.$track.append(this.$fill);
|
|
},
|
|
_buildHandle: function()
|
|
{
|
|
this.$handle = $K.dom('<div />');
|
|
this.$handle.addClass('slider-handle');
|
|
|
|
this.$track.append(this.$handle);
|
|
},
|
|
_buildTicks: function()
|
|
{
|
|
this.$ticks = this.$element.find('.slider-ticks span');
|
|
|
|
var size = this.$ticks.length;
|
|
this.isTicks = (size !== 0)
|
|
|
|
if (!this.isTicks) return;
|
|
|
|
var handleWidth = this.$handle.width();
|
|
var width = this.$element.width() - handleWidth;
|
|
var fix = handleWidth/2;
|
|
var step = width/(size-1);
|
|
var start = fix;
|
|
|
|
this.$ticks.each(function(node, i)
|
|
{
|
|
var $node = $K.dom(node);
|
|
var left = start + step * i;
|
|
|
|
$node.css({ 'left': left + 'px', 'width': step + 'px', 'text-indent': '-' + (step-fix) + 'px' });
|
|
});
|
|
},
|
|
_handleDown: function(e)
|
|
{
|
|
e.preventDefault();
|
|
|
|
if (this._isDisabled()) return;
|
|
|
|
this.$doc.on('mousemove.kube.slider touchmove.kube.slider', this._handleMove.bind(this));
|
|
this.$doc.on('mouseup.kube.slider touchend.kube.slider', this._handleEnd.bind(this));
|
|
|
|
var pos = (e.touches && e.touches.length > 0) ? e.changedTouches[0].clientX : e.clientX;
|
|
var trackPos = this.$track.offset().left;
|
|
var setPos = (pos - trackPos - this.fixPosition);
|
|
|
|
this._setPosition(setPos);
|
|
this._setTarget();
|
|
|
|
},
|
|
_handleMove: function(e)
|
|
{
|
|
e.preventDefault();
|
|
var pos = (e.touches && e.touches.length > 0) ? e.changedTouches[0].clientX : e.clientX;
|
|
var trackPos = this.$track.offset().left;
|
|
var setPos = (pos - trackPos - this.fixPosition);
|
|
|
|
this._setPosition(setPos);
|
|
this._setTarget();
|
|
},
|
|
_handleEnd: function(e)
|
|
{
|
|
e.preventDefault();
|
|
this.$doc.off('.kube.slider');
|
|
},
|
|
_setPosition: function(pos)
|
|
{
|
|
pos = this._getEdge(pos, 0, this.maxHandlePosition);
|
|
|
|
var value = this._getValueFromPosition(pos);
|
|
var newPos = this._getPositionFromValue(value);
|
|
|
|
// update ui
|
|
this.$fill.css('width', (newPos + this.fixPosition) + 'px');
|
|
this.$handle.css('left', newPos + 'px');
|
|
|
|
// update globals
|
|
this.position = newPos;
|
|
this.value = value;
|
|
|
|
},
|
|
_setTarget: function()
|
|
{
|
|
this.app.broadcast('slider.set', this, this.value);
|
|
if (this.$target.length === 0) return;
|
|
|
|
var tag = this.$target.get().tagName;
|
|
|
|
if (tag === 'INPUT' || tag === 'SELECT') this.$target.val(this.value);
|
|
else this.$target.text(this.value);
|
|
},
|
|
_getPositionFromValue: function(value)
|
|
{
|
|
var percentage = (value - this.params.min)/(this.params.max - this.params.min);
|
|
return pos = (!Number.isNaN(percentage)) ? percentage * this.maxHandlePosition : 0;
|
|
},
|
|
_getValueFromPosition: function(pos)
|
|
{
|
|
var percentage = ((pos) / (this.maxHandlePosition || 1));
|
|
var value = this.params.step * Math.round(percentage * (this.params.max - this.params.min) / this.params.step) + this.params.min;
|
|
|
|
return Number((value).toFixed((this.params.step + '').replace('.', '').length - 1));
|
|
},
|
|
_getEdge: function(pos, min, max)
|
|
{
|
|
if (pos < min) return min;
|
|
if (pos > max) return max;
|
|
|
|
return pos;
|
|
}
|
|
});
|
|
})(Kube); |