compass-canvas 0.0.4 → 0.0.5
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.
- data/README.md +6 -0
- data/lib/canvas.rb +14 -1
- data/lib/canvas/actions.rb +35 -34
- data/lib/canvas/backend.rb +37 -11
- data/lib/canvas/backend/cairo.rb +42 -6
- data/lib/canvas/backend/interface/path.rb +5 -0
- data/lib/canvas/functions/canvas.rb +28 -0
- data/plugins/{drop-shadow.rb → drop_shadow.rb} +0 -0
- data/stylesheets/_canvas.scss +24 -0
- data/stylesheets/canvas/_path.scss +1 -0
- data/stylesheets/canvas/path/_curves.scss +7 -0
- metadata +6 -5
data/README.md
CHANGED
@@ -73,6 +73,12 @@ For a complete reference on Cairo methods, visit [Pycairo documentation][pycairo
|
|
73
73
|
[cairo-tutorial]: http://zetcode.com/tutorials/cairographicstutorial/
|
74
74
|
[pycairo]: http://cairographics.org/documentation/pycairo/3/reference/context.html#class-context
|
75
75
|
|
76
|
+
Similar Projects
|
77
|
+
----------------
|
78
|
+
|
79
|
+
[compass-magick](https://github.com/StanAngeloff/compass-magick) is a pure Ruby dynamic image generation for Compass using ChunkyPNG/PhantomJS (no dependency on RMagick despite the name).
|
80
|
+
If you are looking for a project to generate image gradients or small & simple buttons, go check it out.
|
81
|
+
|
76
82
|
### Copyright
|
77
83
|
|
78
84
|
> Copyright (c) 2011 Stan Angeloff. See [LICENSE.md](https://github.com/StanAngeloff/compass-canvas/blob/master/LICENSE.md) for details.
|
data/lib/canvas.rb
CHANGED
@@ -7,7 +7,7 @@ module Compass::Canvas
|
|
7
7
|
# The project and Gem version. When building a Gem file for release, the
|
8
8
|
# version is stripped to X.Y.Z. If you are using a Git cloned-repository,
|
9
9
|
# the version will end in +.git+.
|
10
|
-
VERSION = '0.0.
|
10
|
+
VERSION = '0.0.5.git'
|
11
11
|
|
12
12
|
# The default backend for drawing.
|
13
13
|
BACKEND = 'cairo'
|
@@ -20,6 +20,19 @@ module Compass::Canvas
|
|
20
20
|
File.expand_path(File.join(File.dirname(__FILE__), '..', directory))
|
21
21
|
end
|
22
22
|
|
23
|
+
# Helper function to normalize a CSS path to a filesystem path.
|
24
|
+
#
|
25
|
+
# @param [String] file A CSS file, usually with url(..) and optionally a cache buster.
|
26
|
+
# @return [String] The absolute filesystem path.
|
27
|
+
def self.absolute_path_to(file)
|
28
|
+
if file.include?('url(')
|
29
|
+
file = File.join(Compass.configuration.css_path, file.gsub(/^url\(['"]?|["']?\)$/, ''))
|
30
|
+
else
|
31
|
+
file = File.join(Compass.configuration.images_path, file)
|
32
|
+
end
|
33
|
+
file.split('?').shift()
|
34
|
+
end
|
35
|
+
|
23
36
|
# Locations where plug-ins are installed. These paths are scanned for *.rb files
|
24
37
|
# and loaded in order.
|
25
38
|
PLUGINS_PATH = [
|
data/lib/canvas/actions.rb
CHANGED
@@ -1,39 +1,40 @@
|
|
1
1
|
module Compass::Canvas
|
2
2
|
# This module contains all actions a backend must implement.
|
3
3
|
module Actions
|
4
|
-
ANTIALIAS
|
5
|
-
ARC
|
6
|
-
ARC_REVERSE
|
7
|
-
BRUSH
|
8
|
-
CLIP
|
9
|
-
CLOSE
|
10
|
-
CURVE
|
11
|
-
DASH_PATTERN
|
12
|
-
FILL
|
13
|
-
FILL_RULE
|
14
|
-
GROUP
|
15
|
-
LINE
|
16
|
-
LINE_CAP
|
17
|
-
LINE_JOIN
|
18
|
-
LINE_WIDTH
|
19
|
-
MASK
|
20
|
-
MITER_LIMIT
|
21
|
-
MOVE
|
22
|
-
PAINT
|
23
|
-
POP
|
24
|
-
PUSH
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
4
|
+
ANTIALIAS = :antialias
|
5
|
+
ARC = :arc
|
6
|
+
ARC_REVERSE = :arc_reverse
|
7
|
+
BRUSH = :brush
|
8
|
+
CLIP = :clip
|
9
|
+
CLOSE = :close
|
10
|
+
CURVE = :curve
|
11
|
+
DASH_PATTERN = :dash_pattern
|
12
|
+
FILL = :fill
|
13
|
+
FILL_RULE = :fill_rule
|
14
|
+
GROUP = :group
|
15
|
+
LINE = :line
|
16
|
+
LINE_CAP = :line_cap
|
17
|
+
LINE_JOIN = :line_join
|
18
|
+
LINE_WIDTH = :line_width
|
19
|
+
MASK = :mask
|
20
|
+
MITER_LIMIT = :miter_limit
|
21
|
+
MOVE = :move
|
22
|
+
PAINT = :paint
|
23
|
+
POP = :pop
|
24
|
+
PUSH = :push
|
25
|
+
QUADRATIC_CURVE = :quadratic_curve
|
26
|
+
RESET = :reset
|
27
|
+
RESTORE = :restore
|
28
|
+
RETRIEVE = :retrieve
|
29
|
+
ROTATE = :rotate
|
30
|
+
SAVE = :save
|
31
|
+
SCALE = :scale
|
32
|
+
SLOW_BLUR = :slow_blur
|
33
|
+
STORE = :store
|
34
|
+
STROKE = :stroke
|
35
|
+
TOLERANCE = :tolerance
|
36
|
+
TRANSFORM = :transform
|
37
|
+
TRANSLATE = :translate
|
38
|
+
UNCLIP = :unclip
|
38
39
|
end
|
39
40
|
end
|
data/lib/canvas/backend.rb
CHANGED
@@ -6,6 +6,7 @@ module Compass::Canvas::Backend
|
|
6
6
|
#
|
7
7
|
# Each implementation must respond to four methods:
|
8
8
|
# - {Compass::Canvas::Backend::Base::load_dependencies} - initializes the backend by loading third-party dependencies
|
9
|
+
# - {Compass::Canvas::Backend::Base::read_canvas} - reads a canvas from a file
|
9
10
|
# - {Compass::Canvas::Backend::Base::begin_canvas} - initialization code before the canvas is drawn
|
10
11
|
# - {Compass::Canvas::Backend::Base::execute_one} - executes a single action on the canvas
|
11
12
|
# - {Compass::Canvas::Backend::Base::to_blob} - clean up code, must return a
|
@@ -35,20 +36,15 @@ module Compass::Canvas::Backend
|
|
35
36
|
load_dependencies
|
36
37
|
if args[0].is_a?(String)
|
37
38
|
file = args.shift
|
38
|
-
unless args[
|
39
|
-
if file.include?('url(')
|
40
|
-
file = File.join(Compass.configuration.css_path, file.gsub(/^url\(['"]?|["']?\)$/, '').split('?').shift())
|
41
|
-
else
|
42
|
-
file = File.join(Compass.configuration.images_path, file.split('?').shift())
|
43
|
-
end
|
44
|
-
end
|
39
|
+
file = Compass::Canvas.absolute_path_to(file) unless args[0].is_a?(Fixnum)
|
45
40
|
@file = file
|
46
41
|
end
|
47
42
|
if args[0].is_a?(Fixnum)
|
48
43
|
@width = args.shift
|
49
44
|
@height = args.shift
|
50
45
|
end
|
51
|
-
@actions
|
46
|
+
@actions = args
|
47
|
+
@executed = false
|
52
48
|
end
|
53
49
|
|
54
50
|
# Abstract method.
|
@@ -60,6 +56,15 @@ module Compass::Canvas::Backend
|
|
60
56
|
raise Compass::Canvas::Exception.new("(#{self.class}) Class must implement '#{this_method}'.")
|
61
57
|
end
|
62
58
|
|
59
|
+
# Abstract method.
|
60
|
+
#
|
61
|
+
# Reads a canvas from a file
|
62
|
+
#
|
63
|
+
# @raise [Compass::Canvas::Exception] Backend implementation must override this method.
|
64
|
+
def read_canvas
|
65
|
+
raise Compass::Canvas::Exception.new("(#{self.class}) Class must implement '#{this_method}'.")
|
66
|
+
end
|
67
|
+
|
63
68
|
# Abstract method.
|
64
69
|
#
|
65
70
|
# Initialization code before the canvas is drawn.
|
@@ -87,10 +92,32 @@ module Compass::Canvas::Backend
|
|
87
92
|
raise Compass::Canvas::Exception.new("(#{self.class}) Class must implement '#{this_method}'.")
|
88
93
|
end
|
89
94
|
|
95
|
+
# Reads a property of the backend.
|
96
|
+
#
|
97
|
+
# This can be used to provide custom information about a backend, such as
|
98
|
+
# width, height, the current point's position, etc.
|
99
|
+
#
|
100
|
+
# @param [String] name The property name.
|
101
|
+
# @return [Object] The property value, or nil if it doesn't exist.
|
102
|
+
def property(name)
|
103
|
+
case name
|
104
|
+
when :width; return @width
|
105
|
+
when :height; return @height
|
106
|
+
else return nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
90
110
|
# Creates an empty canvas and executes all stored actions.
|
91
111
|
def execute
|
92
|
-
|
93
|
-
|
112
|
+
return self if @executed
|
113
|
+
if @width && @height
|
114
|
+
begin_canvas
|
115
|
+
execute_actions
|
116
|
+
else
|
117
|
+
read_canvas
|
118
|
+
end
|
119
|
+
@executed = true
|
120
|
+
self
|
94
121
|
end
|
95
122
|
|
96
123
|
# Returns the canvas as a Base64 encoded Data URI or as a file on disk
|
@@ -130,7 +157,6 @@ module Compass::Canvas::Backend
|
|
130
157
|
end
|
131
158
|
execute_one(action, *args)
|
132
159
|
end
|
133
|
-
self
|
134
160
|
end
|
135
161
|
|
136
162
|
private
|
data/lib/canvas/backend/cairo.rb
CHANGED
@@ -25,6 +25,30 @@ module Compass::Canvas::Backend
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
# Reads a property of the Cairo backend.
|
29
|
+
#
|
30
|
+
# This can be used to obtain information about the width/height of the
|
31
|
+
# surface as well as the current point's X/Y coordinates.
|
32
|
+
#
|
33
|
+
# @param [String] name The property name.
|
34
|
+
# @return [Object] The property value, or nil if it doesn't exist.
|
35
|
+
def property(name)
|
36
|
+
execute
|
37
|
+
case name
|
38
|
+
when :width; return @surface.width
|
39
|
+
when :height; return @surface.height
|
40
|
+
when :x; return @context.current_point[0]
|
41
|
+
when :y; return @context.current_point[1]
|
42
|
+
else return nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Creates a new +ImageSurface+ from a file
|
47
|
+
def read_canvas
|
48
|
+
@surface = ::Cairo::ImageSurface.from_png(@file)
|
49
|
+
bind_context
|
50
|
+
end
|
51
|
+
|
28
52
|
# Creates a new +ImageSurface+ and binds a new context to it.
|
29
53
|
def begin_canvas
|
30
54
|
if @width && @height
|
@@ -32,9 +56,7 @@ module Compass::Canvas::Backend
|
|
32
56
|
else
|
33
57
|
@surface = ::Cairo::ImageSurface.from_png(@file)
|
34
58
|
end
|
35
|
-
|
36
|
-
@context.set_line_width(1)
|
37
|
-
@sources = []
|
59
|
+
bind_context
|
38
60
|
end
|
39
61
|
|
40
62
|
# Executes a single action on the context bound to the surface.
|
@@ -46,6 +68,14 @@ module Compass::Canvas::Backend
|
|
46
68
|
@context.line_to(*args)
|
47
69
|
when Compass::Canvas::Actions::CURVE
|
48
70
|
@context.curve_to(*args)
|
71
|
+
when Compass::Canvas::Actions::QUADRATIC_CURVE
|
72
|
+
x1, y1, x2, y2 = args
|
73
|
+
x, y = @context.current_point
|
74
|
+
@context.curve_to(
|
75
|
+
x + 2.0 / 3.0 * (x1 - x), y + 2.0 / 3.0 * (y1 - y),
|
76
|
+
x2 + 2.0 / 3.0 * (x1 - x2), y2 + 2.0 / 3.0 * (y1 - y2),
|
77
|
+
x2, y2
|
78
|
+
)
|
49
79
|
when Compass::Canvas::Actions::ARC
|
50
80
|
@context.arc(*args)
|
51
81
|
when Compass::Canvas::Actions::ARC_REVERSE
|
@@ -117,8 +147,8 @@ module Compass::Canvas::Backend
|
|
117
147
|
pattern.set_extend(constant('EXTEND', args))
|
118
148
|
@context.mask(pattern)
|
119
149
|
else
|
120
|
-
x = args.shift if args.length
|
121
|
-
y = args.shift if args.length
|
150
|
+
x = args.shift if args.length > 0
|
151
|
+
y = args.shift if args.length > 0
|
122
152
|
@context.mask(surface, x || 0, y || 0)
|
123
153
|
end
|
124
154
|
elsif type == Compass::Canvas::Actions::RETRIEVE
|
@@ -142,7 +172,7 @@ module Compass::Canvas::Backend
|
|
142
172
|
canvas = args.shift
|
143
173
|
if canvas.is_a?(Compass::Canvas::Backend::Cairo)
|
144
174
|
pattern = ::Cairo::SurfacePattern.new(canvas.execute.surface)
|
145
|
-
pattern.set_extend(constant('EXTEND', args)) if args.length
|
175
|
+
pattern.set_extend(constant('EXTEND', args)) if args.length > 0
|
146
176
|
@context.set_source(pattern)
|
147
177
|
else
|
148
178
|
raise Compass::Canvas::Exception.new("(#{self.class}.#{action}) Unsupported canvas, Cairo can only paint with Cairo: #{canvas.inspect}")
|
@@ -169,6 +199,12 @@ module Compass::Canvas::Backend
|
|
169
199
|
|
170
200
|
private
|
171
201
|
|
202
|
+
def bind_context
|
203
|
+
@context = ::Cairo::Context.new(@surface)
|
204
|
+
@context.set_line_width(1)
|
205
|
+
@sources = []
|
206
|
+
end
|
207
|
+
|
172
208
|
def constant(name, *args)
|
173
209
|
::Cairo::const_get("#{ name.upcase }_#{ args.join('_').gsub('-', '_').upcase }")
|
174
210
|
end
|
@@ -16,6 +16,11 @@ module Compass::Canvas::Backend::Interface
|
|
16
16
|
[x1.value, y1.value, x2.value, y2.value, x3.value, y3.value]
|
17
17
|
end
|
18
18
|
|
19
|
+
# Unpacks arguments +X+[1..2] and +Y+[1..2] from Sass to Ruby objects.
|
20
|
+
def quadratic_curve(x1, y1, x2, y2)
|
21
|
+
[x1.value, y1.value, x2.value, y2.value]
|
22
|
+
end
|
23
|
+
|
19
24
|
# Unpacks arguments +X+, +Y+, +radius+ and +angle+[1..2] from Sass to Ruby objects.
|
20
25
|
def arc(x, y, radius, angle1, angle2)
|
21
26
|
[x.value, y.value, radius.value, angle1.value * (Math::PI / 180.0), angle2.value * (Math::PI / 180.0)]
|
@@ -16,6 +16,34 @@ module Compass::Canvas
|
|
16
16
|
end
|
17
17
|
klass.new(*Compass::Canvas::Functions.unpack(args).flatten)
|
18
18
|
end
|
19
|
+
|
20
|
+
# Gets the width of a {Compass::Canvas::Backend}.
|
21
|
+
#
|
22
|
+
# @return [Compass::Canvas::Backend] The width of the backend.
|
23
|
+
def width_of(canvas)
|
24
|
+
Sass::Script::Number.new(canvas.property(:width))
|
25
|
+
end
|
26
|
+
|
27
|
+
# Gets the height of a {Compass::Canvas::Backend}.
|
28
|
+
#
|
29
|
+
# @return [Compass::Canvas::Backend] The height of the backend.
|
30
|
+
def height_of(canvas)
|
31
|
+
Sass::Script::Number.new(canvas.property(:height))
|
32
|
+
end
|
33
|
+
|
34
|
+
# Gets the X position of the current path on a {Compass::Canvas::Backend}.
|
35
|
+
#
|
36
|
+
# @return [Compass::Canvas::Backend] The X position of the current backend path.
|
37
|
+
def path_x(canvas)
|
38
|
+
Sass::Script::Number.new(canvas.property(:x))
|
39
|
+
end
|
40
|
+
|
41
|
+
# Gets the Y position of the current path on a {Compass::Canvas::Backend}.
|
42
|
+
#
|
43
|
+
# @return [Compass::Canvas::Backend] The Y position of the current backend path.
|
44
|
+
def path_y(canvas)
|
45
|
+
Sass::Script::Number.new(canvas.property(:y))
|
46
|
+
end
|
19
47
|
end
|
20
48
|
end
|
21
49
|
end
|
File without changes
|
data/stylesheets/_canvas.scss
CHANGED
@@ -1,3 +1,27 @@
|
|
1
1
|
@import 'canvas/context';
|
2
2
|
@import 'canvas/path';
|
3
3
|
@import 'canvas/pattern';
|
4
|
+
|
5
|
+
// @function width-of(canvas) {}
|
6
|
+
// @function height-of(canvas) {}
|
7
|
+
// @function path-x(canvas) {}
|
8
|
+
// @function path-y(canvas) {}
|
9
|
+
|
10
|
+
@function put-image($file, $x: 0, $y: 0) {
|
11
|
+
$canvas: canvas($file);
|
12
|
+
@if ($x == 'repeat') {
|
13
|
+
@return (
|
14
|
+
brush($canvas, $x)
|
15
|
+
paint
|
16
|
+
);
|
17
|
+
} @else {
|
18
|
+
@return (
|
19
|
+
save
|
20
|
+
translate($x, $y)
|
21
|
+
brush($canvas)
|
22
|
+
rectangle(0, 0, width-of($canvas), height-of($canvas))
|
23
|
+
fill
|
24
|
+
restore
|
25
|
+
);
|
26
|
+
}
|
27
|
+
}
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: compass-canvas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Stan Angeloff
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-29 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: compass
|
@@ -79,9 +79,10 @@ files:
|
|
79
79
|
- stylesheets/canvas/_pattern.scss
|
80
80
|
- stylesheets/canvas/_path.scss
|
81
81
|
- stylesheets/canvas/_context.scss
|
82
|
+
- stylesheets/canvas/path/_curves.scss
|
82
83
|
- stylesheets/canvas/path/_primitives.scss
|
83
84
|
- stylesheets/canvas/path/_shapes.scss
|
84
|
-
- plugins/
|
85
|
+
- plugins/drop_shadow.rb
|
85
86
|
homepage: http://StanAngeloff.github.com/compass-canvas/
|
86
87
|
licenses: []
|
87
88
|
|