Mercurial > hg > digilib-old
view webapp/src/main/webapp/jquery/jquery.digilib.sliders.js @ 1042:2c5a48a624c5
TinyRange sliders now work for brgt,cont,rot (not perfect)
author | hertzhaft |
---|---|
date | Thu, 22 Mar 2012 19:22:38 +0100 |
parents | aef8a02e7ea5 |
children | e7733df2e2c4 |
line wrap: on
line source
/** digilib sliders plugin */ // TODO: // - steps // - additional input element for numeric value (function($) { // plugin object with digilib data var digilib = null; // the functions made available by digilib var fn = null; // affine geometry plugin var geom = null; var defaults = { 'label' : 'Slider', 'direction' : 'x', 'handlesize' : 16, 'min' : 0, 'max' : 100, 'start' : 33, 'numberoffset' : -24, 'labeloffset' : 16, 'rect' : null, 'factor' : null, 'onmove' : null // callback function }; var sliderOptions = { rot : { label : "Rotation angle", tooltip : "rotate image", icon : "rotate.png", 'min' : 0, 'max' : 360, 'start' : 90 }, brgt : { label : "Brightness", tooltip : "set numeric value to be added", icon : "brightness.png", 'min' : -255, 'max' : 255, 'start' : 0 }, cont : { label : "Contrast", tooltip : "set numeric value to be multiplied", icon : "contrast.png", 'min' : -4, 'max' : 4, 'start' : 0 }, red : { label : "Red value", tooltip : "set red value", icon : "rgb.png", 'min' : 0, 'max' : 255, 'start' : 127 }, green : { label : "Green value", tooltip : "set green value", icon : "rgb.png", 'min' : 0, 'max' : 255, 'start' : 127 }, blue : { label : "Blue value", tooltip : "set blue value", icon : "rgb.png", 'min' : 0, 'max' : 255, 'start' : 127 }, }; var actions = { // slider to set a rotation angle sliderRotate : function (data) { var $elem = data.$elem; var $panel = fn.setupPanel(data); var opts = { 'start' : parseFloat(data.settings.rot) }; var $slider = fn.setupSlider(data, 'rot', opts); var ok = function(d) { var angle = $slider.slider('getval'); digilib.actions.rotate(d, angle); }; $panel.data['ok'] = ok; $panel.fadeIn(); $panel.prepend($slider); fn.centerOnScreen(data, $panel); $slider.slider('show'); }, // slider to set a brightness value sliderBrightness : function (data) { var $elem = data.$elem; var $panel = fn.setupPanel(data); var opts = { 'start' : parseFloat(data.settings.brgt) }; var $slider = fn.setupSlider(data, 'brgt', opts); var ok = function(d) { var brgt = $slider.slider('getval'); digilib.actions.brightness(d, brgt); }; $panel.data['ok'] = ok; $panel.prepend($slider); fn.centerOnScreen(data, $panel); $slider.slider('show'); }, // slider to set a contrast value sliderContrast : function (data) { var $elem = data.$elem; var $panel = fn.setupPanel(data); var opts = { 'start' : parseFloat(data.settings.cont) }; var $slider = fn.setupSlider(data, 'cont', opts); var ok = function(d) { var cont = $slider.slider('getval'); digilib.actions.contrast(d, cont, true); }; $panel.data['ok'] = ok; $panel.fadeIn(); $panel.prepend($slider); fn.centerOnScreen(data, $panel); $slider.slider('show'); }, // shows brightness slider tinySliderBrgt : function (data) { var callback = function(val) { digilib.actions.brightness(data, val); }; setupTinyRangeSlider(data, 'brgt', callback); }, // shows contrast slider tinySliderCont : function (data) { var callback = function(val) { digilib.actions.contrast(data, val, true); }; setupTinyRangeSlider(data, 'cont', callback); }, // shows rotate slider tinySliderRot : function (data) { var callback = function(val) { digilib.actions.rotate(data, val); }; setupTinyRangeSlider(data, 'rot', callback); } }; var getval = function (data) { // returns the slider value var $this = this; var settings = $this.data('settings'); return settings.val; }; var setval = function (data, val) { // sets the slider value and moves the handle acordingly var $this = this; var settings = $this.data('settings'); if (val != null) settings.val = val; var ratio = (settings.val - settings.min) / settings.diff; var r = settings.rect; var newpos = settings.vertical ? geom.position(r.x + r.width / 2, r.y + ratio * r.height) : geom.position(r.x + ratio * r.width, r.y + r.height / 2); $this.slider('moveto', newpos); }; var moveto = function (data, pos, calc) { // move the handle in response to a mouse position var $this = this; var settings = $this.data('settings'); var r = settings.rect; var h = settings.handlerect; var handlepos = r.getCenter(); if (settings.vertical) { handlepos.y = Math.min(Math.max(r.y, pos.y), r.y + r.height) } else { handlepos.x = Math.min(Math.max(r.x, pos.x), r.x + r.width) } h.setCenter(handlepos); h.adjustDiv(settings.$handle); if (calc) { // calculate new slider value var temp = settings.vertical ? (handlepos.y - r.y) : (handlepos.x - r.x); settings.val = fn.cropFloat(temp * settings.factor + settings.min); } if (settings.onmove) { settings.onmove($this); } }; var show = function (data) { var $this = this; $this.fadeIn(); var settings = $this.data('settings'); // the jquery elements we need var $body = $('body'); // some variables for easier calculation var label = settings.label + ': '; // calculate positions for the slider elements var r = geom.rectangle($this); settings.rect = r; var v = settings.vertical; settings.factor = v ? settings.diff / r.height : settings.diff / r.width; var labelpos = geom.position(r.x, r.y + settings.labeloffset); var minpos = v ? geom.position(r.x + settings.numberoffset, r.y) : geom.position(r.x, r.y + settings.numberoffset); var maxpos = v ? geom.position(r.x + settings.numberoffset, r.y + r.width) : geom.position(r.x + r.width - settings.$max.width(), r.y + settings.numberoffset); // adjust elements labelpos.adjustDiv(settings.$label); minpos.adjustDiv(settings.$min); maxpos.adjustDiv(settings.$max); // set the handle $this.slider('setval'); // mousedown handler: start sliding var sliderStart = function (event) { $body.on("mousemove.slider", sliderMove); $body.on("mouseup.slider", sliderEnd); return false; }; // mousemove handler: move slider var sliderMove = function (event) { var pos = geom.position(event); $this.slider('moveto', pos, true); settings.$label.text(label + settings.val); return false; }; // mouseup handler: end sliding var sliderEnd = function (event) { $body.off("mousemove.slider"); $body.off("mouseup.slider"); return false; }; // bind mousedown handler to sliderhandle settings.$handle.on('mousedown.slider', sliderStart); console.debug('show slider: ', $this, ' settings:', settings); }; var destroy = function() { var $this = this; var settings = $this.data('settings'); var $handle = settings.$handle; $handle.off('mousedown.slider'); $this.fadeOut(function(){ $this.remove() }); }; // set standard button "onclick" field to slider action var setButtonAction = function(buttons, buttonName, action) { var button = buttons[buttonName]; if (button == null) { // normally this means that jquery.digilib.buttons.js was not loaded console.log('could not attach slider action ' + action + ', button ' + buttonName + ' not available' ); return; } button.onclick = action; }; // set standard button actions (rotate, brightness, contrast) to slider var setButtonActions = function (buttons) { console.debug('sliders: setting button acions. digilib:', digilib); setButtonAction(buttons, 'brgt', 'tinySliderBrgt'); setButtonAction(buttons, 'cont', 'tinySliderCont'); setButtonAction(buttons, 'rot', 'tinySliderRot'); }; // plugin installation called by digilib on plugin object. var install = function (plugin) { digilib = plugin; console.debug('installing sliders plugin. digilib:', digilib); fn = digilib.fn; // import geometry classes geom = fn.geometry; // add defaults, actions, buttons $.extend(true, digilib.defaults, defaults); // make deep copy $.extend(digilib.actions, actions); setButtonActions(digilib.buttons); // export functions fn.setupSlider = setupSlider; fn.setupPanel = setupPanel; }; // plugin initialization var init = function (data) { console.debug('initialising sliders plugin. data:', data); var settings = data.settings; var $data = $(data); // we do setup at runtime // $data.bind('setup', handleSetup); }; /** creates the HTML structure for a panel div */ var setupPanel = function (data) { var $elem = data.$elem; var panelClass = data.settings.cssPrefix + 'panel'; var $panel = $elem.find('.' + panelClass); if ($panel.length == 0) { // new panel $panel = $('<div/>'); $panel.addClass(panelClass); $elem.append($panel); $panel.fadeIn(); } else { // panel exists, so empty it $panel.empty(); } var $okcancel = setupOkCancel(data); $panel.append($okcancel); return $panel; }; /** creates the HTML structure for a slider div */ var setupSlider = function (data, paramname, opts) { var id = "slider-" + paramname; var $div = $('#' + id); if ($div.length > 0) { return $div; } // slider not yet created var cssClass = data.cssPrefix+'slider'; var html = '\ <div id="'+id+' class="'+cssClass+'">\ <div class="'+cssClass+'handle"/>\ <div class="'+cssClass+'number">'+options.min+'</div>\ <div class="'+cssClass+'number">'+options.max+'</div>\ <div class="'+cssClass+'label">\ <span>'+options.label+'</span>\ <input class="'+cssClass+'input">'+options.start+'</input>\ </div>\ </div>'; var $div = $(html); var $handle = $div.find('div.'+cssClass+'handle'); var $label = $div.find('div.'+cssClass+'label'); var $input = $div.find('div.'+cssClass+'input'); var $numbers = $div.find('div.'+cssClass+'number'); var $min = $numbers[0]; var $max = $numbers[1]; var options = defaults; $.extend(options, sliderOptions[paramname], opts); $.extend(options, { '$handle' : $handle, '$label' : $label, '$input' : $input, '$min' : $min, '$max' : $max, 'diff' : options.max - options.min, 'vertical' : options.direction == 'y', 'val' : options.start, 'handlerect' : geom.rectangle(0, 0, options.handlesize, options.handlesize) }); $div.data(options); console.debug('new slider: ', $div, ', options: ', options); return $div; }; /** creates the HTML structure for a ok and cancel div */ var setupOkCancel = function (data) { var settings = data.settings; var cssPrefix = settings.cssPrefix; var html = '\ <div>\ <button class="'+cssPrefix+'button" id="'+cssPrefix+'Ok">OK</button>\ <button class="'+cssPrefix+'button" id="'+cssPrefix+'Cancel">Cancel</button>\ </div>'; var $div = $(html); var handler = function(event) { var $panel = $(this).parents('.'+cssPrefix+'panel'); if (event.keyCode == 27 || event.target.id == cssPrefix+'Cancel') { var callback = $panel.data['cancel']; if (callback) { callback(data); } } if (event.keyCode == 13 || event.target.id == cssPrefix+'Ok') { var callback = $panel.data['ok']; if (callback) { callback(data); } } $panel.fadeOut(function() { $panel.remove(); }); return false; }; $div.children().on('click', handler); return $div; }; /** creates a TinyRangeSlider */ var setupTinyRangeSlider = function (data, paramname, callback) { var $elem = data.$elem; var opts = sliderOptions[paramname]; var param = data.settings[paramname] || opts.start; var cssPrefix = data.settings.cssPrefix; var cssClass = cssPrefix + 'tinyslider'; var sliderHtml = '\ <div class="'+cssClass+'" style="width:300px; background-color:white; padding:10px;" title="'+opts.tooltip+'">\ <form class="'+cssClass+'">\ <span>'+opts.label+'</span>\ <input type="range" class="'+cssClass+'range" name="'+paramname+'" min="'+opts.min+'" max="'+opts.max+'" value="'+param+'"/>\ <input type="text" class="'+cssClass+'text" name="'+paramname+'" size="3" value="'+param+'"/>\ <br/>\ <input class="'+cssClass+'cancel" type="button" value="Cancel"/><input type="submit" name="sub" value="Ok"/>\ </form>\ </div>'; var $slider = $(sliderHtml); $elem.append($slider); var $range = $slider.find('input.'+cssClass+'range'); var $text = $slider.find('input.'+cssClass+'text'); // fix non-HTML5 slider var HTML5 = $range.prop('type') === 'range'; if (!HTML5) { console.debug('fix input type=range'); $range.range({change: function (val) { $range.trigger('change'); }}); } // connect slider and input $range.on('change', function () { // TinyRange rounds to integer values, not always desired var val = $range.val(); $text.val(val); }); $text.on('change', function () { var val = $text.val(); $range.val(val); // val() doesn't update handle, but set changes value :-/ // $range.range('set', val); }); // handle submit $slider.find('form').on('submit', function () { console.debug("brgt-form:", this, " sub=", this.sub); callback($text.val()); // digilib.actions.brightness(data, brgt); $slider.remove(); return false; }); // handle cancel $slider.find('.'+cssClass+'cancel').on('click', function () { $slider.remove(); }); $slider.fadeIn(); fn.centerOnScreen(data, $slider); }; // plugin object with name and init // shared objects filled by digilib on registration var plugin = { name : 'sliders', install : install, init : init, buttons : {}, actions : {}, fn : {}, plugins : {} }; if ($.fn.digilib == null) { $.error("jquery.digilib.sliders must be loaded after jquery.digilib!"); } else { $.fn.digilib('plugin', plugin); } })(jQuery);