compass-inline-gradient 0.0.1

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.
@@ -0,0 +1,193 @@
1
+ require "base64"
2
+
3
+ #safe require for compass compile in compass progect with non gem library usage
4
+ require "sass" if not defined?(Sass)
5
+
6
+ begin
7
+ require "rmagick" if not defined?(Magick)
8
+ rescue LoadError => e
9
+ #catch LoadError
10
+ end
11
+
12
+ begin
13
+ require "tinypng" if not defined?(TinyPNG)
14
+ rescue LoadError => e
15
+ #catch LoadError
16
+ end
17
+
18
+
19
+ def distance2px (distance, width)
20
+ distance = distance.to_s
21
+ if distance.end_with?("%")
22
+ percents = Sass::Script::Number.new(distance.gsub("%", "").strip)
23
+ all_persents = Sass::Script::Number.new(100)
24
+ distance = percents.div(all_persents).times(width)
25
+ else
26
+ distance = Sass::Script::Number.new(distance.to_i)
27
+ end
28
+ distance
29
+ end
30
+
31
+ def side2angle (side)
32
+ side2angle_object = {
33
+ "to_top" => 0,
34
+ "to_right" => 90,
35
+ "to_bottom" => 180,
36
+ "to_left" => 270
37
+ }
38
+ side_name = side.to_s.strip.gsub("\s", "_")
39
+ side2angle_object[side_name] or side.to_i
40
+ end
41
+
42
+ def color2hex (color)
43
+ <<-DOC
44
+ Color can be:
45
+ - rgba
46
+ - rgb
47
+ - hex
48
+ Use Sass::Script::Color class
49
+ DOC
50
+
51
+ color = color.to_s
52
+
53
+ if color.start_with?('rgba')
54
+ rgba = color.split(",").map { |s| s.to_i }
55
+ color = Sass::Script::Color.new(rgba[0..2]).with(:alpha => rgba[3])
56
+ elsif color.start_with?('rba')
57
+ rgb = color.split(",").map { |s| s.to_i }
58
+ color = Sass::Script::Color.new(rgba[0..2])
59
+ end
60
+
61
+ color
62
+ end
63
+
64
+ def image2base64(image)
65
+ image.format = "png"
66
+
67
+ begin
68
+ #online mode
69
+ client = TinyPNG::Client.new
70
+ image = client.shrink(image.to_blob)
71
+ image = File.read(image.to_file)
72
+ rescue Exception => e
73
+ #offline mode
74
+ image = image.to_blob
75
+ end
76
+
77
+ Base64.encode64(image).gsub("\n","")
78
+ end
79
+
80
+ DEFAULT_TYPE = Sass::Script::String.new "linear"
81
+ DEFAULT_ANGLE = "to bottom" #http://www.w3.org/TR/css3-images/#linear-gradient-examples to bottom is default
82
+ DEFAULT_COLOR_STOPS = ["#FFF 0%", "#000 100%"]
83
+ DEFAULT_WIDTH = Sass::Script::Number.new 100
84
+ DEFAULT_HEIGHT = Sass::Script::Number.new 100
85
+
86
+ module Sass::Script::Functions
87
+
88
+ def inline_gradient(type = DEFAULT_TYPE, width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT, angle = DEFAULT_ANGLE , *color_stops)
89
+
90
+ assert_type(type, :String)
91
+ assert_type(width, :Number)
92
+ assert_type(height, :Number)
93
+
94
+ if color_stops.size == 0
95
+ color_stops = DEFAULT_COLOR_STOPS
96
+ end
97
+
98
+ if type.to_s == "linear"
99
+ return self.inline_linear_gradient(width, height, angle, color_stops)
100
+ elsif type.to_s == "radial"
101
+ #return self.inline_radial_gradient(width, height, angle, color_stops)
102
+ end
103
+
104
+ end
105
+
106
+ def inline_linear_gradient(width, height, angle, color_stops)
107
+ <<-DOC
108
+ I use http://www.w3.org/TR/css3-images/#linear-gradient-syntax
109
+
110
+ <linear-gradient> = linear-gradient(
111
+ [ [ <angle> | to <side-or-corner> ] ,]?
112
+ <color-stop>[, <color-stop>]+
113
+ )
114
+ <side-or-corner> = [left | right] || [top | bottom]
115
+
116
+ it means that
117
+ - angle is string <angle> | to <side-or-corner>
118
+ - color_stops is string of <color-stop> string
119
+
120
+ example: inline-gradient(linear, 100, 100, to left, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%)
121
+ DOC
122
+
123
+ if color_stops.class != Array
124
+ color_stops = color_stops.split(',')
125
+ end
126
+
127
+ # The vertical gradient needs to change sides to be like horizonlat
128
+ # After creation vertical gradient just needs to be rotated
129
+ angle = side2angle(angle)
130
+ if angle % 180 == 0
131
+ width, height = height, width
132
+ end
133
+
134
+ need_rotation = angle != 90
135
+
136
+ #get info from first stop color
137
+ first_color_stop = color_stops.shift()
138
+ first_color_stop_arr = first_color_stop.to_s.strip.split(' ')
139
+ first_color = color2hex(first_color_stop_arr[0])
140
+ first_color_distance = first_color_stop_arr[1]
141
+
142
+ prev_distance = distance2px(first_color_distance, width)
143
+ prev_color = first_color
144
+
145
+ image_list = Magick::ImageList.new
146
+
147
+ color_stops.each do |color_stop|
148
+ # Making a single image for each pair of "color stop" values in color_stops.
149
+ # Images concats after this iterator.
150
+ # In this iterator there is no matter is gradient vertical or horizontal.
151
+ # Vertical gradient will just rotate after images concatination
152
+ color_stop_arr = color_stop.to_s.strip.split(' ')
153
+
154
+ current_color = color2hex(color_stop_arr[0])
155
+ current_distance = distance2px(color_stop_arr[1], width)
156
+
157
+ new_image_width = current_distance.minus(prev_distance).value.ceil
158
+
159
+ fill = Magick::GradientFill.new(0, 0, 0, new_image_width, prev_color, current_color)
160
+ image_list.new_image(new_image_width, height.to_i, fill);
161
+
162
+ prev_distance = current_distance
163
+ prev_color = current_color
164
+ end
165
+
166
+ image = image_list.append(false) #concat from left to right
167
+
168
+ if need_rotation
169
+ # Magick has a different start point, difference is -90deg
170
+ angle = angle - 90;
171
+ if angle % 90 != 0
172
+ deg2rad = angle / 180.0 * Math::PI
173
+ adding_delta_x = Math.cos( (90 - angle) / 180.0 * Math::PI ) * height.to_i
174
+ adding_delta_y = Math.tan(deg2rad) * width.to_i
175
+ adding_delta_x = adding_delta_x.abs.ceil
176
+ adding_delta_y = adding_delta_y.abs.ceil
177
+ image.scale!(width.to_i + adding_delta_x, height.to_i + adding_delta_y)
178
+ image.rotate!(angle)
179
+ image.crop!(adding_delta_x / 2, adding_delta_y / 2, width.to_i + adding_delta_x / 2, height.to_i + adding_delta_y / 2)
180
+ elsif angle != 0#TODO check
181
+ image.rotate!(angle)
182
+ end
183
+ end
184
+
185
+ data_uri_image = image2base64(image)
186
+ Sass::Script::String.new("url(data:image/png;base64," + data_uri_image + ")")
187
+ end
188
+
189
+ #def inline_radial_gradient(width, height, angle, color_stops)
190
+ #GradientFill with 0,0,0,0 is radial
191
+ #end
192
+
193
+ end
@@ -0,0 +1,3 @@
1
+ module InlineGradient
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: compass-inline-gradient
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Pinchuk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sass
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rmagick
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: tinypng
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Sass/Compass extension to convert css3 gradient to base64
84
+ email:
85
+ - front.end.developing@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.rdoc
94
+ - Rakefile
95
+ - compass-inline-gradient.gemspec
96
+ - example/config.rb
97
+ - example/example.html
98
+ - example/sass/example.scss
99
+ - example/sass/theme.scss
100
+ - example/stylesheets/example.css
101
+ - example/stylesheets/theme.css
102
+ - example/vendor/jquery.js
103
+ - example/vendor/jquery.snippet.css
104
+ - example/vendor/jquery.snippet.js
105
+ - lib/inline-gradient.rb
106
+ - lib/inline-gradient/version.rb
107
+ homepage: https://github.com/frontenddeveloping/compass-inline-gradient
108
+ licenses:
109
+ - MIT
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.0.3
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Convert css3 gradient to base64 hash
131
+ test_files: []