motion-image-editor 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bf6b38e31764220c4bb4d6f140089e3bdb50297
4
- data.tar.gz: cb67aebfe59a677c3965522e83ce44151ff9af61
3
+ metadata.gz: 226472c295b2d57d3bd62e85792534346b931730
4
+ data.tar.gz: 08016d9fb24343fbac4d2247ba543756f957617e
5
5
  SHA512:
6
- metadata.gz: 7b4f42115362f4ff5b14d2948949fe31db972b7d5d5fbbb608229778a3ad533468dfd724d48ec5fc8999842ff1fe0a20d4ba2b126b6b501ebef8e33d7a2f3f6f
7
- data.tar.gz: ce32cb9001e626e9425cb70d421643ab5621e56c1e80cbe477e3a6f69a852517800cf1ddf89136fd95d94557934d3d885685f9357efa3435b277a07ae5b6b892
6
+ metadata.gz: c3721b52b59c18805e7b4d7ca69807fc854536ecf340da76670d9c1dfc6405600e04ac6874a7acada985310c99e15e27241981f21d0ca19eba8c762fa91c5cc5
7
+ data.tar.gz: f2bfa5a4e7a5226cbc930b3172d40e04821269d6b200a7472bdcad2ae9b4cf5e9bb4fcc04b10fecf1fa515bab63c169a0dbb31d5c2775b71021a2d9183612678
@@ -3,12 +3,15 @@ class Motion; class ImageEditorController < UIViewController
3
3
  MINIMUM_SCALE = 1
4
4
  MAXIMUM_SCALE = 3
5
5
 
6
- attr_reader :touch_center,
7
- :scale_center,
8
- :scale,
9
- :output_width,
10
- :source_image,
11
- :crop_rect
6
+ attr_reader :source_image, :crop_rect, :output_width
7
+ attr_writer :rotation_enabled, :enforce_bounds
8
+
9
+ def initWithNibName(nib, bundle: bundle)
10
+ super.tap do |controller|
11
+ controller.rotation_enabled = true
12
+ controller.enforce_bounds = false
13
+ end
14
+ end
12
15
 
13
16
  def viewDidLoad
14
17
  super
@@ -20,6 +23,14 @@ class Motion; class ImageEditorController < UIViewController
20
23
  setup_constraints
21
24
  end
22
25
 
26
+ def viewDidAppear(animated)
27
+ super
28
+
29
+ image_view.image = preview_image
30
+
31
+ reset
32
+ end
33
+
23
34
  def add_subviews
24
35
  view.addSubview(crop_view)
25
36
  view.insertSubview(image_view, belowSubview: crop_view)
@@ -46,6 +57,53 @@ class Motion; class ImageEditorController < UIViewController
46
57
  views: { 'crop' => crop_view }))
47
58
  end
48
59
 
60
+ def source_image=(image)
61
+ if image != source_image
62
+ @source_image = image
63
+ @preview_image = nil
64
+ end
65
+ end
66
+
67
+ def crop_rect=(rect)
68
+ @crop_rect = rect
69
+
70
+ crop_view.crop_rect = rect
71
+ end
72
+
73
+ def handle_gesture_state?(state)
74
+ case state
75
+ when UIGestureRecognizerStateEnded || UIGestureRecognizerStateCancelled
76
+ new_scale = bounded_scale(scale)
77
+
78
+ delta_x = scale_center.x - image_view.bounds.size.width / 2.0
79
+ delta_y = scale_center.y - image_view.bounds.size.height / 2.0
80
+
81
+ transform = CGAffineTransformTranslate(image_view.transform, delta_x, delta_y)
82
+
83
+ transform = CGAffineTransformScale(transform, new_scale / scale , new_scale / scale)
84
+
85
+ transform = CGAffineTransformTranslate(transform, -delta_x, -delta_y)
86
+
87
+ view.userInteractionEnabled = false
88
+
89
+ UIView.animateWithDuration(
90
+ ANIMATION_DURATION,
91
+ delay: 0,
92
+ options: UIViewAnimationOptionCurveEaseOut,
93
+ animations: -> { image_view.transform = transform },
94
+ completion: -> (finished) {
95
+ view.userInteractionEnabled = true
96
+ @scale = new_scale
97
+ })
98
+
99
+ check_bounds if enforce_bounds?
100
+
101
+ false
102
+ else
103
+ true
104
+ end
105
+ end
106
+
49
107
  def process(&block)
50
108
  view.userInteractionEnabled = false
51
109
 
@@ -74,19 +132,6 @@ class Motion; class ImageEditorController < UIViewController
74
132
  end
75
133
  end
76
134
 
77
- def crop_rect=(rect)
78
- @crop_rect = rect
79
-
80
- crop_view.crop_rect = rect
81
- end
82
-
83
- def scale_reset_orientations
84
- [ UIImageOrientationUpMirrored,
85
- UIImageOrientationDownMirrored,
86
- UIImageOrientationLeftMirrored,
87
- UIImageOrientationRightMirrored ]
88
- end
89
-
90
135
  def transform_image(transform, source_image: source_image, source_size: source_size, source_orientation: source_orientation, output_width: output_width, crop_rect: crop_rect, image_view_size: image_view_size)
