croppable 0.1.0 → 0.2.0

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
  SHA256:
3
- metadata.gz: bc06a6b34a2f7a532d24d39e64720bac364ccf40d176a2c47d64e0a93814c779
4
- data.tar.gz: 6045bfc5c350d93eae70dd4692194327e38f47b3d8008ee87610c21a5160a2fd
3
+ metadata.gz: 4d7748fdc65361664f5e6b39b0c8bb68a64453f7bb47a43a3957cd3984e60115
4
+ data.tar.gz: 2f2c3b3cce9896172e1f2117ae25e3e4d537230c2fc38a1dc742cbaf04d37157
5
5
  SHA512:
6
- metadata.gz: 4b9055c91ee55c59e79f1f2c46abee67d3b99dda35fbb90cb4d5abf24f7df39587ecb4e7d07bc08554831db71ab631a3e645629a181299eb760ad4bf406d1b65
7
- data.tar.gz: 1904b7435d75b0c19ed2db1c1887d722e07e2991374a53e051403c417738c3310518254cfb13a60cc13cc3ad40253c23a7417bf7262fb68d2266c99821f9d002
6
+ metadata.gz: 2c43837b3fa737eaa8006a8e57f8fb78467bf5a54ffeb0877f501066a892a66eb7ca3ff4a8b19398215ced4ca15c4fda45e71ae59317f54a7b1c74e492d34757
7
+ data.tar.gz: b5edca4cffaef90aed0ba2c8233c17b737a1a06353b3ceac2fbc1a1ee13052764d0080126662b52a387e5cdc2ac56294d734edf1900115ac0815375aef74f7c0
data/README.md CHANGED
@@ -54,9 +54,13 @@ brew install vips
54
54
  ## Usage
55
55
  Add has_croppable into your model
56
56
  ```ruby
57
- has_croppable :logo, width: 300, height: 300
57
+ has_croppable :logo, width: 300, height: 300, scale: 2
58
58
  ```
59
59
 
60
+ `width` and `height` are in pixels and required.
61
+
62
+ `scale: 2` will generate an image twice as big. Useful for retina display monitors. It defaults to 1.
63
+
60
64
  Add croppable_field to your form
