Class: Ruby2D::Canvas

Inherits:
Object
  • Object
show all
Includes:
Renderable
Defined in:
lib/ruby2d/canvas.rb

Overview

Canvas provides a surface into which you can draw using primitives and render the contents as if it were an image/texture.

Examples:

A basic Canvas positioned at (0, 0)

Canvas.new width: 320, height: 240

A Canvas that doesn’t update texture on every draw method

Canvas.new width: 320, height: 240, update: false

Instance Attribute Summary

Attributes included from Renderable

#color, #height, #width, #x, #y, #z

Instance Method Summary collapse

Methods included from Renderable

#add, #contains?, #remove

Constructor Details

#initialize(width:, height:, x: 0, y: 0, z: 0, rotate: 0, fill: [0, 0, 0, 0], color: nil, colour: nil, opacity: nil, update: true, show: true) ⇒ Canvas

Create a Canvas.

Parameters:

  • width (Numeric)

    The width of the canvas in pixels

  • height (Numeric)

    The height of the canvas in pixels

  • x (Numeric) (defaults to: 0)
  • y (Numeric) (defaults to: 0)
  • z (Numeric) (defaults to: 0)
  • rotate (Numeric) (defaults to: 0)

    Angle, default is 0

  • fill (String) (defaults to: [0, 0, 0, 0])

    Colour to clear the canvas, respects transparency

  • color (String) (defaults to: nil)

    or colour Tint the texture when rendering

  • opacity (Numeric) (defaults to: nil)

    Opacity of the texture when rendering

  • update (true, false) (defaults to: true)

    If true updates the texture for every draw/fill call

  • show (true, false) (defaults to: true)

    If true the canvas is added to Window automatically.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ruby2d/canvas.rb', line 31

def initialize(width:, height:, x: 0, y: 0, z: 0, rotate: 0,
               fill: [0, 0, 0, 0], color: nil, colour: nil, opacity: nil,
               update: true, show: true)
  @x = x
  @y = y
  @z = z
  @width = width
  @height = height
  @rotate = rotate
  @fill = Color.new(fill)
  self.color = color || colour || 'white'
  color.opacity = opacity if opacity
  @update = update

  ext_create([@width, @height, @fill.r, @fill.g, @fill.b, @fill.a]) # sets @ext_pixel_data
  @texture = Texture.new(@ext_pixel_data, @width, @height)
  add if show
end

Instance Method Details

#clear(fill_color = @fill) ⇒ Object

Clear the entire canvas, replacing every pixel with fill colour without blending.

Parameters:

  • fill_color (Color) (defaults to: @fill)


52
53
54
55
56
# File 'lib/ruby2d/canvas.rb', line 52

def clear(fill_color = @fill)
  color = fill_color || @fill
  ext_clear([color.r, color.g, color.b, color.a])
  update_texture if @update
end

#draw_circle(x:, y:, radius:, sectors: 30, stroke_width: 1, color: nil, colour: nil) ⇒ Object

Draw a circle.

Parameters:

  • x (Numeric)

    Centre

  • y (Numeric)

    Centre

  • radius (Numeric)
  • sectors (Numeric) (defaults to: 30)

    The number of segments to subdivide the circumference.

  • stroke_width (Numeric) (defaults to: 1)

    The thickness of the circle in pixels

  • color (Color) (defaults to: nil)

    (or colour) The fill colour



91
92
93
94
95
96
97
98
99
# File 'lib/ruby2d/canvas.rb', line 91

def draw_circle(x:, y:, radius:, sectors: 30, stroke_width: 1, color: nil, colour: nil)
  clr = color || colour
  clr = Color.new(clr) unless clr.is_a? Color
  ext_draw_ellipse([
                     x, y, radius, radius, sectors, stroke_width,
                     clr.r, clr.g, clr.b, clr.a
                   ])
  update_texture if @update
end

#draw_ellipse(x:, y:, xradius:, yradius:, sectors: 30, stroke_width: 1, color: nil, colour: nil) ⇒ Object

Draw an ellipse

