compass-inline-gradient 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []