imaginable 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +84 -0
  4. data/README.textile +114 -0
  5. data/Rakefile +2 -0
  6. data/imaginable.gemspec +21 -0
  7. data/lib/generators/imaginable/install/install_generator.rb +28 -0
  8. data/lib/generators/templates/fancybox/blank.gif +0 -0
  9. data/lib/generators/templates/fancybox/fancy_close.png +0 -0
  10. data/lib/generators/templates/fancybox/fancy_loading.png +0 -0
  11. data/lib/generators/templates/fancybox/fancy_nav_left.png +0 -0
  12. data/lib/generators/templates/fancybox/fancy_nav_right.png +0 -0
  13. data/lib/generators/templates/fancybox/fancy_shadow_e.png +0 -0
  14. data/lib/generators/templates/fancybox/fancy_shadow_n.png +0 -0
  15. data/lib/generators/templates/fancybox/fancy_shadow_ne.png +0 -0
  16. data/lib/generators/templates/fancybox/fancy_shadow_nw.png +0 -0
  17. data/lib/generators/templates/fancybox/fancy_shadow_s.png +0 -0
  18. data/lib/generators/templates/fancybox/fancy_shadow_se.png +0 -0
  19. data/lib/generators/templates/fancybox/fancy_shadow_sw.png +0 -0
  20. data/lib/generators/templates/fancybox/fancy_shadow_w.png +0 -0
  21. data/lib/generators/templates/fancybox/fancy_title_left.png +0 -0
  22. data/lib/generators/templates/fancybox/fancy_title_main.png +0 -0
  23. data/lib/generators/templates/fancybox/fancy_title_over.png +0 -0
  24. data/lib/generators/templates/fancybox/fancy_title_right.png +0 -0
  25. data/lib/generators/templates/fancybox/fancybox-x.png +0 -0
  26. data/lib/generators/templates/fancybox/fancybox-y.png +0 -0
  27. data/lib/generators/templates/fancybox/fancybox.png +0 -0
  28. data/lib/generators/templates/fancybox/jquery.fancybox-1.3.4.css +359 -0
  29. data/lib/generators/templates/imaginable.js +429 -0
  30. data/lib/generators/templates/imaginable.rb +6 -0
  31. data/lib/generators/templates/imgareaselect/border-anim-h.gif +0 -0
  32. data/lib/generators/templates/imgareaselect/border-anim-v.gif +0 -0
  33. data/lib/generators/templates/imgareaselect/border-h.gif +0 -0
  34. data/lib/generators/templates/imgareaselect/border-v.gif +0 -0
  35. data/lib/generators/templates/imgareaselect/imgareaselect-animated.css +41 -0
  36. data/lib/generators/templates/imgareaselect/imgareaselect-default.css +41 -0
  37. data/lib/generators/templates/imgareaselect/imgareaselect-deprecated.css +36 -0
  38. data/lib/generators/templates/jquery.fancybox-1.3.4.pack.js +46 -0
  39. data/lib/generators/templates/jquery.imgareaselect.pack.js +1 -0
  40. data/lib/generators/templates/plupload.flash.swf +0 -0
  41. data/lib/generators/templates/plupload.full.min.js +2 -0
  42. data/lib/imaginable.rb +22 -0
  43. data/lib/imaginable/form_builder.rb +100 -0
  44. data/lib/imaginable/image.rb +24 -0
  45. data/lib/imaginable/model.rb +67 -0
  46. data/lib/imaginable/railtie.rb +27 -0
  47. data/lib/imaginable/schema.rb +11 -0
  48. data/lib/imaginable/version.rb +3 -0
  49. metadata +52 -5
