Mercurial > hg > digilib-old
view webapp/src/main/webapp/jquery/jquery.digilib.sliders.js @ 1070:27ee06879f14
finished slider preview
author | hertzhaft |
---|---|
date | Mon, 23 Apr 2012 09:31:57 +0200 |
parents | 788c757d7f70 |
children | 9e06a7bf2303 |
line wrap: on
line source
/** digilib sliders plugin */ // TODO: add a "default" button that resets slider to the default value // (not to the current URL param) (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 = {}; var sliderOptions = { rot : { label : "Rotation angle", tooltip : "rotate image", icon : "rotate.png", preview : false, 'min' : 0, 'max' : 360, 'step' : 0.1, 'start' : 90 }, brgt : { label : "Brightness", tooltip : "set numeric value to be added", icon : "brightness.png", preview : true, 'min' : -255, 'max' : 255, 'step' : 10, 'start' : 0 }, cont : { label : "Contrast", tooltip : "set numeric value to be multiplied", icon : "contrast.png", preview : true, 'min' : -4, 'max' : 4, 'step' : 0.01, 'start' : 0 } }; var primaryColors = ['r', 'g', 'b']; var colorVals = { r : { label : "red", color : "#800000", a : 0, m : 0 }, g : { label : "green", color : "#008000", a : 0, m : 0 }, b : { label : "blue", color : "#000080", a : 0, m : 0 }, brgt : 0, cont : 0 } var actions = { // shows brightness slider sliderBrgt : function (data) { var onChange = function($slider, val) { colorVals['brgt'] = parseFloat(val); updatePreview($slider); }; var onSubmit = function(val) { digilib.actions.brightness(data, val); }; singleSlider(data, 'brgt', onChange, onSubmit); }, // shows contrast slider sliderCont : function (data) { var onChange = function($slider, val) { var m = Math.pow(2, parseFloat(val)); colorVals['cont'] = val; colorVals['brgt'] = 127 - (127 * m); updatePreview($slider); }; var onSubmit = function(val) { digilib.actions.contrast(data, val, true); }; singleSlider(data, 'cont', onChange, onSubmit); }, // shows rotate slider sliderRot : function (data) { var onChange = null; var onSubmit = function(val) { digilib.actions.rotate(data, val); }; singleSlider(data, 'rot', onChange, onSubmit); }, // shows RGB sliders sliderRGB : function (data) { var onSubmit = function(m, a) { digilib.actions.setRGB(data, m, a); }; rgbSlider(data, onSubmit); } }; // update preview values for a given slider var updatePreview = function ($slider) { if ($slider == null) return; var cls = $slider.data('cls'); var $preview = $slider.data('preview'); var $td2 = $preview.find('table.'+cls+'preview td'); // account for current brgt/cont/rgbm/rgba values var calcRGBValue = function (code, val) { var c = colorVals[code]; var cm = Math.pow(2, c.m) * val; var colorVal = cm + c.a; var cont = Math.pow(2, colorVals.cont) * colorVal; var brgt = colorVals.brgt; var resultVal = cont + brgt; return Math.min(Math.max(Math.round(resultVal), 0), 255); }; // color one table cell according to index position var setRGBValues = function (index) { var val = index * 32; var r = calcRGBValue('r', val); var g = calcRGBValue('g', val); var b = calcRGBValue('b', val); $(this).css('background-color', 'rgb('+r+','+g+','+b+')'); }; $td2.each(setRGBValues); }; // assign button actions to sliders (rotate, brightness, contrast) var setButtonActions = function () { if (fn.setButtonAction == null) { console.debug('sliders: could not assign button actions. Maybe jquery.digilib.buttons.js was not loaded?'); return; } console.debug('sliders: assign new button actions. digilib:', digilib); fn.setButtonAction('brgt', 'sliderBrgt'); fn.setButtonAction('cont', 'sliderCont'); fn.setButtonAction('rot', 'sliderRot'); fn.setButtonAction('rgb', 'sliderRGB'); }; // 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 }; // plugin initialization var init = function (data) { console.debug('initialising sliders plugin. data:', data); var $data = $(data); $data.bind('update', handleUpdate); }; // get brgt/cont/rgba/rgbm params (brightness/contrast/color) var handleUpdate = function (evt) { console.debug("sliders: handleUpdate"); var data = this; var settings = data.settings; colorVals.brgt = parseFloat(settings.brgt) || 0; colorVals.cont = parseFloat(settings.cont) || 0; setRGBcolorVals(data, 'a'); setRGBcolorVals(data, 'm'); var sliderSelector = '#'+ settings.cssPrefix + 'slider'; var $slider = fn.find(data, sliderSelector); fn.centerOnScreen(data, $slider); updatePreview($slider); }; // read rgb m/a parameters and set start values for sliders var setRGBcolorVals = function (data, code) { var colorparts = data.settings['rgb'+code] || '0/0/0'; var values = colorparts.split("/"); colorVals.r[code] = parseFloat(values[0]) || 0; colorVals.g[code] = parseFloat(values[1]) || 0; colorVals.b[code] = parseFloat(values[2]) || 0; }; /** creates a div with a form, setup events and callback */ var setupFormDiv = function (data, $content, cssSuffix, onSubmit) { var cssPrefix = data.settings.cssPrefix; var cls = cssPrefix + cssSuffix; var tiny = cssPrefix + 'tinyslider'; var $elem = data.$elem; var sliderSelector = '#'+cssPrefix+'slider'; if (fn.isOnScreen(data, sliderSelector)) return; // already onscreen var html = '\ <div id="'+cssPrefix+'slider" class="'+cls+'">\ <form class="'+cls+'">\ <input class="'+cls+'cancel" type="button" value="Cancel"/>\ <input class="'+cls+'reset" type="button" value="Reset"/>\ <input type="submit" name="sub" value="Ok"/>\ </form>\ </div>'; $div = $(html).appendTo($elem); var $form = $div.find('form'); $form.prepend($content); // handle submit $form.on('submit', function () { onSubmit(); fn.withdraw($div); return false; }); // handle reset $form.find('.'+cls+'reset').on('click', function () { var sliders = $form.find('div.'+tiny); sliders.each(function () { var reset = $(this).data('reset'); reset(); }); }); // handle cancel $form.find('.'+cls+'cancel').on('click', function () { fn.withdraw($div); }); // show div $div.fadeIn(); // fix non-HTML5 slider var $range = $form.find('input.'+tiny+'range'); var HTML5 = $range.prop('type') === 'range'; if (!HTML5) { console.debug('fix input type=range'); $range.range({change: function (val) { $range.trigger('change'); }}); } fn.centerOnScreen(data, $div); return $div; }; /** creates a TinyRange slider */ var tinySlider = function (data, paramname, startvalue) { var $elem = data.$elem; var opts = sliderOptions[paramname]; var cssPrefix = data.settings.cssPrefix; var cls = cssPrefix + 'tinyslider'; var html = '\ <div class="'+cls+'">\ <span>'+opts.label+'</span>\ <input type="range" class="'+cls+'range" name="'+paramname+'" step="'+opts.step+'" min="'+opts.min+'" max="'+opts.max+'" value="'+startvalue+'"/>\ <input type="text" class="'+cls+'text" name="'+paramname+'" size="4" value="'+startvalue+'"/>\ </div>'; var $slider = $(html); var $range = $slider.find('input.'+cls+'range'); var $text = $slider.find('input.'+cls+'text'); var rangeChange = function () { // crop floating point imprecision var val = parseFloat($range.val()).toFixed(4); $text.val(parseFloat(val)); var update = $slider.data('update'); if ($.isFunction(update)) { update($slider, val); } }; var textChange = function () { var val = $text.val(); $range.val(val); // val doesn't change the slider handle position in Tinyrange // can't use a jQuery "valHook" here because input type is reported as "text" (???) var HTML5 = $range.prop('type') === 'range'; if (!HTML5) { $range.range('set', val); } var update = $slider.data('update'); if ($.isFunction(update)) { update($slider, val); } }; var reset = function () { $text.val(startvalue); textChange(); }; // connect slider and input $range.on('change', rangeChange); $text.on('change', textChange); $slider.data({ '$text' : $text, '$range' : $range, 'reset' : reset, 'update' : null }); return $slider; }; /** creates a single TinyRangeSlider for param "paramname", the new value is passed to the "onSubmit" function. */ var singleSlider = function (data, paramname, onChange, onSubmit) { var classname = 'singleslider'; var $div = $('<div/>'); var opts = sliderOptions[paramname]; var startvalue = data.settings[paramname] || opts.start; var $slider = tinySlider(data, paramname, startvalue); var getValue = function () { // get the new value and do something with it var val = $slider.data('$text').val(); onSubmit(val); }; $div.append($slider); setupFormDiv(data, $div, classname, getValue); var hasPreview = opts.preview; if (hasPreview) { var cls = data.settings.cssPrefix + classname; var $preview = preview(cls); $div.append($preview); $slider.data({ 'cls' : cls, 'preview' : $preview, 'update' : onChange }); onChange($slider, startvalue); } }; /** creates a compound RGB slider the new values are passed to the "onSubmit" function. */ var rgbSlider = function (data, onSubmit) { var css = data.settings.cssPrefix; var cls = css + 'rgbslider'; var $div = $('<div/>'); var $table = $('<table class="'+cls+'" />'); var $preview = preview(cls); $div.append($table); $div.append($preview); // create slider rows for the 3 primary colors var insertTableRow = function(index, value) { var color = colorVals[value]; // start values are set in "handleSetup" var $tr = $('<tr/>').appendTo($table); var html = '\ <td class="'+css+'color '+css+value+'">\ <div>'+color.label+'</div>\ </td>'; $(html).appendTo($tr); var $brgt = tinySlider(data, 'brgt', color.a); var $cont = tinySlider(data, 'cont', color.m); $table.data(value+'a', $brgt.data('$text')); $table.data(value+'m', $cont.data('$text')); $('<td class="'+css+'rgb"/>').append($brgt).appendTo($tr); $('<td class="'+css+'rgb"/>').append($cont).appendTo($tr); }; var onChange = function ($slider) { // show effects of color brightness/contrast on a grey scale var input = $table.data(); $.each(primaryColors, function (index, value) { colorVals[value].a = parseFloat(input[value+'a'].val()); colorVals[value].m = parseFloat(input[value+'m'].val()); }); updatePreview($slider); }; var submitSliderValues = function () { // get values from sliders var input = $table.data(); var rgba = input['ra'].val() + '/' + input['ga'].val() + '/' + input['ba'].val(); var rgbm = input['rm'].val() + '/' + input['gm'].val() + '/' + input['bm'].val(); onSubmit(rgbm, rgba); }; $.each(primaryColors, insertTableRow); setupFormDiv(data, $div, 'rgbslider', submitSliderValues); // update callback is made known to each slider var $sliders = $div.find('div.'+css+'tinyslider'); $sliders.data({ 'cls' : cls, 'preview' : $preview, 'update' : onChange }); onChange($sliders); }; /** creates a new preview div with 2 x 9 cells in scaled grey values */ var preview = function (cls) { var td = new Array(10).join('<td/>'); var html = '\ <div class="'+cls+'preview">\ <table class="'+cls+'grey">\ <tr>'+td+'</tr>\ </table>\ <table class="'+cls+'preview">\ <tr>'+td+'</tr>\ </table>\ </div>'; var $div = $(html); // creates a table with a series of scaled grey values var setGreyScale = function (index) { var val = index * 32; $(this).css('background-color', 'rgb('+val+','+val+','+val+')'); }; $div.find('table.'+cls+'grey td').each(setGreyScale); return $div; }; // 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);