Parameters:

  • x (Numeric)

    Centre

  • y (Numeric)

    Centre

  • xradius (Numeric)
  • yradius (Numeric)
  • sectors (Numeric) (defaults to: 30)

    The number of segments to subdivide the circumference.

  • stroke_width (Numeric) (defaults to: 1)

    The thickness of the circle in pixels

  • color (Color) (defaults to: nil)

    (or colour) The fill colour



109
110
111
112
113
114
115
116
117
# File 'lib/ruby2d/canvas.rb', line 109

def draw_ellipse(x:, y:, xradius:, yradius:, sectors: 30, stroke_width: 1, color: nil, colour: nil)
  clr = color || colour
  clr = Color.new(clr) unless clr.is_a? Color
  ext_draw_ellipse([
                     x, y, xradius, yradius, sectors, stroke_width,
                     clr.r, clr.g, clr.b, clr.a
                   ])
  update_texture if @update
end

#draw_line(x1:, y1:, x2:, y2:, stroke_width: 1, color: nil, colour: nil) ⇒ Object

Draw a straight line between two points

Parameters:

  • x1 (Numeric)
  • y1 (Numeric)
  • x2 (Numeric)
  • y2 (Numeric)
  • stroke_width (Numeric) (defaults to: 1)

    The line’s thickness in pixels; defaults to 1.

  • color (Color) (defaults to: nil)

    (or colour) The line colour



224
225
226
227
228
229
230
231
232
# File 'lib/ruby2d/canvas.rb', line 224

def draw_line(x1:, y1:, x2:, y2:, stroke_width: 1, color: nil, colour: nil)
  clr = color || colour
  clr = Color.new(clr) unless clr.is_a? Color
  ext_draw_line([
                  x1, y1, x2, y2, stroke_width,
                  clr.r, clr.g, clr.b, clr.a
                ])
  update_texture if @update
end

#draw_pixmap(pixmap, x:, y:, width: nil, height: nil, crop: nil) ⇒ Object

Note:

This API will evolve to be able to draw a portion of the pixmap; coming soon.

Draw the pixmap at the specified location and size

