Class: Vizcore::Renderer::SnapshotRenderer::Canvas
- Inherits:
-
Object
- Object
- Vizcore::Renderer::SnapshotRenderer::Canvas
- Defined in:
- lib/vizcore/renderer/snapshot_renderer.rb
Overview
Tiny RGBA canvas with alpha blending and a few primitive drawing helpers.
Instance Attribute Summary collapse
-
#bytes ⇒ Object
readonly
Returns the value of attribute bytes.
-
#height ⇒ Object
readonly
Returns the value of attribute height.
-
#width ⇒ Object
readonly
Returns the value of attribute width.
Instance Method Summary collapse
- #draw_circle_outline(cx, cy, radius, color, alpha:) ⇒ Object
- #draw_label(text, x:, y:, color:, alpha:, letter_spacing: 0.0) ⇒ Object
- #draw_line(x1, y1, x2, y2, color, alpha:) ⇒ Object
- #draw_rect_outline(x, y, rect_width, rect_height, color, alpha:) ⇒ Object
- #draw_wave(y_base, amplitude:, color:, alpha:, height_scale: 1.0) ⇒ Object
- #fill_circle(cx, cy, radius, color, alpha:) ⇒ Object
- #fill_gradient(top, bottom) ⇒ Object
- #fill_rect(x, y, rect_width, rect_height, color, alpha:) ⇒ Object
-
#initialize(width:, height:) ⇒ Canvas
constructor
A new instance of Canvas.
Constructor Details
#initialize(width:, height:) ⇒ Canvas
Returns a new instance of Canvas.
811 812 813 814 815 816 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 811 def initialize(width:, height:) @width = width @height = height @bytes = String.new(capacity: width * height * 4, encoding: Encoding::BINARY) @bytes << ([0, 0, 0, 255].pack("C4") * (width * height)) end |
Instance Attribute Details
#bytes ⇒ Object (readonly)
Returns the value of attribute bytes.
818 819 820 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 818 def bytes @bytes end |
#height ⇒ Object (readonly)
Returns the value of attribute height.
818 819 820 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 818 def height @height end |
#width ⇒ Object (readonly)
Returns the value of attribute width.
818 819 820 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 818 def width @width end |
Instance Method Details
#draw_circle_outline(cx, cy, radius, color, alpha:) ⇒ Object
845 846 847 848 849 850 851 852 853 854 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 845 def draw_circle_outline(cx, cy, radius, color, alpha:) segments = 96 previous = nil (0..segments).each do |index| angle = (index.to_f / segments) * Math::PI * 2 point = [cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius] draw_line(previous[0], previous[1], point[0], point[1], color, alpha: alpha) if previous previous = point end end |
#draw_label(text, x:, y:, color:, alpha:, letter_spacing: 0.0) ⇒ Object
893 894 895 896 897 898 899 900 901 902 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 893 def draw_label(text, x:, y:, color:, alpha:, letter_spacing: 0.0) chars = text.each_byte.first(24) char_width = 14 + Float(letter_spacing).clamp(0.0, 96.0).round total_width = chars.length * char_width start_x = x.round - total_width / 2 chars.each_with_index do |byte, index| height_factor = 0.35 + (byte % 9) * 0.07 (start_x + index * char_width, y.round, 9, (42 * height_factor).round, color, alpha) end end |
#draw_line(x1, y1, x2, y2, color, alpha:) ⇒ Object
866 867 868 869 870 871 872 873 874 875 876 877 878 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 866 def draw_line(x1, y1, x2, y2, color, alpha:) x1 = x1.round y1 = y1.round x2 = x2.round y2 = y2.round steps = [(x2 - x1).abs, (y2 - y1).abs].max return blend_pixel(x1, y1, color, alpha) if steps.zero? steps.times do |step| t = step.to_f / steps blend_pixel(interpolate(x1, x2, t).round, interpolate(y1, y2, t).round, color, alpha) end end |
#draw_rect_outline(x, y, rect_width, rect_height, color, alpha:) ⇒ Object
838 839 840 841 842 843 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 838 def draw_rect_outline(x, y, rect_width, rect_height, color, alpha:) draw_line(x, y, x + rect_width, y, color, alpha: alpha) draw_line(x + rect_width, y, x + rect_width, y + rect_height, color, alpha: alpha) draw_line(x + rect_width, y + rect_height, x, y + rect_height, color, alpha: alpha) draw_line(x, y + rect_height, x, y, color, alpha: alpha) end |
#draw_wave(y_base, amplitude:, color:, alpha:, height_scale: 1.0) ⇒ Object
828 829 830 831 832 833 834 835 836 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 828 def draw_wave(y_base, amplitude:, color:, alpha:, height_scale: 1.0) previous = nil width.times do |x| phase = (x.to_f / width) * Math::PI * 4.0 y = y_base + Math.sin(phase) * height * (0.06 + amplitude * 0.08) * height_scale draw_line(previous[0], previous[1], x, y, color, alpha: alpha) if previous previous = [x, y] end end |
#fill_circle(cx, cy, radius, color, alpha:) ⇒ Object
880 881 882 883 884 885 886 887 888 889 890 891 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 880 def fill_circle(cx, cy, radius, color, alpha:) cx = cx.round cy = cy.round radius = radius.round (cy - radius).upto(cy + radius) do |y| (cx - radius).upto(cx + radius) do |x| next if ((x - cx)**2) + ((y - cy)**2) > radius**2 blend_pixel(x, y, color, alpha) end end end |
#fill_gradient(top, bottom) ⇒ Object
820 821 822 823 824 825 826 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 820 def fill_gradient(top, bottom) height.times do |y| t = y.to_f / [height - 1, 1].max color = 3.times.map { |index| interpolate(top[index], bottom[index], t).round } width.times { |x| set_pixel(x, y, color, 255) } end end |
#fill_rect(x, y, rect_width, rect_height, color, alpha:) ⇒ Object
856 857 858 859 860 861 862 863 864 |
# File 'lib/vizcore/renderer/snapshot_renderer.rb', line 856 def fill_rect(x, y, rect_width, rect_height, color, alpha:) start_x = x.round end_x = (x + rect_width).round start_y = y.round end_y = (y + rect_height).round start_y.upto(end_y) do |py| start_x.upto(end_x) { |px| blend_pixel(px, py, color, alpha) } end end |