Module: Plushie::Type::Gradient

Defined in:
lib/plushie/type/gradient.rb

Overview

Gradient specification for widget backgrounds.

Build gradients with +linear+:

Gradient.linear([0, 0], [100, 100], [[0.0, :red], [1.0, :blue]])

Or from an angle with +linear_from_angle+:

Gradient.linear_from_angle(90, [[0.0, :red], [1.0, :blue]])

Stop colors accept any form Color.cast supports (named atoms, hex strings, RGBA maps). They are normalized to canonical hex strings.

== Wire format

Uses the coordinate-based format matching canvas gradients:

"linear", start: [0, 0], end: [100, 100], stops: [[0.0, "#ff0000"], [1.0, "#0000ff"]]

Class Method Summary collapse

Class Method Details

.encode(value) ⇒ Hash

Encode a gradient for the wire protocol.

Parameters:

  • value (Hash)

    gradient specification

Returns:

  • (Hash)


70
71
72
73
74
75
# File 'lib/plushie/type/gradient.rb', line 70

def encode(value)
  case value
  when Hash then value
  else raise ArgumentError, "invalid gradient: #{value.inspect}"
  end
end

.linear(from, to, stops) ⇒ Hash

Create a linear gradient between two coordinate points.

Parameters:

  • from (Array(Numeric, Numeric))

    start point [x, y]

  • to (Array(Numeric, Numeric))

    end point [x, y]

  • stops (Array<Array(Float, String|Symbol)>)

    color stops as [offset, color] pairs

Returns:

  • (Hash)

    wire-ready gradient map



33
34
35
36
37
38
39
40
# File 'lib/plushie/type/gradient.rb', line 33

def linear(from, to, stops)
  {
    type: "linear",
    start: Array(from),
    end: Array(to),
    stops: stops.map { |offset, color| [offset.to_f, Color.cast(color)] }
  }
end

.linear_from_angle(angle, stops) ⇒ Hash

Create a linear gradient from an angle (degrees) and stops.

The angle is converted to start/end coordinates on a unit square (0,0 to 1,1). Use this when you want angle-based gradients without computing coordinates manually.

Parameters:

  • angle (Numeric)

    angle in degrees (0 = bottom to top)

  • stops (Array<Array(Float, String|Symbol)>)

    color stops

Returns:

  • (Hash)

    wire-ready gradient map



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/plushie/type/gradient.rb', line 51

def linear_from_angle(angle, stops)
  rad = angle * Math::PI / 180.0
  dx = Math.cos(rad)
  dy = Math.sin(rad)

  # Extend to unit square edges so the gradient covers the full box
  half_len = dx.abs / 2.0 + dy.abs / 2.0
  cx = 0.5
  cy = 0.5

  from = [cx - dx * half_len, cy - dy * half_len]
  to = [cx + dx * half_len, cy + dy * half_len]
  linear(from, to, stops)
end