91
136
  aspect = crop_rect.size.height / crop_rect.size.width
92
137
  output_size = CGSizeMake(output_width, output_width * aspect)
@@ -145,14 +190,6 @@ class Motion; class ImageEditorController < UIViewController
145
190
  CGBitmapContextCreateImage(context)
146
191
  end
147
192
 
148
- def viewDidAppear(animated)
149
- super
150
-
151
- image_view.image = preview_image
152
-
153
- reset
154
- end
155
-
156
193
  def reset(options = {})
157
194
  animated = options.fetch(:animated, false)
158
195
 
@@ -163,8 +200,8 @@ class Motion; class ImageEditorController < UIViewController
163
200
  crop_aspect = crop_rect.size.height / crop_rect.size.width
164
201
 
165
202
  if source_aspect > crop_aspect
166
- w = crop_rect.size.width
167
- h = source_aspect * w
203
+ w = crop_rect.size.width
204
+ h = source_aspect * w
168
205
  else
169
206
  h = crop_rect.size.height
170
207
  w = h / source_aspect
@@ -189,7 +226,53 @@ class Motion; class ImageEditorController < UIViewController
189
226
  end
190
227
  end
191
228
 
192
- # Touch handling
229
+ def check_bounds
230
+ y_offset = 0
231
+ x_offset = 0
232
+
233
+ if image_view.frame.origin.x > crop_rect.origin.x
234
+ x_offset = -(image_view.frame.origin.x - crop_rect.origin.x)
235
+ new_right_x = CGRectGetMaxX(image_view.frame) + x_offset
236
+
237
+ if new_right_x < CGRectGetMaxX(crop_rect)
238
+ x_offset = CGRectGetMaxX(crop_rect) - CGRectGetMaxX(image_view.frame)
239
+ end
240
+ elsif CGRectGetMaxX(image_view.frame) < CGRectGetMaxX(crop_rect)
241
+ x_offset = CGRectGetMaxX(crop_rect) - CGRectGetMaxX(image_view.frame)
242
+ new_left_x = image_view.frame.origin.x + x_offset
243
+
244
+ if new_left_x > crop_rect.origin.x
245
+ x_offset = crop_rect.origin.x - image_view.frame.origin.x
246
+ end
247
+ end
248
+
249
+ if image_view.frame.origin.y > crop_rect.origin.y
250
+ y_offset = -(image_view.frame.origin.y - crop_rect.origin.y)
251
+ new_bottom_y = CGRectGetMaxY(image_view.frame) + y_offset
252
+
253
+ if new_bottom_y < CGRectGetMaxY(crop_rect)
254
+ y_offset = CGRectGetMaxY(crop_rect) - CGRectGetMaxY(image_view.frame)
255
+ end
256
+ elsif CGRectGetMaxY(image_view.frame) < CGRectGetMaxY(crop_rect)
257
+ y_offset = CGRectGetMaxY(crop_rect) - CGRectGetMaxY(image_view.frame)
258
+ new_top_y = image_view.frame.origin.y + y_offset
259
+
260
+ if new_top_y > crop_rect.origin.y
261
+ y_offset = crop_rect.origin.y - image_view.frame.origin.y
262
+ end
263
+ end
264
+
265
+ if x_offset || y_offset
266
+ view.userInteractionEnabled = false
267
+ transform = CGAffineTransformTranslate(image_view.transform, x_offset / scale, y_offset / scale)
268
+ UIView.animateWithDuration(
269
+ ANIMATION_DURATION,
270
+ delay: 0,
271
+ options: UIViewAnimationOptionCurveEaseOut,
272
+ animations: -> { image_view.transform = transform },
273
+ completion: -> (finished) { view.userInteractionEnabled = true })
274
+ end
275
+ end
193
276
 
194
277
  def touchesBegan(touches, withEvent: event)
195
278
  handle_touches(event.allTouches)
@@ -221,48 +304,19 @@ class Motion; class ImageEditorController < UIViewController
221
304
  end
222
305
  end
223
306
 
224
- def handle_state?(state)
225
- if state == UIGestureRecognizerStateEnded
226
- new_scale = bounded_scale(scale)
227
-
228
- delta_x = scale_center.x - image_view.bounds.size.width / 2.0
229
- delta_y = scale_center.y - image_view.bounds.size.height / 2.0
230
-
231
- transform = CGAffineTransformTranslate(image_view.transform, delta_x, delta_y)
232
-
233
- transform = CGAffineTransformScale(transform, new_scale / scale , new_scale / scale)
234
-
235
- transform = CGAffineTransformTranslate(transform, -delta_x, -delta_y)
236
-
237
- view.userInteractionEnabled = false
238
-
239
- UIView.animateWithDuration(
240
- ANIMATION_DURATION,
241
- delay: 0,
242
- options: UIViewAnimationOptionCurveEaseOut,
243
- animations: -> { image_view.transform = transform },
244
- completion: -> (finished) {
245
- view.userInteractionEnabled = true
246
- @scale = new_scale
247
- })
248
-
249
- false
250
- else
251
- true
252
- end
253
- end
254
-
255
307
  def handle_pan(recognizer)
