fastlane-plugin-framer 1.0.3 → 1.0.4

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
- SHA1:
3
- metadata.gz: 968bd2a30dcbe75d3a0aaf7de7644a75933490b8
4
- data.tar.gz: 68fdf41192c9f490d4fe6c81393cc860f9b75478
2
+ SHA256:
3
+ metadata.gz: 7f483825329db96f65ffb7a835c9d859e458e25eba3f592312f5eecf9fc172b8
4
+ data.tar.gz: afc487ad12cec280e48a57fd8bd21314bd9eeba576eaf83c4bc64a8043b70a47
5
5
  SHA512:
6
- metadata.gz: '09f51aa885488c576f6ea7b91b51119fc2b06a8a8e513da640c5e533c533c8ef344a0f9a6320114c287de531dddbb0e536f970ddf511d3a903a548dea387c32a'
7
- data.tar.gz: 3337431151a6fe493cbc4761bbfe1e2b0e336e21674771b973a67eee11bd97a7a45de1b4d3280053c045179d16912a4806dae72828b71b3fc98f8c9f031964b2
6
+ metadata.gz: 3fe4de5acdb69e3bfd2ba3c3084bff037c4be88db36073c000917c7316ce0ee63ce4314aeb84069edec1cd180fea9b40d6d6dffa3e3496cff2135c814627f645
7
+ data.tar.gz: 42e043f83d7b16f9024e9e4aecd26b148cd04711c16b288edbdbf41085421bb3615505cf5ba511574d29a09af743474c40e58a1390a83bc1a6c0aeff0104af8d
data/README.md CHANGED
@@ -26,9 +26,9 @@ You can specify the position and the size of the screen in the template and (opt
26
26
 
27
27
  Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin.
28
28
 
29
- There are 2 lanes, one for a simple flow (`demo-1`) and another with more languages and screens (`demo-2`).
29
+ There are 4 lanes: for a simple flow (`demo-1`), with more languages and screens (`demo-2`), 3ª for android screenshots with rotation images and more them one frame(`demo-3`) and last for ios screenshots (`demo-4`).
30
30
 
31
- Try them by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane demo_1` or `bundle exec fastlane demo_2`.
31
+ Try them by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane` and select lane.
32
32
 
33
33
  ## Configuration
34
34
 
@@ -40,16 +40,16 @@ In order to work, you need to configure each template and the text to draw in th
40
40
 
41
41
  The **framer** action support 4 optional parameters (default values are used).
42
42
 
43
- | Option | Description | Default |
44
- | ----------------- | -------- | ------------ |
45
- | `source_folder` | path to the folder that contains raw screenshots and `text.json` file | `./fastlane/framer/screens` |
46
- | `template_folder` | path to the folder that contains the templates images and configuration | `./fastlane/framer/templates` |
43
+ | Option | Description | Default |
44
+ | ----------------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------- |
45
+ | `source_folder` | path to the folder that contains raw screenshots and `text.json` file | `./fastlane/framer/screens` |
46
+ | `template_folder` | path to the folder that contains the templates images and configuration | `./fastlane/framer/templates` |
47
47
  | `output_folder` | path to the folder that will contains the final images, framed. Used then by `deliver` | `./fastlane/screenshots` (default one for `deliver`) |
48
- | `output_suffix` | filenam suffix for the framed images | `-framed` |
48
+ | `output_suffix` | filenam suffix for the framed images | `-framed` |
49
49
 
50
50
  ### Template Configuration
51
51
 
52
- In the template folder you choose, there must be a `Config.json` file (see [example](fastlane/demo-1/templates/Config.json)). In there you will found
52
+ In the template folder you choose, there must be a `config.json` file (see [example](fastlane/demo-1/templates/config.json)). In there you will found
53
53
 
54
54
  - a default configuration for all templates
55
55
  - a custom configuration for each template (if needed).
@@ -76,36 +76,39 @@ There are keys for configuring screeshot and for the text.
76
76
 
77
77
  #### Image
78
78
 
79
- | Key | Type | Description |
80
- | -------------- | --------:| ------------:|
81
- | `offset` | String | Pixel position in the format `+[X value]+[Y value]` |
82
- | `width` | Number | space available, in pixel, for the screen |
83
- | `add_below` | Boolean | add screen below the template or not |
79
+ | Key | Type | Description |
80
+ | ----------- | ------: | -----------------------------------------------------------: |
81
+ | `offset` | String | Pixel position in the format `+[X value]+[Y value]` |
82
+ | `width` | Number | space available, in pixel, for the screen |
83
+ | `add_below` | Boolean | add screen below the template or not |
84
+ | `rotation` | Number | degrees for rotate image |
85
+ | `previous` | Object | same parameters as image, used to display the previous image |
86
+ | `next` | Object | same parameters as image, used to display the previous image |
84
87
 
85
88
  #### Text
86
89
 
87
- | Key | Type | Description |
88
- | -------------- | --------:| ------------:|
89
- | `offset_x` | Number | X position of the text block |
90
- | `offset_y` | Number | Y position of the text block|
91
- | `height` | Number | height of the text block |
92
- | `size` | Number | font size |
93
- | `font` | String | path of custom font file to use |
94
- | `color` | String | color for the text in hex format (ex. `#545454`) |
95
- | `padding` | Number | horizontal internal padding of the text block |
90
+ | Key | Type | Description |
91
+ | ---------- | -----: | -----------------------------------------------: |
92
+ | `offset_x` | Number | X position of the text block |
93
+ | `offset_y` | Number | Y position of the text block |
94
+ | `height` | Number | height of the text block |
95
+ | `size` | Number | font size |
96
+ | `font` | String | path of custom font file to use |
97
+ | `color` | String | color for the text in hex format (ex. `#545454`) |
98
+ | `padding` | Number | horizontal internal padding of the text block |
96
99
 
97
100
  ### Screenshots Text
98
101
 
99
102
  If you want some text in the final framed images, you need to create a `text.json` file and put it with the raw device screenshots. It makes sense to commit this file in your repository.
100
103
 
101
- `text.json` is a simple map where *key* is the part of the screenshot filename (I suggest the same string you use with the `snapshot()` command on your UI tests.
102
- The *value* can be any strings.
104
+ `text.json` is a simple map where _key_ is the part of the screenshot filename (I suggest the same string you use with the `snapshot()` command on your UI tests.
105
+ The _value_ can be any strings.
103
106
 
104
107
  ### Colors
105
108
 
106
109
  You can customize the color of the text and the background color applyed below the template (if you have transparencies on the template, you can fill them with the background color).
107
110
 
108
- `colors.json` is a simple map where *key* is part of the screenshot filename. The *value* is a map with 2 optional keys, *text* and *background*.
111
+ `colors.json` is a simple map where _key_ is part of the screenshot filename. The _value_ is a map with 2 optional keys, _text_ and _background_.
109
112
 
110
113
  ```
111
114
  {
@@ -119,16 +122,18 @@ You can customize the color of the text and the background color applyed below t
119
122
  }
120
123
  ```
121
124
 
122
- Default values can be defined inside the *default* map.
125
+ Default values can be defined inside the _default_ map.
123
126
 
124
127
  ## Run tests for this plugin
125
128
 
126
129
  To run both the tests, and code style validation, run
130
+
127
131
  ```
128
132
  rake
129
133
  ```
130
134
 
131
135
  To automatically fix many of the styling issues, use
136
+
132
137
  ```
133
138
  rubocop -a
134
139
  ```
@@ -9,7 +9,9 @@ module Fastlane
9
9
  attr_accessor :width, :height
10
10
 
11
11
  attr_accessor :file
12
- attr_accessor :imageOffset, :imageWidth, :imageBelow
12
+ attr_accessor :imageOffset, :imageWidth, :imageBelow, :imageRotation
13
+ attr_accessor :imagePreviousOffset, :imagePreviousWidth, :imagePreviousRotation
14
+ attr_accessor :imageNextOffset, :imageNextWidth, :imageNextRotation
13
15
  attr_accessor :textOffsetX, :textOffsetY, :textWidth, :textHeight, :textPadding, :textSize, :textFont
14
16
  end
15
17
 
@@ -35,6 +37,7 @@ module Fastlane
35
37
  source_folder = params[:source_folder]
36
38
  output_folder = params[:output_folder]
37
39
  template_folder = params[:template_folder]
40
+ list_files = Dir.glob("#{source_folder}/**/*.png").sort
38
41
  templates = []
39
42
  platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
40
43
 
@@ -44,8 +47,8 @@ module Fastlane
44
47
 
45
48
  # Process each screen
46
49
  UI.success "Processing screenshots from #{source_folder}"
47
- Dir.glob("#{source_folder}/**/*.png") do |file|
48
- UI.message "Processing #{file}"
50
+ list_files.each_with_index do |file, index|
51
+ UI.message "Processing #{file} index #{index}"
49
52
 
50
53
  template = self.find_template(templates, file, platform)
51
54
  if template.nil?
@@ -57,14 +60,14 @@ module Fastlane
57
60
  text = self.find_text(source_folder, file)
58
61
  UI.verbose "Using text: #{text}"
59
62
 
60
- colors = self.find_colors(source_folder, file)
63
+ colors = self.find_colors(source_folder, file, template_folder)
61
64
  UI.verbose "Using colors: #{colors}"
62
65
 
63
66
  output = self.find_output(source_folder, file, output_folder, params[:output_suffix])
64
67
  UI.verbose "Saving to: #{output}"
65
68
 
66
- # Do the magic
67
- self.combine(file, template, colors, text, output)
69
+ # # Do the magic
70
+ self.combine(file, template, colors, text, output, list_files, index)
68
71
 
69
72
  UI.verbose "Framed screenshot #{output}"
70
73
  end
@@ -74,7 +77,7 @@ module Fastlane
74
77
  end
75
78
 
76
79
  def self.load_templates(template_folder)
77
- json_file_path = "#{template_folder}/Config.json"
80
+ json_file_path = "#{template_folder}/config.json"
78
81
 
79
82
  UI.user_error!("Missing Config.json file in template folder") unless File.exist?(json_file_path)
80
83
 
@@ -86,7 +89,6 @@ module Fastlane
86
89
 
87
90
  # Detect available templates
88
91
  templates = []
89
-
90
92
  Dir.glob("#{template_folder}/**/*.png") do |file|
91
93
 
92
94
  name = File.basename(file, ".png")
@@ -110,18 +112,30 @@ module Fastlane
110
112
  next
111
113
  end
112
114
 
113
- # Set config
114
- template.imageOffset = (config_custom['image'] && config_custom['image']['offset']) || (config_default['image'] && config_default['image']['offset'])
115
- template.imageWidth = (config_custom['image'] && config_custom['image']['width']) || (config_default['image'] && config_default['image']['width'])
116
- template.imageBelow = (config_custom['image'] && config_custom['image']['add_below']) || (config_default['image'] && config_default['image']['add_below']) || false
117
-
118
- template.textFont = (config_custom['text'] && config_custom['text']['font']) || (config_default['text'] && config_default['text']['font'])
119
- template.textSize = (config_custom['text'] && config_custom['text']['size']) || (config_default['text'] && config_default['text']['size'])
120
- template.textWidth = (config_custom['text'] && config_custom['text']['width']) || (config_default['text'] && config_default['text']['width'])
121
- template.textHeight = (config_custom['text'] && config_custom['text']['height']) || (config_default['text'] && config_default['text']['height'])
122
- template.textPadding = (config_custom['text'] && config_custom['text']['padding']) || (config_default['text'] && config_default['text']['padding']) || 0
123
- template.textOffsetX = (config_custom['text'] && config_custom['text']['offset_x']) || (config_default['text'] && config_default['text']['offset_x']) || 0
124
- template.textOffsetY = (config_custom['text'] && config_custom['text']['offset_y']) || (config_default['text'] && config_default['text']['offset_y']) || 0
115
+ # set image
116
+ template.imageOffset = (config_custom['image'] && config_custom['image']['offset']) || (config_default['image'] && config_default['image']['offset'])
117
+ template.imageWidth = (config_custom['image'] && config_custom['image']['width']) || (config_default['image'] && config_default['image']['width'])
118
+ template.imageBelow = (config_custom['image'] && config_custom['image']['add_below']) || (config_default['image'] && config_default['image']['add_below']) || false
119
+ template.imageRotation = (config_custom['image'] && config_custom['image']['rotation']) || (config_default['image'] && config_default['image']['rotation'])
120
+
121
+ # set image back
122
+ template.imagePreviousOffset = (config_custom['image']['previous'] && config_custom['image']['previous']['offset']) || (config_default['image']['previous'] && config_default['image']['previous']['offset'])
123
+ template.imagePreviousWidth = (config_custom['image']['previous'] && config_custom['image']['previous']['width']) || (config_default['image']['previous'] && config_default['image']['previous']['width'])
124
+ template.imagePreviousRotation = (config_custom['image']['previous'] && config_custom['image']['previous']['rotation']) || (config_default['image']['previous'] && config_default['image']['previous']['rotation'])
125
+
126
+ # set image next
127
+ template.imageNextOffset = (config_custom['image']['next'] && config_custom['image']['next']['offset']) || (config_default['image']['next'] && config_default['image']['next']['offset'])
128
+ template.imageNextWidth = (config_custom['image']['next'] && config_custom['image']['next']['width']) || (config_default['image']['next'] && config_default['image']['next']['width'])
129
+ template.imageNextRotation = (config_custom['image']['next'] && config_custom['image']['next']['rotation']) || (config_default['image']['next'] && config_default['image']['next']['rotation'])
130
+
131
+ # set font
132
+ template.textFont = (config_custom['text'] && config_custom['text']['font']) || (config_default['text'] && config_default['text']['font'])
133
+ template.textSize = (config_custom['text'] && config_custom['text']['size']) || (config_default['text'] && config_default['text']['size'])
134
+ template.textWidth = (config_custom['text'] && config_custom['text']['width']) || (config_default['text'] && config_default['text']['width'])
135
+ template.textHeight = (config_custom['text'] && config_custom['text']['height']) || (config_default['text'] && config_default['text']['height'])
136
+ template.textPadding = (config_custom['text'] && config_custom['text']['padding']) || (config_default['text'] && config_default['text']['padding']) || 0
137
+ template.textOffsetX = (config_custom['text'] && config_custom['text']['offset_x']) || (config_default['text'] && config_default['text']['offset_x']) || 0
138
+ template.textOffsetY = (config_custom['text'] && config_custom['text']['offset_y']) || (config_default['text'] && config_default['text']['offset_y']) || 0
125
139
 
126
140
  templates << template
127
141
  end
@@ -163,7 +177,7 @@ module Fastlane
163
177
  return result.last if result
164
178
  end
165
179
 
166
- def self.find_colors(source_dir, screenshot_file)
180
+ def self.find_colors(source_dir, screenshot_file, colors_dir)
167
181
 
168
182
  # Default values
169
183
  colors = Colors.new
@@ -172,7 +186,7 @@ module Fastlane
172
186
 
173
187
  # Read values from file
174
188
  directory = File.dirname(screenshot_file)
175
- colors_path = File.join(directory, "colors.json")
189
+ colors_path = File.join(colors_dir, "colors.json")
176
190
 
177
191
  while directory.start_with?(source_dir) && !File.exist?(colors_path) do
178
192
  directory = File.dirname(directory)
@@ -226,7 +240,16 @@ module Fastlane
226
240
  return file_path
227
241
  end
228
242
 
229
- def self.combine(screenshot_file, template, colors, text, output_file)
243
+ # Magic is HERE
244
+ def self.combine(screenshot_file, template, colors, text, output_file, list_files, index)
245
+
246
+ # Get list lenght
247
+ list_lenght = list_files.length()
248
+
249
+ # Var images
250
+ screenshot_img_back = nil
251
+ screenshot_img = nil
252
+ screenshot_img_next = nil
230
253
 
231
254
  # Prepare base image
232
255
  result_img = MiniMagick::Image.open("#{Framer::ROOT}/assets/background.png")
@@ -243,20 +266,86 @@ module Fastlane
243
266
 
244
267
  # Get template image
245
268
  template_img = MiniMagick::Image.open(template.file)
269
+
270
+ # Get back screenshot
271
+ unless template.imagePreviousOffset.nil?
272
+ if list_lenght >= index -1
273
+ screenshot_img_back = MiniMagick::Image.open(list_files[index -1]).auto_orient
274
+ screenshot_img_back.resize "#{template.imagePreviousWidth}x"
275
+ unless template.imagePreviousRotation.nil?
276
+ screenshot_img_back.combine_options do |cmd|
277
+ cmd.background "rgba(255,255,255,0.0)" # transparent
278
+ cmd.rotate(template.imagePreviousRotation.to_f)
279
+ end
280
+ end
281
+ else
282
+ UI.error "Unable to find back screenshot index #{index-1} in #{list_lenght}"
283
+ end
284
+ end
246
285
 
247
286
  # Get screenshot image
248
287
  screenshot_img = MiniMagick::Image.open(screenshot_file).auto_orient
249
-
288
+
250
289
  # Resize screenshot to fit template
251
290
  screenshot_img.resize "#{template.imageWidth}x"
291
+
292
+ # rotate screenshot
293
+ unless template.imageRotation.nil?
294
+ screenshot_img.combine_options do |cmd|
295
+ cmd.background "rgba(255,255,255,0.0)" # transparent
296
+ cmd.rotate(template.imageRotation.to_f)
297
+ end
298
+ end
299
+
300
+ # Get next screenshot
301
+ unless template.imageNextOffset.nil?
302
+ if list_lenght >= index + 1
303
+ image_path = list_files[index+1]
304
+ list_files.each_with_index do |_file, _index|
305
+ if _index === index
306
+ print("file: ", _file, " index ", _index, " my index ", index)
307
+ end
308
+ end
309
+ # print("aqui jovem: ", image_path, " list_lenght ", list_lenght, " index ", index)
310
+ screenshot_img_next = MiniMagick::Image.open(list_files[index]).auto_orient
311
+ screenshot_img_next.resize "#{template.imageNextWidth}x"
312
+ unless template.imageNextRotation.nil?
313
+ screenshot_img_next.combine_options do |cmd|
314
+ cmd.background "rgba(255,255,255,0.0)" # transparent
315
+ cmd.rotate(template.imageNextRotation.to_f)
316
+ end
317
+ end
318
+ else
319
+ UI.error "Unable to find next screenshot index #{index+1} in #{list_lenght}"
320
+ end
321
+ end
252
322
 
253
323
  # Put screenshot over template
254
324
  if template.imageBelow
255
325
 
326
+ # Screenshot back
327
+ unless screenshot_img_back.nil?
328
+ result_img = result_img.composite(screenshot_img_back) do |c|
329
+ c.compose "Over"
330
+ c.geometry template.imagePreviousOffset.to_s
331
+
332
+ end
333
+ end
334
+
256
335
  # Screenshot first
257
336
  result_img = result_img.composite(screenshot_img) do |c|
258
337
  c.compose "Over"
259
338
  c.geometry template.imageOffset.to_s
339
+
340
+ end
341
+
342
+ # Screenshot next
343
+ unless screenshot_img_next.nil?
344
+ result_img = result_img.composite(screenshot_img_next) do |c|
345
+ c.compose "Over"
346
+ c.geometry template.imageNextOffset.to_s
347
+
348
+ end
260
349
  end
261
350
 
262
351
  # Template second
@@ -271,10 +360,29 @@ module Fastlane
271
360
  c.compose "Over"
272
361
  end
273
362
 
274
- # Screenshot second
363
+ # Screenshot back
364
+ unless screenshot_img_back.nil?
365
+ result_img = result_img.composite(screenshot_img_back) do |c|
366
+ c.compose "Over"
367
+ c.geometry template.imagePreviousOffset.to_s
368
+
369
+ end
370
+ end
371
+
372
+ # Screenshot first
275
373
  result_img = result_img.composite(screenshot_img) do |c|
276
374
  c.compose "Over"
277
375
  c.geometry template.imageOffset.to_s
376
+
377
+ end
378
+
379
+ # Screenshot next
380
+ unless screenshot_img_next.nil?
381
+ result_img = result_img.composite(screenshot_img_next) do |c|
382
+ c.compose "Over"
383
+ c.geometry template.imageNextOffset.to_s
384
+
385
+ end
278
386
  end
279
387
 
280
388
  end
@@ -294,7 +402,7 @@ module Fastlane
294
402
  text_img.combine_options do |c|
295
403
  c.font text_font
296
404
  c.pointsize template.textSize.to_s
297
- c.gravity "Center"
405
+ c.gravity "NorthWest"
298
406
  c.draw "text 0,0 '#{text}'"
299
407
  c.fill colors.text.to_s
300
408
  end
@@ -351,11 +459,11 @@ module Fastlane
351
459
  #####################################################
352
460
 
353
461
  def self.description
354
- "Create images combining app screenshots to templates to make a nice \'screenshot\' to upload in App Store"
462
+ "Create images combining app screenshots to templates to make a nice \'screenshot\' to upload in App Store and Google Play"
355
463
  end
356
464
 
357
465
  def self.authors
358
- ["DrAL3X"]
466
+ ["DrAL3X", "AzureRodrigo"]
359
467
  end
360
468
 
361
469
  def self.available_options
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Framer
3
- VERSION = "1.0.3"
3
+ VERSION = "1.0.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-framer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - DrAL3X
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-11 00:00:00.000000000 Z
11
+ date: 2021-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_magick
@@ -122,7 +122,7 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: 1.100.0
125
- description:
125
+ description:
126
126
  email: alessandro.calzavara@gmail.com
127
127
  executables: []
128
128
  extensions: []
@@ -139,7 +139,7 @@ homepage: https://github.com/spreaker/fastlane-framer-plugin
139
139
  licenses:
140
140
  - MIT
141
141
  metadata: {}
142
- post_install_message:
142
+ post_install_message:
143
143
  rdoc_options: []
144
144
  require_paths:
145
145
  - lib
@@ -154,9 +154,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  - !ruby/object:Gem::Version
155
155
  version: '0'
156
156
  requirements: []
157
- rubyforge_project:
158
- rubygems_version: 2.5.2.3
159
- signing_key:
157
+ rubygems_version: 3.1.2
158
+ signing_key:
160
159
  specification_version: 4
161
160
  summary: Create images combining app screenshots with templates to make nice pictures
162
161
  for the App Store