motion-image-editor 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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