@@ -0,0 +1,429 @@
1
+ (function($){
2
+
3
+ var Imaginable = function(element, options) {
4
+ // CONSTRANTS
5
+ var ASPECT_RATIOS = {portrait: '13:20'}
6
+ var ASPECT_RATIO_IDS = {original: 0, square: 1, tv: 2, wide: 3, portrait: 4}
7
+
8
+ // ELEMENTS - Main
9
+ var main_elem = $(element);
10
+ var uploader_elem;
11
+ var cropper_elem;
12
+ // ELEMENTS - Uploader
13
+ var file_list_elem;
14
+ var preview_image_elem;
15
+ // ELEMENTS - Cropper
16
+ var crop_image_elem;
17
+ var save_crop_button_elem;
18
+ var cancel_crop_button_elem;
19
+
20
+ // FORM ELEMENTS
21
+ var uuid_field;
22
+ var token_field;
23
+ var version_field;
24
+
25
+ // SETTINGS
26
+ var settings = $.extend({
27
+ prefix: main_elem.data('imaginable-prefix'),
28
+ scaleServer: main_elem.data('imaginable-scale-server') || 'http://127.0.0.1:3333',
29
+ uploadServer: main_elem.data('imaginable-upload-server') || 'http://127.0.0.1:3001',
30
+ preview_width: main_elem.data('imaginable-preview-width') || 250,
31
+ enable_cropping: main_elem.data('imaginable-enable-cropping') || true,
32
+ force_crop: main_elem.data('imaginable-force-crop') || false,
33
+ format: main_elem.data('imaginable-format') || 'original',
34
+ new_version: main_elem.data('imaginable-new-version') + '' || '0',
35
+
36
+ force_crop: main_elem.data('imaginable-force-crop') || false,
37
+
38
+ runtimes: 'flash',
39
+ max_file_size: '10mb',
40
+ file_data_name: 'image_file',
41
+ multipart: true,
42
+ auto_start: true,
43
+ flash_swf_url: '/javascripts/plupload.flash.swf',
44
+ silverlight_xap_url: '/javascripts/plupload.silverlight.xap',
45
+ filters: [
46
+ {title: "Image files", extensions: "jpg,gif,png"},
47
+ ]
48
+ }, options || {});
49
+
50
+ // INSTANCE
51
+ var obj = this;
52
+
53
+ // INSTANCE VARIABLES - Shared
54
+ var existing_image = false;
55
+ var image_version;
56
+
57
+ // INSTANCE VARIABLES - Uploader
58
+ var uploader;
59
+ var current_image_uuid;
60
+ var current_image_token;
61
+ var current_image_width;
62
+ var current_image_height;
63
+
64
+ // INSTANCE VARIABLES - Cropper
65
+ var cropper;
66
+ var current_crop_points = null;
67
+
68
+ // Public methods
69
+ this.refreshPreviewImage = function() {
70
+ var preview_url = settings.scaleServer + '/image/' + current_image_uuid + '-' + image_version + '-' + settings.format + '-' + settings.preview_width + '.jpg';
71
+
72
+ preview_image_elem.attr('src', preview_url).load(function() {
73
+ preview_image_elem.fadeIn();
74
+ uploader.refresh();
75
+ });
76
+ }
77
+
78
+ this.refreshCroppingPreviewImage = function() {
79
+ var crop_preview_url = settings.scaleServer + '/image/' + current_image_uuid + '-' + image_version + '-original-600-600.jpg';
80
+
81
+ crop_image_elem.attr('src', crop_preview_url).load(function() {
82
+ if (settings.force_crop == true)
83
+ obj.showCropDialog();
84
+ });
85
+ }
86
+
87
+ this.showCropDialog = function() {
88
+ cropper_elem.trigger('click');
89
+ $.fancybox.center();
90
+ };
91
+
92
+ this.saveCropping = function() {
93
+ var crop_points = getCropPoints();
94
+
95
+ var prefix = 'crop' + ASPECT_RATIO_IDS[settings.format] + '_';
96
+ var x = crop_points['x1'];
97
+ var y = crop_points['y1'];
98
+ var width = crop_points['width'];
99
+ var image_data = {};
100
+ image_data[prefix + 'x'] = x
101
+ image_data[prefix + 'y'] = y
102
+ image_data[prefix + 'width'] = width;
103
+ var data = {_method: 'PUT', image: image_data, callback: '?', auth_token: current_image_token};
104
+
105
+ var url = settings.uploadServer + '/images/' + current_image_uuid;
106
+
107
+ console.log(data);
108
+
109
+ $.ajaxSetup({
110
+ headers: {
111
+ "X-CSRF-Token": $("meta[name='csrf-token']").attr('content')
112
+ }
113
+ });
114
+
115
+ $.ajax({
116
+ type: 'POST',
117
+ url: url,
118
+ data: data,
119
+ dataType: 'json',
120
+ success: onCroppingSaved
121
+ });
122
+
123
+ writeToFormFields();
124
+ };
125
+
126
+ // Private methods
127
+ var initialize = function() {
128
+ initializeElements();
129
+ initializeImageVersion();
130
+ initializeButtons();
131
+ initializeUploader();
132
+ initializeCropper();
133
+ };
134
+
135
+ var initializeElements = function() {
136
+ // Form Fields
137
+ uuid_field = $('#' + settings.prefix + '_uuid');
138
+ token_field = $('#' + settings.prefix + '_token');
139
+ version_field = $('#' + settings.prefix + '_version');
140
+
141
+ if (uuid_field.val() != null && uuid_field.val() != "") {
142
+ existing_image = true;
143
+ current_image_uuid = uuid_field.val();
144
+ current_image_token = token_field.val();
145
+ downloadImageMetadata();
146
+ }
147
+
148
+ // Uploader
149
+ uploader_elem = main_elem.find('.imaginable_browse_files_button').first();
150
+ file_list_elem = main_elem.find('.imaginable_file_list').first();
151
+ preview_image_elem = main_elem.find('.imaginable_preview_image').first();
152
+
153
+ // Cropper
154
+ cropper_elem = main_elem.find('.imaginable_crop_button').first();
155
+
156
+ crop_image_elem = main_elem.find('.imaginable_crop_image').first();
157
+ save_crop_button_elem = main_elem.find('.imaginable_save_crop_button').first();
158
+ cancel_crop_button_elem = main_elem.find('.imaginable_cancel_crop_button').first();
159
+ }
160
+
161
+ var initializeImageVersion = function() {
162
+ image_version = settings.new_version.replace(/'/, "").replace(/'/, "");
163
+
164
+ form_value = version_field.val();
165
+ if (form_value != null && form_value.length > 0)
166
+ obj.refreshPreviewImage();
167
+
168
+ //form_value = version_field.val();
169
+ //
170
+ //if (form_value != null && form_value.length > 0) {
171
+ // image_version = form_value;
172
+ //} else {
173
+ // image_version = settings.new_version;
174
+ //}
175
+ };
176
+
177
+ var initializeButtons = function() {
178
+ // Cropper
179
+ cancel_crop_button_elem.bind('click', onCancelCropButtonClick);
180
+ save_crop_button_elem.bind('click', onSaveCropButtonClick);
181
+ };
182
+
183
+ var initializeUploader = function() {
184
+ uploader = new plupload.Uploader({
185
+ runtimes: settings['runtimes'],
186
+ browse_button: uploader_elem.attr('id'),
187
+ container: uploader_elem.parent().first().attr('id'),
188
+ max_file_size: settings['max_file_size'],
189
+ url: settings['uploadServer'] + '/images',
190
+ file_data_name: settings['file_data_name'],
191
+ multipart: settings['multipart'],
192
+ flash_swf_url: settings['flash_swf_url'],
193
+ silverlight_xap_url: settings['silverlight_xap_url'],
194
+ filters: settings['filters']
195
+ });
196
+
197
+ uploader.init();
198
+
199
+ uploader.bind('FilesAdded', onUploaderFilesAdded);
200
+ uploader.bind('FilesRemoved', onUploaderFilesRemoved);
201
+ uploader.bind('UploadProgress', onUploaderUploadProgress);
202
+ uploader.bind('Error', onUploaderError);
203
+ uploader.bind('FileUploaded', onUploaderFileUploaded);
204
+ uploader.bind('UploadComplete', onUploaderUploadComplete);
205
+ };
206
+
207
+ var initializeCropper = function() {
208
+ cropper_elem.fancybox({
209
+ 'modal' : true,
210
+ onComplete: function() {
211
+ var crop_points = getCropPoints();
212
+
213
+ cropper = crop_image_elem.imgAreaSelect({
214
+ handles: true,
215
+ instance: true,
216
+ imageHeight: current_image_height,
217
+ imageWidth: current_image_width,
218
+ onSelectEnd: onAreaSelectorSelectEnd
219
+ });
220
+
221
+ if (settings.format != 'original')
222
+ cropper.setOptions({aspectRatio: ASPECT_RATIOS[settings.format]});
223
+
224
+ cropper.setSelection(crop_points['x1'],crop_points['y1'],crop_points['x2'],crop_points['y2'],false);
225
+ cropper.setOptions({ show: true });
226
+ cropper.update();
227
+ },
228
+ onCleanup: function() {
229
+ crop_image_elem.imgAreaSelect({
230
+ remove: true
231
+ });
232
+ }
233
+ });
234
+ };
235
+
236
+ var changeImageVersion = function(version) {
237
+ image_version = version;
238
+ writeToFormFields();
239
+ };
240
+
241
+ var getCropPoints = function() {
242
+ if (current_crop_points != null)
243
+ return current_crop_points;
244
+
245
+ current_crop_points = {x1: 0, x2: current_image_width, y1: 0, y2: current_image_height, width: current_image_width, height: current_image_height};
246
+
247
+ if (settings.format != 'original') {
248
+ var numeric_aspect_ratio = numericAspectRatio();
249
+ if (numeric_aspect_ratio > 1) {
250
+ // Width > Height
251
+ current_crop_points['x2'] = current_image_width;
252
+ current_crop_points['y2'] = Math.round(current_image_width * numeric_aspect_ratio);
253
+ current_crop_points['height'] = current_crop_points['y2'];
254
+ } else {
255
+ // Width < Height || Width == Height
256
+ current_crop_points['y2'] = current_image_height;
257
+ current_crop_points['x2'] = Math.round(current_image_height * numeric_aspect_ratio);
258
+ current_crop_points['width'] = current_crop_points['x2'];
259
+ }
260
+ }
261
+
262
+ return current_crop_points;
263
+ };
264
+
265
+ var resetCropPoints = function() {
266
+ current_crop_points = null;
267
+ current_scaled_crop_points = null;
268
+ };
269
+
270
+ var showCropButton = function() {
271
+ cropper_elem.fadeIn();
272
+ };
273
+
274
+ var numericAspectRatio = function() {
275
+ var format = settings.format;
276
+
277
+ if (format != 'original') {
278
+ var aspect_ratio = ASPECT_RATIOS[format];
279
+ return (d = (aspect_ratio || '').split(/:/))[0] / d[1];
280
+ } else {
281
+ return 0;
282
+ }
283
+ };
284
+
285
+ var writeToFormFields = function() {
286
+ uuid_field.val(current_image_uuid);
287
+ token_field.val(current_image_token);
288
+ version_field.val(image_version);
289
+ };
290
+
291
+ var downloadImageMetadata = function() {
292
+ var url = settings.uploadServer + '/images/' + current_image_uuid + '?callback=?';
293
+ $.getJSON(url, onDownloadImageMetadataComplete);
294
+ };
295
+
296
+ var onDownloadImageMetadataComplete = function(data) {
297
+ console.log(data);
298
+
299
+ current_image_width = data.image.width;
300
+ current_image_height = data.image.height;
301
+
302
+ // Make sure that crop points are initialized
303
+ getCropPoints();
304
+
305
+ var prefix = 'crop' + ASPECT_RATIO_IDS[settings.format] + '_';
306
+
307
+ current_crop_points.x1 = parseInt(data.image[prefix + 'x']);
308
+ current_crop_points.y1 = parseInt(data.image[prefix + 'y']);
309
+ current_crop_points.width = parseInt(data.image[prefix + 'width']);
310
+ current_crop_points.x2 = current_crop_points.x1 + current_crop_points.width;
311
+
312
+ var numeric_aspect_ratio = settings.format != 'original' ? numericAspectRatio() : current_image_width / current_image_height
313
+
314
+ current_crop_points.height = Math.round(parseFloat(current_crop_points.width) / numeric_aspect_ratio);
315
+ current_crop_points.y2 = current_crop_points.y1 + current_crop_points.height;
316
+
317
+ showCropButton();
318
+ console.log(current_crop_points);
319
+ };
320
+
321
+ var onUploaderFilesAdded = function(up, files) {
322
+ $.each(files, function(i, file) {
323
+ file_list_elem.append(
324
+ '<div id="' + file.id + '">' +
325
+ file.name + ' (' + plupload.formatSize(file.size) + ') <b></b>' +
326
+ '</div>');
327
+ });
328
+
329
+ up.refresh(); // Reposition Flash/Silverlight
330
+
331
+ if (settings.auto_start == true) up.start();
332
+ };
333
+
334
+ var onUploaderFilesRemoved = function(up, files) {
335
+ $.each(files, function(i, file) {
336
+ $('#' + file.id).remove();
337
+ });
338
+
339
+ up.refresh(); // Reposition Flash/Silverlight
340
+ };
341
+
342
+ var onUploaderUploadProgress = function(up, file) {
343
+ $('#' + file.id + " b").html(file.percent + "%");
344
+ };
345
+
346
+ var onUploaderError = function(up, err) {
347
+ file_list_elem.append("<div>Error: " + err.code +
348
+ ", Message: " + err.message +
349
+ (err.file ? ", File: " + err.file.name : "") +
350
+ "</div>"
351
+ );
352
+
353
+ up.refresh(); // Reposition Flash/Silverlight
354
+ };
355
+
356
+ var onUploaderFileUploaded = function(up, file, response) {
357
+ $('#' + file.id + " b").html("Done");
358
+ responseData = jQuery.parseJSON(response.response);
359
+ current_image_uuid = responseData.image.uuid;
360
+ current_image_token = responseData.auth_token;
361
+ current_image_width = responseData.image.width;
362
+ current_image_height = responseData.image.height;
363
+ resetCropPoints();
364
+ existing_image = false;
365
+ };
366
+
367
+ var onUploaderUploadComplete = function(up, files) {
368
+ writeToFormFields();
369
+ obj.refreshPreviewImage();
370
+ obj.refreshCroppingPreviewImage();
371
+ showCropButton();
372
+ up.splice();
373
+ };
374
+
375
+ var onCancelCropButtonClick = function(event) {
376
+ event.preventDefault();
377
+ $.fancybox.close();
378
+ };
379
+
380
+ var onSaveCropButtonClick = function(event) {
381
+ event.preventDefault();
382
+ obj.saveCropping();
383
+ }
384
+
385
+ var onAreaSelectorSelectEnd = function(img, selection) {
386
+ selection = cropper.getSelection(false);
387
+
388
+ current_crop_points['x1'] = selection['x1'];
389
+ current_crop_points['y1'] = selection['y1'];
390
+ current_crop_points['x2'] = selection['x2'];
391
+ current_crop_points['y2'] = selection['y2'];
392
+ current_crop_points['width'] = selection['width'];
393
+ current_crop_points['height'] = selection['height'];
394
+ };
395
+
396
+ var onCroppingSaved = function(response) {
397
+ changeImageVersion(response.new_version);
398
+ obj.refreshPreviewImage();
399
+ $.fancybox.close();
400
+ };
401
+
402
+ // Get it all rolling
403
+ initialize();
404
+ };
405
+
406
+ $.fn.imaginable = function(options) {
407
+ return this.each(function() {
408
+ var element = $(this);
409
+
410
+ // Return early if this element already has a plugin instance
411
+ if (element.data('imaginable')) return;
412
+
413
+ var imaginable = new Imaginable(this, options);
414
+
415
+ // Store plugin object in this element's data
416
+ element.data('imaginable', imaginable);
417
+ });
418
+ };
419
+
420
+ })(jQuery);
421
+
422
+ $(function() {
423
+
424
+ $('.imaginable').each(function(){
425
+ var el = $(this);
426
+ el.imaginable();
427
+ });
428
+
429
+ });
@@ -0,0 +1,6 @@
1
+ Imaginable.setup do |config|
2
+
3
+ config.upload_server = 'http://127.0.0.1:3001'
4
+ config.scale_server = 'http://127.0.0.1:3333'
5
+
6
+ end
@@ -0,0 +1,41 @@
1
+ /*
2
+ * imgAreaSelect animated border style
3
+ */
4
+
5
+ .imgareaselect-border1 {
6
+ background: url(border-anim-v.gif) repeat-y left top;
7
+ }
8
+
9
+ .imgareaselect-border2 {
10
+ background: url(border-anim-h.gif) repeat-x left top;
11
+ }
12
+
13
+ .imgareaselect-border3 {
14
+ background: url(border-anim-v.gif) repeat-y right top;
15
+ }
16
+
17
+ .imgareaselect-border4 {
18
+ background: url(border-anim-h.gif) repeat-x left bottom;
19
+ }
20
+
21
+ .imgareaselect-border1, .imgareaselect-border2,
22
+ .imgareaselect-border3, .imgareaselect-border4 {
23
+ filter: alpha(opacity=50);
24
+ opacity: 0.5;
25
+ }
26
+
27
+ .imgareaselect-handle {
28
+ background-color: #fff;
29
+ border: solid 1px #000;
30
+ filter: alpha(opacity=50);
31
+ opacity: 0.5;
32
+ }
33
+
34
+ .imgareaselect-outer {
35
+ background-color: #000;
36
+ filter: alpha(opacity=50);
37
+ opacity: 0.5;
38
+ }
39
+
40
+ .imgareaselect-selection {
41
+ }