256
- translation = recognizer.translationInView(image_view)
257
- transform = CGAffineTransformTranslate(image_view.transform, translation.x, translation.y)
308
+ if handle_gesture_state? recognizer.state
309
+ translation = recognizer.translationInView(image_view)
310
+ transform = CGAffineTransformTranslate(image_view.transform, translation.x, translation.y)
258
311
 
259
- image_view.transform = transform
312
+ image_view.transform = transform
260
313
 
261
- recognizer.setTranslation(CGPointZero, inView: crop_view)
314
+ recognizer.setTranslation(CGPointZero, inView: crop_view)
315
+ end
262
316
  end
263
317
 
264
318
  def handle_pinch(recognizer)
265
- if handle_state? recognizer.state
319
+ if handle_gesture_state? recognizer.state
266
320
  if recognizer.state == UIGestureRecognizerStateBegan
267
321
  @scale_center = @touch_center
268
322
  end
@@ -283,22 +337,37 @@ class Motion; class ImageEditorController < UIViewController
283
337
  end
284
338
 
285
339
  def handle_rotation(recognizer)
286
- delta_x = touch_center.x - image_view.bounds.size.width / 2
287
- delta_y = touch_center.y - image_view.bounds.size.height / 2
340
+ if rotation_enabled? && handle_gesture_state?(recognizer.state)
341
+ delta_x = touch_center.x - image_view.bounds.size.width / 2
342
+ delta_y = touch_center.y - image_view.bounds.size.height / 2
288
343
 
289
- transform = CGAffineTransformTranslate(image_view.transform, delta_x, delta_y)
290
- transform = CGAffineTransformRotate(transform, recognizer.rotation)
291
- transform = CGAffineTransformTranslate(transform, -delta_x, -delta_y)
344
+ transform = CGAffineTransformTranslate(image_view.transform, delta_x, delta_y)
345
+ transform = CGAffineTransformRotate(transform, recognizer.rotation)
346
+ transform = CGAffineTransformTranslate(transform, -delta_x, -delta_y)
292
347
 
293
- image_view.transform = transform
348
+ image_view.transform = transform
294
349
 
295
- recognizer.rotation = 0
350
+ recognizer.rotation = 0
351
+ end
296
352
  end
297
353
 
298
354
  def handle_tap(recognizer)
299
355
  reset(animated: true)
300
356
  end
301
357
 
358
+ def bounded_scale(scale)
359
+ return scale if (MINIMUM_SCALE..MAXIMUM_SCALE).include? scale
360
+
361
+ scale < MINIMUM_SCALE ? MINIMUM_SCALE : MAXIMUM_SCALE
362
+ end
363
+
364
+ def scale_reset_orientations
365
+ [ UIImageOrientationUpMirrored,
366
+ UIImageOrientationDownMirrored,
367
+ UIImageOrientationLeftMirrored,
368
+ UIImageOrientationRightMirrored ]
369
+ end
370
+
302
371
  def pan_recognizer
303
372
  @pan_recognizer ||= UIPanGestureRecognizer.alloc.initWithTarget(self, action: 'handle_pan:').tap do |recognizer|
304
373
  recognizer.cancelsTouchesInView = false
@@ -326,19 +395,6 @@ class Motion; class ImageEditorController < UIViewController
326
395
  end
327
396
  end
328
397
 
329
- def source_image=(image)
330
- if image != source_image
331
- @source_image = image
332
- @preview_image = nil
333
- end
334
- end
335
-
336
- def bounded_scale(scale)
337
- return scale if (MINIMUM_SCALE..MAXIMUM_SCALE).include? scale
338
-
339
- scale < MINIMUM_SCALE ? MINIMUM_SCALE : MAXIMUM_SCALE
340
- end
341
-
342
398
  def preview_image
343
399
  @preview_image ||= source_image.resizedImageToFitInSize(view.bounds.size, scaleIfSmaller: false)
344
400
  end
@@ -355,7 +411,27 @@ class Motion; class ImageEditorController < UIViewController
355
411
  end
356
412
  end
357
413
 
414
+ def scale
415
+ @scale ||= 1
416
+ end
417
+
418
+ def touch_center
419
+ @touch_center ||= CGPointZero
420
+ end
421
+
422
+ def scale_center
423
+ @scale_center ||= CGPointZero
424
+ end
425
+
358
426
  def prefersStatusBarHidden
359
427
  true
360
428
  end
429
+
430
+ def rotation_enabled?
431
+ !!@rotation_enabled
432
+ end
433
+
434
+ def enforce_bounds?
435
+ !!@enforce_bounds
436
+ end
361
437
  end; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-image-editor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Devon Blandin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-29 00:00:00.000000000 Z
11
+ date: 2013-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: motion-cocoapods