croppable 0.1.0 → 0.2.0

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
  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: []