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 +4 -4
- data/README.md +5 -1
- data/app/assets/javascripts/croppable.js +11 -26
- data/lib/croppable/crop.rb +18 -23
- data/lib/croppable/model.rb +2 -6
- data/lib/croppable/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d7748fdc65361664f5e6b39b0c8bb68a64453f7bb47a43a3957cd3984e60115
|
4
|
+
data.tar.gz: 2f2c3b3cce9896172e1f2117ae25e3e4d537230c2fc38a1dc742cbaf04d37157
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
4
|
-
|
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
|
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
|
-
|
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
|
-
|
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 =
|
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;
|
data/lib/croppable/crop.rb
CHANGED
@@ -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
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
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
|
-
|
24
|
-
|
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
|
-
|
27
|
-
|
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
|
-
|
31
|
-
|
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
|
-
|
33
|
+
path = Tempfile.new('cropped').path + ".jpg"
|
40
34
|
|
41
|
-
|
35
|
+
vips_img.write_to_file(path, background: background, Q: 100)
|
42
36
|
|
43
|
-
|
37
|
+
@model.send("#{ @attr_name }_cropped").attach(io: File.open(path), filename: "cropped")
|
38
|
+
end
|
44
39
|
end
|
45
40
|
end
|
46
41
|
end
|
data/lib/croppable/model.rb
CHANGED
@@ -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:,
|
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 },
|
19
|
+
{width: #{ width }, height: #{ height }, scale: #{ scale }}
|
24
20
|
end
|
25
21
|
|
26
22
|
def to_crop_croppable
|
data/lib/croppable/version.rb
CHANGED
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.
|
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
|
-
-
|
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://
|
77
|
+
homepage: https://rubygems.org/gems/croppable
|
78
78
|
licenses:
|
79
79
|
- MIT
|
80
80
|
metadata:
|
81
|
-
homepage_uri: https://
|
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: []
|