Parameters:

  • pixmap (Pixmap)
  • x (Numeric)
  • y (Numeric)
  • width (Numeric) (defaults to: nil)

    Optional, specify to scale the size

  • height (Numeric) (defaults to: nil)

    Optional, specify to scale the size

  • crop (Hash) (defaults to: nil)

    Optional, specify a hash with ‘x:, y:, width:, height:` to crop from within the pixmap to draw.



275
276
277
278
# File 'lib/ruby2d/canvas.rb', line 275

def draw_pixmap(pixmap, x:, y:, width: nil, height: nil, crop: nil)
  src_rect = crop ? [crop[:x], crop[:y], crop[:width], crop[:height]] : nil
  ext_draw_pixmap pixmap, src_rect, x, y, width, height
end

#draw_polyline(coordinates:, stroke_width: 1, color: nil, colour: nil, closed: false) ⇒ Object

Draw a poly-line between N points.

Parameters:

  • coordinates (Array)

    An array of numbers x1, y1, x2, y2 … with at least three coordinates (6 values)

  • stroke_width (Numeric) (defaults to: 1)

    The line’s thickness in pixels; defaults to 1.

  • color (Color) (defaults to: nil)

    (or colour) The line colour

  • closed (Boolean) (defaults to: false)

    Use true to draw this as a closed shape



239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/ruby2d/canvas.rb', line 239

def draw_polyline(coordinates:, stroke_width: 1, color: nil, colour: nil, closed: false)
  return if coordinates.nil? || coordinates.count < 6

  clr = color || colour
  clr = Color.new(clr) unless clr.is_a? Color
  config = [stroke_width, clr.r, clr.g, clr.b, clr.a]
  if closed
    ext_draw_polygon(config, coordinates)
  else
    ext_draw_polyline(config, coordinates)
  end
  update_texture if @update
end

#draw_quad(x1:, y1:, x2:, y2:, x3:, y3:, x4:, y4:, stroke_width: 1, color: nil, colour: nil) ⇒ Object

Draw an outline of a quad.

Parameters:

  • x1 (Numeric)
  • y1 (Numeric)
  • x2 (Numeric)
  • y2 (Numeric)
  • x3 (Numeric)
  • y3 (Numeric)
  • x4 (Numeric)
  • y4 (Numeric)
  • stroke_width (Numeric) (defaults to: 1)

    The thickness of the rectangle in pixels

  • color (Color) (defaults to: nil)

    (or colour) The line colour



194
195
196
197
198
# File 'lib/ruby2d/canvas.rb', line 194

def draw_quad(x1:, y1:, x2:, y2:, x3:, y3:, x4:, y4:, stroke_width: 1, color: nil, colour: nil)
  draw_polyline closed: true,
                coordinates: [x1, y1, x2, y2, x3, y3, x4, y4],
                color: color, colour: colour, stroke_width: stroke_width
end

#draw_rectangle(x:, y:, width:, height:, stroke_width: 1, color: nil, colour: nil) ⇒ Object

Draw an outline of a rectangle

Parameters:

  • x (Numeric)
  • y (Numeric)
  • width (Numeric)
  • height (Numeric)
  • stroke_width (Numeric) (defaults to: 1)

    The thickness of the rectangle in pixels

  • color (Color) (defaults to: nil)

    (or colour) The line colour



207
208
209
210
211
212
213
214
215
# File 'lib/ruby2d/canvas.rb', line 207

def draw_rectangle(x:, y:, width:, height:, stroke_width: 1, color: nil, colour: nil)
  clr = color || colour
  clr = Color.new(clr) unless clr.is_a? Color
  ext_draw_rectangle([
                       x, y, width, height, stroke_width,
                       clr.r, clr.g, clr.b, clr.a
                     ])
  update_texture if @update
end

#draw_triangle(x1:, y1:, x2:, y2:, x3:, y3:, stroke_width: 1, color: nil, colour: nil) ⇒ Object

Draw an outline of a triangle.

Parameters:

  • x1 (Numeric)
  • y1 (Numeric)
  • x2 (Numeric)
  • y2 (Numeric)
  • x3 (Numeric)
  • y3 (Numeric)
  • stroke_width (Numeric) (defaults to: 1)

    The thickness of the rectangle in pixels

  • color (Color) (defaults to: nil)

    (or colour) The line colour



177
178
179
180
181
# File 'lib/ruby2d/canvas.rb', line 177

def draw_triangle(x1:, y1:, x2:, y2:, x3:, y3:, stroke_width: 1, color: nil, colour: nil)
  draw_polyline closed: true,
                coordinates: [x1, y1, x2, y2, x3, y3],
                color: color, colour: colour, stroke_width: stroke_width
end

#fill_circle(x:, y:, radius:, sectors: 30, color: nil, colour: nil) ⇒ Object

Draw a filled circle.

Parameters:

  • x (Numeric)

    Centre

  • y (Numeric)

    Centre

  • radius (Numeric)
  • sectors (Numeric) (defaults to: 30)

    The number of segments to subdivide the circumference.

  • color (Color) (defaults to: nil)

    (or colour) The fill colour



125
126
127
128
129
130
131
132
133
# File 'lib/ruby2d/canvas.rb', line 125

def fill_circle(x:, y:, radius:, sectors: 30, color: nil, colour: nil)
  clr = color || colour
  clr = Color.new(clr) unless clr.is_a? Color
  ext_fill_ellipse([
                     x, y, radius, radius, sectors,
                     clr.r, clr.g, clr.b, clr.a
                   ])
  update_texture if @update
end

#fill_ellipse(x:, y:, xradius:, yradius:, sectors: 30, color: nil, colour: nil) ⇒ Object

Draw a filled ellipse.

Parameters:

  • x (Numeric)

    Centre

  • y (Numeric)

    Centre

  • xradius (Numeric)
  • yradius (Numeric)
  • sectors (Numeric) (defaults to: 30)

    The number of segments to subdivide the circumference.

  • color (Color) (defaults to: nil)

    (or colour) The fill colour



142
143
144
145
146
147
148
149
150
# File 'lib/ruby2d/canvas.rb', line 142

def fill_ellipse(x:, y:, xradius:, yradius:, sectors: 30, color: nil, colour: nil)
  clr = color || colour
  clr = Color.new(clr) unless clr.is_a? Color
  ext_fill_ellipse([
                     x, y, xradius, yradius, sectors,
                     clr.r, clr.g, clr.b, clr.a
                   ])
  update_texture if @update
end

#fill_polygon(coordinates:, color: nil, colour: nil) ⇒ Object

Note:

Currently only supports convex polygons or simple polygons with one concave corner.

Note:

Supports per-vertex coloring, but the triangulation may change and affect the coloring.

Fill a polygon made up of N points.

Parameters:

  • coordinates (Array)

    An array of numbers x1, y1, x2, y2 … with at least three coordinates (6 values)

  • color (Color, Color::Set) (defaults to: nil)

    (or colour) Set one or per-vertex colour; at least one colour must be specified.



258
259
260
261
262
263
264
# File 'lib/ruby2d/canvas.rb', line 258

def fill_polygon(coordinates:, color: nil, colour: nil)
  return if coordinates.nil? || coordinates.count < 6 || (color.nil? && colour.nil?)

  colors = colors_to_a(color || colour)
  ext_fill_polygon(coordinates, colors)
  update_texture if @update
end

#fill_quad(x1:, y1:, x2:, y2:, x3:, y3:, x4:, y4:, color: nil, colour: nil) ⇒ Object

Draw a filled quad(rilateral) with a single colour or per-vertex colour blending.

Parameters:

  • x1 (Numeric)
  • y1 (Numeric)
  • x2 (Numeric)
  • y2 (Numeric)
  • x3 (Numeric)
  • y3 (Numeric)
  • x4 (Numeric)
  • y4 (Numeric)
  • color (Color, Color::Set) (defaults to: nil)

    (or colour) Set one or per-vertex colour



80
81
82
# File 'lib/ruby2d/canvas.rb', line 80

def fill_quad(x1:, y1:, x2:, y2:, x3:, y3:, x4:, y4:, color: nil, colour: nil)
  fill_polygon coordinates: [x1, y1, x2, y2, x3, y3, x4, y4], color: color || colour
end

#fill_rectangle(x:, y:, width:, height:, color: nil, colour: nil) ⇒ Object

Draw a filled rectangle.

Parameters:

  • x (Numeric)
  • y (Numeric)
  • width (Numeric)
  • height (Numeric)
  • color (Color) (defaults to: nil)

    (or colour) The fill colour



158
159
160
161
162
163
164
165
166
# File 'lib/ruby2d/canvas.rb', line 158

def fill_rectangle(x:, y:, width:, height:, color: nil, colour: nil)
  clr = color || colour
  clr = Color.new(clr) unless clr.is_a? Color
  ext_fill_rectangle([
                       x, y, width, height,
                       clr.r, clr.g, clr.b, clr.a
                     ])
  update_texture if @update
end

#fill_triangle(x1:, y1:, x2:, y2:, x3:, y3:, color: nil, colour: nil) ⇒ Object

Draw a filled triangle with a single colour or per-vertex colour blending.

Parameters:

  • x1 (Numeric)
  • y1 (Numeric)
  • x2 (Numeric)
  • y2 (Numeric)
  • x3 (Numeric)
  • y3 (Numeric)
  • color (Color, Color::Set) (defaults to: nil)

    (or colour) Set one or per-vertex colour



66
67
68
# File 'lib/ruby2d/canvas.rb', line 66

def fill_triangle(x1:, y1:, x2:, y2:, x3:, y3:, color: nil, colour: nil)
  fill_polygon coordinates: [x1, y1, x2, y2, x3, y3], color: color || colour
end

#updateObject



280
281
282
# File 'lib/ruby2d/canvas.rb', line 280

def update
  update_texture
end