/* Script: Slider.js Class for creating horizontal and vertical slider controls. License: MIT-style license. */ var Slider = new Class({ Implements: [Events, Options], options: {/* onChange: $empty, onComplete: $empty,*/ onTick: function(position){ if(this.options.snap) position = this.toPosition(this.step); this.knob.setStyle(this.property, position); }, snap: false, offset: 0, range: false, wheel: false, steps: 100, mode: 'horizontal' }, initialize: function(element, knob, options){ this.setOptions(options); this.element = $(element); this.knob = $(knob); this.previousChange = this.previousEnd = this.step = -1; this.element.addEvent('mousedown', this.clickedElement.bind(this)); if (this.options.wheel) this.element.addEvent('mousewheel', this.scrolledElement.bindWithEvent(this)); var offset, limit = {}, modifiers = {'x': false, 'y': false}; switch (this.options.mode){ case 'vertical': this.axis = 'y'; this.property = 'top'; offset = 'offsetHeight'; break; case 'horizontal': this.axis = 'x'; this.property = 'left'; offset = 'offsetWidth'; } this.half = this.knob[offset] / 2; this.full = this.element[offset] - this.knob[offset] + (this.options.offset * 2); this.min = $chk(this.options.range[0]) ? this.options.range[0] : 0; this.max = $chk(this.options.range[1]) ? this.options.range[1] : this.options.steps; this.range = this.max - this.min; this.steps = this.options.steps || this.full; this.stepSize = Math.abs(this.range) / this.steps; this.stepWidth = this.stepSize * this.full / Math.abs(this.range) ; this.knob.setStyle('position', 'relative').setStyle(this.property, - this.options.offset); modifiers[this.axis] = this.property; limit[this.axis] = [- this.options.offset, this.full - this.options.offset]; this.drag = new Drag(this.knob, { snap: 0, limit: limit, modifiers: modifiers, onDrag: this.draggedKnob.bind(this), onStart: this.draggedKnob.bind(this), onComplete: function(){ this.draggedKnob(); this.end(); }.bind(this) }); if (this.options.snap) { this.drag.options.grid = Math.ceil(this.stepWidth); this.drag.options.limit[this.axis][1] = this.full; } }, set: function(step){ if (!((this.range > 0) ^ (step < this.min))) step = this.min; if (!((this.range > 0) ^ (step > this.max))) step = this.max; this.step = Math.round(step); this.checkStep(); this.end(); this.fireEvent('tick', this.toPosition(this.step)); return this; }, clickedElement: function(event){ var dir = this.range < 0 ? -1 : 1; var position = event.page[this.axis] - this.element.getPosition()[this.axis] - this.half; position = position.limit(-this.options.offset, this.full -this.options.offset); this.step = Math.round(this.min + dir * this.toStep(position)); this.checkStep(); this.end(); this.fireEvent('tick', position); }, scrolledElement: function(event){ var mode = (this.options.mode == 'horizontal') ? (event.wheel < 0) : (event.wheel > 0); this.set(mode ? this.step - this.stepSize : this.step + this.stepSize); event.stop(); }, draggedKnob: function(){ var dir = this.range < 0 ? -1 : 1; var position = this.drag.value.now[this.axis]; position = position.limit(-this.options.offset, this.full -this.options.offset); this.step = Math.round(this.min + dir * this.toStep(position)); this.checkStep(); }, checkStep: function(){ if (this.previousChange != this.step){ this.previousChange = this.step; this.fireEvent('change', this.step); } }, end: function(){ if (this.previousEnd !== this.step){ this.previousEnd = this.step; this.fireEvent('complete', this.step + ''); } }, toStep: function(position){ var step = (position + this.options.offset) * this.stepSize / this.full * this.steps; return this.options.steps ? Math.round(step -= step % this.stepSize) : step; }, toPosition: function(step){ return (this.full * Math.abs(this.min - step)) / (this.steps * this.stepSize) - this.options.offset; } });