61
65
  ```ruby
62
66
  form.croppable_field :logo
@@ -1,20 +1,11 @@
1
1
  import Cropper from 'cropperjs';
2
2
 
3
- function isTurbolinksEnabled() {
4
- try {
5
- return Turbolinks.supported;
6
- } catch(_) {
7
- return false;
8
- }
9
- }
10
-
11
- if(isTurbolinksEnabled()) {
12
- document.addEventListener('turbo:load', start)
13
- } else {
14
- document.addEventListener('DOMContentLoaded', start)
15
- }
3
+ document.addEventListener('turbo:load', start);
4
+ document.addEventListener('DOMContentLoaded', start);
16
5
 
17
6
  function start() {
7
+ document.removeEventListener('DOMContentLoaded', start)
8
+
18
9
  const dropAreas = document.getElementsByClassName('croppable-droparea');
19
10
 
20
11
  Array.from(dropAreas).forEach((dropArea) => {
@@ -50,7 +41,7 @@ function start() {
50
41
  input.files = event.dataTransfer.files;
51
42
 
52
43
  const image = document.createElement('img');
53
- image.src = URL.createObjectURL(file);
44
+ image.src = URL.createObjectURL(file);
54
45
 
55
46
  updateImageDisplay(image, wrapper, true, input)
56
47
  }
@@ -85,7 +76,9 @@ function updateImageDisplay(image, wrapper, isNewImage, input) {
85
76
 
86
77
  dropArea.classList.add("inactive");
87
78
  container.classList.add("active");
88
- deleteInput.checked = false;
79
+
80
+ deleteInput.checked = false;
81
+ controls.style.display = "flex";
89
82
 
90
83
  cleanContainer()
91
84
 
@@ -94,20 +87,13 @@ function updateImageDisplay(image, wrapper, isNewImage, input) {
94
87
  const cropperImage = cropper.getCropperImage();
95
88
  const cropperCanvas = cropper.getCropperCanvas();
96
89
 
97
- controls.style.display = "flex";
90
+ cropperCanvas.style.backgroundColor = bgColorBtn.value;
98
91
 
99
92
  var saveTransform = false;
100
93
 
101
94
  cropperImage.$ready(() => {
102
95
  if (xInput.value != "" && !isNewImage) {
103
- var waitForTranform = null;
104
-
105
- // Turbolinks hack to actually apply initial transformation
106
- if(isTurbolinksEnabled) {
107
- waitForTranform = 10;
108
- } else {
109
- waitForTranform = 0;
110
- }
96
+ var waitForTranform = 10; // needed due turbolinks 🤦
111
97
 
112
98
  setTimeout(() => {
113
99
  cropperImage.$setTransform(+scaleInput.value, 0, 0, +scaleInput.value, +xInput.value, +yInput.value);
@@ -116,6 +102,7 @@ function updateImageDisplay(image, wrapper, isNewImage, input) {
116
102
  }, waitForTranform)
117
103
  } else {
118
104
  const matrix = cropperImage.$getTransform();
105
+
119
106
  xInput.value = matrix[4];
120
107
  yInput.value = matrix[5];
121
108
  scaleInput.value = matrix[0];
@@ -133,8 +120,6 @@ function updateImageDisplay(image, wrapper, isNewImage, input) {
133
120
  }
134
121
  });
135
122
 
136
- cropperCanvas.style.backgroundColor = bgColorBtn.value;
137
-
138
123
  bgColorBtn.addEventListener("change", (event) => {
139
124
  event.preventDefault();
140
125
  cropperCanvas.style.backgroundColor = event.target.value;
@@ -2,45 +2,40 @@ require 'open-uri'
2
2
  require 'vips'
3
3
 
4
4
  module Croppable
5
-
6
5
  class Crop
7
6
  def initialize(model, attr_name)
8
7
  @model = model
9
8
  @attr_name = attr_name
10
9
  @data = model.send("#{attr_name}_croppable_data")
11
10
  @setup = model.send("#{attr_name}_croppable_setup")
12
- original = model.send("#{attr_name}_original")
13
- @url = Rails.application.routes.url_helpers.rails_blob_url(original, host: Rails.application.config.asset_host)
14
11
  end
15
12
 
16
13
  def perform()
17
- file = URI(@url).open
18
- vips_img = Vips::Image.new_from_file(file.path)
14
+ @model.send("#{@attr_name}_original").open do |file|
15
+ vips_img = Vips::Image.new_from_file(file.path)
16
+
17
+ height = vips_img.height
18
+ width = vips_img.width
19
19
 
20
- height = vips_img.height
21
- width = vips_img.width
20
+ x = ((width - (width * @data.scale)) / 2 + @data.x) * @setup[:scale]
21
+ y = ((height - (height * @data.scale)) / 2 + @data.y) * @setup[:scale]
22
22
 
23
- x = (width - (width * @data.scale)) / 2 + @data.x
24
- y = (height - (height * @data.scale)) / 2 + @data.y
23
+ background = @data.background_color.remove("#").scan(/\w{2}/).map {|color| color.to_i(16) }
24
+ background_embed = background.dup
25
+ background_embed << 255 if vips_img.bands == 4
25
26
 
26
- background = @data.background_color.remove("#").scan(/\w{2}/).map {|color| color.to_i(16) }
27
- background_embed = background.dup
28
- background_embed << 255 if vips_img.bands == 4
27
+ new_width = @setup[:width] * @setup[:scale]
28
+ new_height = @setup[:height] * @setup[:scale]
29
29
 
30
- vips_img = vips_img.resize(@data.scale * @setup[:resolution])
31
- vips_img = vips_img.embed(
32
- x * @setup[:resolution],
33
- y * @setup[:resolution],
34
- @setup[:width] * @setup[:resolution],
35
- @setup[:height] * @setup[:resolution],
36
- background: background_embed
37
- )
30
+ vips_img = vips_img.resize(@data.scale * @setup[:scale])
31
+ vips_img = vips_img.embed(x, y, new_width, new_height, background: background_embed)
38
32
 
39
- path = Tempfile.new('cropped').path + ".jpg"
33
+ path = Tempfile.new('cropped').path + ".jpg"
40
34
 
41
- vips_img.write_to_file(path, background: background, Q: 100)
35
+ vips_img.write_to_file(path, background: background, Q: 100)
42
36
 
43
- @model.send("#{ @attr_name }_cropped").attach(io: File.open(path), filename: "cropped")
37
+ @model.send("#{ @attr_name }_cropped").attach(io: File.open(path), filename: "cropped")
38
+ end
44
39
  end
45
40
  end
46
41
  end
@@ -2,12 +2,8 @@ module Croppable
2
2
  module Model
3
3
  extend ActiveSupport::Concern
4
4
 
5
- # High-resolution displays, which are a large part of the market, need twice
6
- # the pixels to look professional.
7
- DEFAULT_RESOLUTION = 2
8
-
9
5
  class_methods do
10
- def has_croppable(name, width:, height:, resolution: DEFAULT_RESOLUTION)
6
+ def has_croppable(name, width:, height:, scale: 1)
11
7
  has_one_attached :"#{ name }_cropped"
12
8
  has_one_attached :"#{ name }_original"
13
9
 
@@ -20,7 +16,7 @@ module Croppable
20
16
 
21
17
  generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
22
18
  def #{ name }_croppable_setup
23
- {width: #{ width }, height: #{ height }, resolution: #{ resolution }}
19
+ {width: #{ width }, height: #{ height }, scale: #{ scale }}
24
20
  end
25
21
 
26
22
  def to_crop_croppable
@@ -1,3 +1,3 @@
1
1
  module Croppable
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: croppable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Barragán Naranjo
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: '1.2'
41
41
  description:
42
42
  email:
43
- - me@steven.mx
43
+ - stvnbarragan@gmail.com
44
44
  executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
@@ -74,11 +74,11 @@ files:
74
74
  - lib/croppable/version.rb
75
75
  - lib/generators/croppable/install/install_generator.rb
76
76
  - lib/tasks/croppable_tasks.rake
77
- homepage: https://github.com/stevenbarragan/croppable
77
+ homepage: https://rubygems.org/gems/croppable
78
78
  licenses:
79
79
  - MIT
80
80
  metadata:
81
- homepage_uri: https://github.com/stevenbarragan/croppable
81
+ homepage_uri: https://rubygems.org/gems/croppable
82
82
  source_code_uri: https://github.com/stevenbarragan/croppable
83
83
  post_install_message:
84
84
  rdoc_options: []