Mercurial > hg > digilib-old
comparison webapp/src/main/webapp/jquery/jquery.digilib.sliders.js @ 1057:d139f59a5f80
rgb slider functional, get/set values not yet
author | hertzhaft |
---|---|
date | Sat, 31 Mar 2012 00:41:28 +0200 |
parents | 4f17420392a9 |
children | 95d28c6ad018 |
comparison
equal
deleted
inserted
replaced
1056:89c5b56933af | 1057:d139f59a5f80 |
---|---|
11 // the functions made available by digilib | 11 // the functions made available by digilib |
12 var fn = null; | 12 var fn = null; |
13 // affine geometry plugin | 13 // affine geometry plugin |
14 var geom = null; | 14 var geom = null; |
15 | 15 |
16 var defaults = { | 16 var defaults = {}; |
17 'label' : 'Slider', | |
18 'direction' : 'x', | |
19 'handlesize' : 16, | |
20 'min' : 0, | |
21 'max' : 100, | |
22 'start' : 33, | |
23 'numberoffset' : -24, | |
24 'labeloffset' : 16, | |
25 'rect' : null, | |
26 'factor' : null, | |
27 'onmove' : null // callback function | |
28 }; | |
29 | 17 |
30 var sliderOptions = { | 18 var sliderOptions = { |
31 rot : { | 19 rot : { |
32 label : "Rotation angle", | 20 label : "Rotation angle", |
33 tooltip : "rotate image", | 21 tooltip : "rotate image", |
52 icon : "contrast.png", | 40 icon : "contrast.png", |
53 'min' : -4, | 41 'min' : -4, |
54 'max' : 4, | 42 'max' : 4, |
55 'step' : 0.01, | 43 'step' : 0.01, |
56 'start' : 0 | 44 'start' : 0 |
57 }, | 45 } |
58 red : { | 46 }; |
59 label : "Red value", | 47 |
60 tooltip : "set red value", | 48 var rgb = { |
61 icon : "rgb.png", | 49 r : { |
62 'min' : 0, | 50 label : "red", |
63 'max' : 255, | 51 color : "#800000" |
64 'start' : 127 | 52 }, |
65 }, | 53 g : { |
66 | 54 label : "green", |
67 green : { | 55 color : "#008000" |
68 label : "Green value", | 56 }, |
69 tooltip : "set green value", | 57 b : { |
70 icon : "rgb.png", | 58 label : "blue", |
71 'min' : 0, | 59 color : "#000080" |
72 'max' : 255, | 60 } |
73 'start' : 127 | 61 } |
74 }, | |
75 | |
76 blue : { | |
77 label : "Blue value", | |
78 tooltip : "set blue value", | |
79 icon : "rgb.png", | |
80 'min' : 0, | |
81 'max' : 255, | |
82 'start' : 127 | |
83 }, | |
84 }; | |
85 | |
86 var actions = { | 62 var actions = { |
87 // slider to set a rotation angle | |
88 sliderRotate : function (data) { | |
89 var $elem = data.$elem; | |
90 var $panel = fn.setupPanel(data); | |
91 var opts = { 'start' : parseFloat(data.settings.rot) }; | |
92 var $slider = fn.setupSlider(data, 'rot', opts); | |
93 var ok = function(d) { | |
94 var angle = $slider.slider('getval'); | |
95 digilib.actions.rotate(d, angle); | |
96 }; | |
97 $panel.data['ok'] = ok; | |
98 $panel.fadeIn(); | |
99 $panel.prepend($slider); | |
100 fn.centerOnScreen(data, $panel); | |
101 $slider.slider('show'); | |
102 }, | |
103 | |
104 // slider to set a brightness value | |
105 sliderBrightness : function (data) { | |
106 var $elem = data.$elem; | |
107 var $panel = fn.setupPanel(data); | |
108 var opts = { 'start' : parseFloat(data.settings.brgt) }; | |
109 var $slider = fn.setupSlider(data, 'brgt', opts); | |
110 var ok = function(d) { | |
111 var brgt = $slider.slider('getval'); | |
112 digilib.actions.brightness(d, brgt); | |
113 }; | |
114 $panel.data['ok'] = ok; | |
115 $panel.prepend($slider); | |
116 fn.centerOnScreen(data, $panel); | |
117 $slider.slider('show'); | |
118 }, | |
119 | |
120 // slider to set a contrast value | |
121 sliderContrast : function (data) { | |
122 var $elem = data.$elem; | |
123 var $panel = fn.setupPanel(data); | |
124 var opts = { 'start' : parseFloat(data.settings.cont) }; | |
125 var $slider = fn.setupSlider(data, 'cont', opts); | |
126 var ok = function(d) { | |
127 var cont = $slider.slider('getval'); | |
128 digilib.actions.contrast(d, cont, true); | |
129 }; | |
130 $panel.data['ok'] = ok; | |
131 $panel.fadeIn(); | |
132 $panel.prepend($slider); | |
133 fn.centerOnScreen(data, $panel); | |
134 $slider.slider('show'); | |
135 }, | |
136 | |
137 // shows brightness slider | 63 // shows brightness slider |
138 tinySliderBrgt : function (data) { | 64 tinySliderBrgt : function (data) { |
139 var callback = function(val) { | 65 var callback = function(val) { |
140 digilib.actions.brightness(data, val); | 66 digilib.actions.brightness(data, val); |
141 }; | 67 }; |
142 setupTinyRangeSlider(data, 'brgt', callback); | 68 singleSlider(data, 'brgt', callback); |
143 }, | 69 }, |
144 | 70 |
145 // shows contrast slider | 71 // shows contrast slider |
146 tinySliderCont : function (data) { | 72 tinySliderCont : function (data) { |
147 var callback = function(val) { | 73 var callback = function(val) { |
148 digilib.actions.contrast(data, val, true); | 74 digilib.actions.contrast(data, val, true); |
149 }; | 75 }; |
150 setupTinyRangeSlider(data, 'cont', callback); | 76 singleSlider(data, 'cont', callback); |
151 }, | 77 }, |
152 | 78 |
153 // shows rotate slider | 79 // shows rotate slider |
154 tinySliderRot : function (data) { | 80 tinySliderRot : function (data) { |
155 var callback = function(val) { | 81 var callback = function(val) { |
156 digilib.actions.rotate(data, val); | 82 digilib.actions.rotate(data, val); |
157 }; | 83 }; |
158 setupTinyRangeSlider(data, 'rot', callback); | 84 singleSlider(data, 'rot', callback); |
159 } | 85 }, |
160 }; | 86 |
161 | 87 // shows RGB sliders |
162 var getval = function (data) { | 88 tinySliderRGB : function (data) { |
163 // returns the slider value | 89 var callback = function(m, a) { |
164 var $this = this; | 90 digilib.actions.setRGB(data, m, a); |
165 var settings = $this.data('settings'); | 91 }; |
166 return settings.val; | 92 rgbSlider(data, callback); |
167 }; | 93 } |
168 | |
169 var setval = function (data, val) { | |
170 // sets the slider value and moves the handle acordingly | |
171 var $this = this; | |
172 var settings = $this.data('settings'); | |
173 if (val != null) settings.val = val; | |
174 var ratio = (settings.val - settings.min) / settings.diff; | |
175 var r = settings.rect; | |
176 var newpos = settings.vertical | |
177 ? geom.position(r.x + r.width / 2, r.y + ratio * r.height) | |
178 : geom.position(r.x + ratio * r.width, r.y + r.height / 2); | |
179 $this.slider('moveto', newpos); | |
180 }; | |
181 | |
182 var moveto = function (data, pos, calc) { | |
183 // move the handle in response to a mouse position | |
184 var $this = this; | |
185 var settings = $this.data('settings'); | |
186 var r = settings.rect; | |
187 var h = settings.handlerect; | |
188 var handlepos = r.getCenter(); | |
189 if (settings.vertical) { | |
190 handlepos.y = Math.min(Math.max(r.y, pos.y), r.y + r.height) | |
191 } else { | |
192 handlepos.x = Math.min(Math.max(r.x, pos.x), r.x + r.width) | |
193 } | |
194 h.setCenter(handlepos); | |
195 h.adjustDiv(settings.$handle); | |
196 if (calc) { | |
197 // calculate new slider value | |
198 var temp = settings.vertical | |
199 ? (handlepos.y - r.y) | |
200 : (handlepos.x - r.x); | |
201 settings.val = fn.cropFloat(temp * settings.factor + settings.min); | |
202 } | |
203 if (settings.onmove) { | |
204 settings.onmove($this); | |
205 } | |
206 }; | |
207 | |
208 var show = function (data) { | |
209 var $this = this; | |
210 $this.fadeIn(); | |
211 var settings = $this.data('settings'); | |
212 // the jquery elements we need | |
213 var $body = $('body'); | |
214 // some variables for easier calculation | |
215 var label = settings.label + ': '; | |
216 // calculate positions for the slider elements | |
217 var r = geom.rectangle($this); | |
218 settings.rect = r; | |
219 var v = settings.vertical; | |
220 settings.factor = v | |
221 ? settings.diff / r.height | |
222 : settings.diff / r.width; | |
223 var labelpos = geom.position(r.x, r.y + settings.labeloffset); | |
224 var minpos = v | |
225 ? geom.position(r.x + settings.numberoffset, r.y) | |
226 : geom.position(r.x, r.y + settings.numberoffset); | |
227 var maxpos = v | |
228 ? geom.position(r.x + settings.numberoffset, r.y + r.width) | |
229 : geom.position(r.x + r.width - settings.$max.width(), r.y + settings.numberoffset); | |
230 // adjust elements | |
231 labelpos.adjustDiv(settings.$label); | |
232 minpos.adjustDiv(settings.$min); | |
233 maxpos.adjustDiv(settings.$max); | |
234 // set the handle | |
235 $this.slider('setval'); | |
236 | |
237 // mousedown handler: start sliding | |
238 var sliderStart = function (event) { | |
239 $body.on("mousemove.slider", sliderMove); | |
240 $body.on("mouseup.slider", sliderEnd); | |
241 return false; | |
242 }; | |
243 | |
244 // mousemove handler: move slider | |
245 var sliderMove = function (event) { | |
246 var pos = geom.position(event); | |
247 $this.slider('moveto', pos, true); | |
248 settings.$label.text(label + settings.val); | |
249 return false; | |
250 }; | |
251 | |
252 // mouseup handler: end sliding | |
253 var sliderEnd = function (event) { | |
254 $body.off("mousemove.slider"); | |
255 $body.off("mouseup.slider"); | |
256 return false; | |
257 }; | |
258 | |
259 // bind mousedown handler to sliderhandle | |
260 settings.$handle.on('mousedown.slider', sliderStart); | |
261 console.debug('show slider: ', $this, ' settings:', settings); | |
262 }; | |
263 | |
264 var destroy = function() { | |
265 var $this = this; | |
266 var settings = $this.data('settings'); | |
267 var $handle = settings.$handle; | |
268 $handle.off('mousedown.slider'); | |
269 fn.withdraw($this); | |
270 }; | 94 }; |
271 | 95 |
272 // assign button actions to sliders (rotate, brightness, contrast) | 96 // assign button actions to sliders (rotate, brightness, contrast) |
273 var setButtonActions = function () { | 97 var setButtonActions = function () { |
274 if (fn.setButtonAction == null) { | 98 if (fn.setButtonAction == null) { |
277 } | 101 } |
278 console.debug('sliders: assign new button actions. digilib:', digilib); | 102 console.debug('sliders: assign new button actions. digilib:', digilib); |
279 fn.setButtonAction('brgt', 'tinySliderBrgt'); | 103 fn.setButtonAction('brgt', 'tinySliderBrgt'); |
280 fn.setButtonAction('cont', 'tinySliderCont'); | 104 fn.setButtonAction('cont', 'tinySliderCont'); |
281 fn.setButtonAction('rot', 'tinySliderRot'); | 105 fn.setButtonAction('rot', 'tinySliderRot'); |
106 // fn.setButtonAction('rgb', 'tinySliderRGB'); | |
282 }; | 107 }; |
283 | 108 |
284 // plugin installation called by digilib on plugin object. | 109 // plugin installation called by digilib on plugin object. |
285 var install = function (plugin) { | 110 var install = function (plugin) { |
286 digilib = plugin; | 111 digilib = plugin; |
291 // add defaults, actions, buttons | 116 // add defaults, actions, buttons |
292 $.extend(true, digilib.defaults, defaults); // make deep copy | 117 $.extend(true, digilib.defaults, defaults); // make deep copy |
293 $.extend(digilib.actions, actions); | 118 $.extend(digilib.actions, actions); |
294 setButtonActions(digilib.buttons); | 119 setButtonActions(digilib.buttons); |
295 // export functions | 120 // export functions |
296 fn.setupSlider = setupSlider; | |
297 fn.setupPanel = setupPanel; | |
298 }; | 121 }; |
299 | 122 |
300 // plugin initialization | 123 // plugin initialization |
301 var init = function (data) { | 124 var init = function (data) { |
302 console.debug('initialising sliders plugin. data:', data); | 125 console.debug('initialising sliders plugin. data:', data); |
303 var settings = data.settings; | 126 // var settings = data.settings; |
304 var $data = $(data); | 127 // var $data = $(data); |
305 // we do setup at runtime | 128 // we do setup at runtime |
306 // $data.bind('setup', handleSetup); | 129 // $data.bind('setup', handleSetup); |
307 }; | 130 }; |
308 | 131 |
309 /** creates the HTML structure for a panel div | 132 /** creates a div with a form, setup events and callback |
310 */ | 133 */ |
311 var setupPanel = function (data) { | 134 var setupFormDiv = function (data, $content, cssSuffix, callback) { |
312 var $elem = data.$elem; | 135 var cssPrefix = data.settings.cssPrefix; |
313 var panelClass = data.settings.cssPrefix + 'panel'; | 136 var cls = cssPrefix + cssSuffix; |
314 var $panel = $elem.find('.' + panelClass); | |
315 if ($panel.length == 0) { | |
316 // new panel | |
317 $panel = $('<div/>'); | |
318 $panel.addClass(panelClass); | |
319 $elem.append($panel); | |
320 $panel.fadeIn(); | |
321 } else { | |
322 // panel exists, so empty it | |
323 $panel.empty(); | |
324 } | |
325 var $okcancel = setupOkCancel(data); | |
326 $panel.append($okcancel); | |
327 return $panel; | |
328 }; | |
329 | |
330 /** creates the HTML structure for a slider div | |
331 */ | |
332 var setupSlider = function (data, paramname, opts) { | |
333 var id = "slider-" + paramname; | |
334 var $div = $('#' + id); | |
335 if ($div.length > 0) { | |
336 return $div; | |
337 } | |
338 // slider not yet created | |
339 var cssClass = data.cssPrefix+'slider'; | |
340 var html = '\ | 137 var html = '\ |
341 <div id="'+id+' class="'+cssClass+'">\ | 138 <div class="'+cls+'">\ |
342 <div class="'+cssClass+'handle"/>\ | 139 <form class="'+cls+'">\ |
343 <div class="'+cssClass+'number">'+options.min+'</div>\ | 140 <input class="'+cls+'cancel" type="button" value="Cancel"/>\ |
344 <div class="'+cssClass+'number">'+options.max+'</div>\ | 141 <input type="submit" name="sub" value="Ok"/>\ |
345 <div class="'+cssClass+'label">\ | |
346 <span>'+options.label+'</span>\ | |
347 <input class="'+cssClass+'input">'+options.start+'</input>\ | |
348 </div>\ | |
349 </div>'; | |
350 var $div = $(html); | |
351 var $handle = $div.find('div.'+cssClass+'handle'); | |
352 var $label = $div.find('div.'+cssClass+'label'); | |
353 var $input = $div.find('div.'+cssClass+'input'); | |
354 var $numbers = $div.find('div.'+cssClass+'number'); | |
355 var $min = $numbers[0]; | |
356 var $max = $numbers[1]; | |
357 var options = defaults; | |
358 $.extend(options, sliderOptions[paramname], opts); | |
359 $.extend(options, { | |
360 '$handle' : $handle, | |
361 '$label' : $label, | |
362 '$input' : $input, | |
363 '$min' : $min, | |
364 '$max' : $max, | |
365 'diff' : options.max - options.min, | |
366 'vertical' : options.direction == 'y', | |
367 'val' : options.start, | |
368 'handlerect' : geom.rectangle(0, 0, options.handlesize, options.handlesize) | |
369 }); | |
370 $div.data(options); | |
371 console.debug('new slider: ', $div, ', options: ', options); | |
372 return $div; | |
373 }; | |
374 | |
375 /** creates the HTML structure for a ok and cancel div | |
376 */ | |
377 var setupOkCancel = function (data) { | |
378 var settings = data.settings; | |
379 var cssPrefix = settings.cssPrefix; | |
380 var html = '\ | |
381 <div>\ | |
382 <button class="'+cssPrefix+'button" id="'+cssPrefix+'Ok">OK</button>\ | |
383 <button class="'+cssPrefix+'button" id="'+cssPrefix+'Cancel">Cancel</button>\ | |
384 </div>'; | |
385 var $div = $(html); | |
386 var handler = function(event) { | |
387 var $panel = $(this).parents('.'+cssPrefix+'panel'); | |
388 if (event.keyCode == 27 || event.target.id == cssPrefix+'Cancel') { | |
389 var callback = $panel.data['cancel']; | |
390 if (callback) { | |
391 callback(data); | |
392 } | |
393 } | |
394 if (event.keyCode == 13 || event.target.id == cssPrefix+'Ok') { | |
395 var callback = $panel.data['ok']; | |
396 if (callback) { | |
397 callback(data); | |
398 } | |
399 } | |
400 fn.withdraw($panel); | |
401 return false; | |
402 }; | |
403 $div.children().on('click', handler); | |
404 return $div; | |
405 }; | |
406 | |
407 /** creates a TinyRangeSlider | |
408 */ | |
409 var setupTinyRangeSlider = function (data, paramname, callback) { | |
410 var $elem = data.$elem; | |
411 var opts = sliderOptions[paramname]; | |
412 var param = data.settings[paramname] || opts.start; | |
413 var cssPrefix = data.settings.cssPrefix; | |
414 var cssClass = cssPrefix + 'tinyslider'; | |
415 var sliderHtml = '\ | |
416 <div class="'+cssClass+'" title="'+opts.tooltip+'">\ | |
417 <form class="'+cssClass+'">\ | |
418 <span>'+opts.label+'</span>\ | |
419 <input type="range" class="'+cssClass+'range" name="'+paramname+'" step="'+opts.step+'" min="'+opts.min+'" max="'+opts.max+'" value="'+param+'"/>\ | |
420 <input type="text" class="'+cssClass+'text" name="'+paramname+'" size="4" value="'+param+'"/>\ | |
421 <br/>\ | |
422 <input class="'+cssClass+'cancel" type="button" value="Cancel"/><input type="submit" name="sub" value="Ok"/>\ | |
423 </form>\ | 142 </form>\ |
424 </div>'; | 143 </div>'; |
425 var $slider = $(sliderHtml); | 144 var $elem = data.$elem; |
426 $elem.append($slider); | 145 var $div = $(html).appendTo($elem); |
427 $slider.fadeIn(); | 146 var $form = $div.find('form'); |
428 var $range = $slider.find('input.'+cssClass+'range'); | 147 $form.prepend($content); |
429 var $text = $slider.find('input.'+cssClass+'text'); | 148 // handle submit |
149 $form.on('submit', function () { | |
150 callback(); | |
151 fn.withdraw($div); | |
152 return false; | |
153 }); | |
154 // handle cancel | |
155 $form.find('.'+cls+'cancel').on('click', function () { | |
156 fn.withdraw($div); | |
157 }); | |
158 // show div | |
159 $div.fadeIn(); | |
430 // fix non-HTML5 slider | 160 // fix non-HTML5 slider |
161 var tiny = cssPrefix + 'tinyslider'; | |
162 var $range = $form.find('input.'+tiny+'range'); | |
431 var HTML5 = $range.prop('type') === 'range'; | 163 var HTML5 = $range.prop('type') === 'range'; |
432 if (!HTML5) { | 164 if (!HTML5) { |
433 console.debug('fix input type=range'); | 165 console.debug('fix input type=range'); |
434 $range.range({change: function (val) { | 166 $range.range({change: function (val) { |
435 $range.trigger('change'); | 167 $range.trigger('change'); |
436 }}); | 168 }}); |
437 } | 169 } |
170 fn.centerOnScreen(data, $div); | |
171 return $div; | |
172 }; | |
173 | |
174 /** creates a TinyRangeSlider | |
175 */ | |
176 var tinySlider = function (data, paramname, startval) { | |
177 var $elem = data.$elem; | |
178 var opts = sliderOptions[paramname]; | |
179 var param = startval || data.settings[paramname] || opts.start; | |
180 var cssPrefix = data.settings.cssPrefix; | |
181 var cls = cssPrefix + 'tinyslider'; | |
182 var html = '\ | |
183 <div class="'+cls+'frame">\ | |
184 <span>'+opts.label+'</span>\ | |
185 <input type="range" class="'+cls+'range" name="'+paramname+'" step="'+opts.step+'" min="'+opts.min+'" max="'+opts.max+'" value="'+param+'"/>\ | |
186 <input type="text" class="'+cls+'text" name="'+paramname+'" size="4" value="'+param+'"/>\ | |
187 </div>'; | |
188 var $slider = $(html); | |
189 var $range = $slider.find('input.'+cls+'range'); | |
190 var $text = $slider.find('input.'+cls+'text'); | |
191 $slider.data({'$text' : $text, '$range' : $range}); | |
438 // connect slider and input | 192 // connect slider and input |
439 $range.on('change', function () { | 193 $range.on('change', function () { |
440 // TinyRange rounds to integer values, not always desired | |
441 var val = $range.val(); | 194 var val = $range.val(); |
442 $text.val(val); | 195 $text.val(val); |
443 }); | 196 }); |
444 $text.on('change', function () { | 197 $text.on('change', function () { |
445 var val = $text.val(); | 198 var val = $text.val(); |
446 $range.val(val); | 199 $range.val(val); |
200 // val doesn't change the slider handle position in Tinyrange | |
201 // can't use a jQuery "valHook" here because input type is reported as "text" (???) | |
202 var HTML5 = $range.prop('type') === 'range'; | |
447 if (!HTML5) { | 203 if (!HTML5) { |
448 $range.range('set', val); | 204 $range.range('set', val); |
449 } | 205 } |
450 }); | 206 }); |
451 // handle submit | 207 return $slider; |
452 $slider.find('form').on('submit', function () { | 208 }; |
453 // console.debug("brgt-form:", this, " sub=", this.sub); | 209 |
454 callback($text.val()); | 210 /** creates a single TinyRangeSlider for param "paramname", |
455 fn.withdraw($slider); | 211 the new value is passed to the "callback" function. |
456 return false; | 212 */ |
457 }); | 213 var singleSlider = function (data, paramname, callback) { |
458 // handle cancel | 214 var $slider = tinySlider(data, paramname); |
459 $slider.find('.'+cssClass+'cancel').on('click', function () { | 215 var getValue = function () { |
460 fn.withdraw($slider); | 216 var val = $slider.data('$text').val(); |
461 }); | 217 callback(val); |
462 fn.centerOnScreen(data, $slider); | 218 }; |
219 setupFormDiv(data, $slider, 'singleslider', getValue); | |
220 }; | |
221 | |
222 /** creates a compound RGB slider | |
223 the new values are passed to the "callback" function. | |
224 */ | |
225 var rgbSlider = function (data, callback) { | |
226 var cls = data.settings.cssPrefix + 'rgbslider'; | |
227 var $table = $('<table class="'+cls+'" />'); | |
228 var makeSliders = function(index, value) { | |
229 // TODO: set start values | |
230 var $tr = $('<tr/>').appendTo($table); | |
231 var $td = $('<td class="color">'+rgb[value].label+'</td>').appendTo($tr); | |
232 var $td = $('<td class="rgb"/>').append(tinySlider(data, 'brgt')).appendTo($tr); | |
233 var $td = $('<td class="rgb"/>').append(tinySlider(data, 'cont')).appendTo($tr); | |
234 } | |
235 $.each(['r','g','b'], makeSliders); | |
236 var getValue = function () { | |
237 // TODO: get values from sliders | |
238 callback(null, null); | |
239 }; | |
240 setupFormDiv(data, $table, 'rgbslider', getValue); | |
463 }; | 241 }; |
464 | 242 |
465 // plugin object with name and init | 243 // plugin object with name and init |
466 // shared objects filled by digilib on registration | 244 // shared objects filled by digilib on registration |
467 var plugin = { | 245 var plugin = { |